简体   繁体   中英

Error while doing phone number verification using twilio in swift

I want to verify phone number by getting one time password. But I am getting some error. Please look into the code bellow and help me to resolve it. I am using Twilio for mobile verification. And Alamofire for API request. But the error I am getting like:-

Authentication Error - No credentials provided.
The data couldn’t be read because it isn’t in the correct format

My code is:-

Here is my model class: -

...struct SendVerificationCode: Codable {
let status: String?
let payee: String?
let dateUpdated: Date?
let sendCodeAttempts: [SendCodeAttempt]?
let accountSid, to: String?
let amount: Int?
let valid: Bool?
let lookup: Lookup?
let url: String?
let sid: String?
let dateCreated: Date?
let serviceSid, channel: String?

enum CodingKeys: String, CodingKey {
    case status, payee
    case dateUpdated = "date_updated"
    case sendCodeAttempts = "send_code_attempts"
    case accountSid = "account_sid"
    case to, amount, valid, lookup, url, sid
    case dateCreated = "date_created"
    case serviceSid = "service_sid"
    case channel
}
}


struct Lookup: Codable {
let carrier: Carrier?
}


struct Carrier: Codable {
let mobileCountryCode, type: String?
let errorCode: String?
let mobileNetworkCode, name: String?

enum CodingKeys: String, CodingKey {
    case mobileCountryCode = "mobile_country_code"
    case type
    case errorCode = "error_code"
    case mobileNetworkCode = "mobile_network_code"
    case name
}
}


 struct SendCodeAttempt: Codable {
let channel, time: String?
}...

Api Request:-

...func sendcode(mobileWithCode: String, completion: @escaping sendTwillioVerificationCodeCompletion) {

    let url = URL(string: SEND_TWILIO_VERIFICATION_CODE)
   var urlRequest = URLRequest(url: url!)
   urlRequest.httpMethod = HTTPMethod.post.rawValue
   urlRequest.addValue(userNameData, forHTTPHeaderField: "Username")
    urlRequest.addValue(PasswordData, forHTTPHeaderField: "Password")
    urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")


   Alamofire.request(urlRequest).responseJSON { (response) in
       if let error = response.result.error {
           debugPrint(error.localizedDescription)
           completion(nil)
           return
       }

       guard let data = response.data else { return completion(nil)}

       Common.sharedInstance().printRequestOutput(data: data)

       let jsonDecoder = JSONDecoder()
       do {
           let clear = try jsonDecoder.decode(SendVerificationCode.self, from: data)
           completion(clear)
       } catch {
           debugPrint(error.localizedDescription)
           completion(nil)
       }
   }
}...

But i am getting error:-

   {"code": 20003, "detail": "Your AccountSid or AuthToken was incorrect.", "message": "Authentication Error - No credentials provided", "more_info": "https://www.twilio.com/docs/errors/20003", "status": 401}
   "The data couldn’t be read because it isn’t in the correct format."

Also i have tried the following code:-

import Foundation
semaphore = DispatchSemaphore (value: 0)

let parameters = "To=+919778882332&Channel=sms"
let postData =  parameters.data(using: .utf8)

var request = URLRequest(url: URL(string:  myUrl)!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue(requestData, forHTTPHeaderField: "Authorization")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
semaphore.signal()
}

task.resume()
semaphore.wait()

But i am getting error like

"Invalid parameter"

Twilio developer evangelist here.

It looks as though your code is trying to call the Twilio API directly from the device and that you weren't setting your Account SID or Auth Token in that.

The issue here is that you should not store or access your auth token from within your application. That would make your account sid and auth token vulnerable to be stolen and then used to abuse your account.

Instead, you should create a server side application that talks to the Twilio API and then call that from your application.

As Jamil pointed out, there is a blog post you can follow on performing phone verification in iOS with Twilio Verify and Swift and I recommend you go through that. It includes an example server side application to call the Twilio Verify API built in Python, but you could build your own too.

Here is sample code:

import UIKit

class ViewController: UIViewController {

    static let path = Bundle.main.path(forResource: "Config", ofType: "plist")
    static let config = NSDictionary(contentsOfFile: path!)
    private static let baseURLString = config!["serverUrl"] as! String

    @IBOutlet var countryCodeField: UITextField! = UITextField()
    @IBOutlet var phoneNumberField: UITextField! = UITextField()
    @IBAction func sendVerification() {
        if let phoneNumber = phoneNumberField.text,
            let countryCode = countryCodeField.text {
            ViewController.sendVerificationCode(countryCode, phoneNumber)
        }
    }

    static func sendVerificationCode(_ countryCode: String, _ phoneNumber: String) {

        let parameters = [
            "via": "sms",
            "country_code": countryCode,
            "phone_number": phoneNumber
        ]

        let path = "start"
        let method = "POST"

        let urlPath = "\(baseURLString)/\(path)"
        var components = URLComponents(string: urlPath)!

        var queryItems = [URLQueryItem]()

        for (key, value) in parameters {
            let item = URLQueryItem(name: key, value: value)
            queryItems.append(item)
        }

        components.queryItems = queryItems

        let url = components.url!

        var request = URLRequest(url: url)
        request.httpMethod = method

        let session: URLSession = {
            let config = URLSessionConfiguration.default
            return URLSession(configuration: config)
        }()

        let task = session.dataTask(with: request) {
            (data, response, error) in
            if let data = data {
                do {
                    let jsonSerialized = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]

                    print(jsonSerialized!)
                }  catch let error as NSError {
                    print(error.localizedDescription)
                }
            } else if let error = error {
                print(error.localizedDescription)
            }
        }
        task.resume()
    }
}

For more please check this link: Link .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM