Reputation: 373
I'm building an app that contains references to some shop of my city. Now I'd like to insert, in the detail view of each shop, a table with the last 3 or 5 tweet from the shop's account.
I'd like not use third party solution.
Reading the Twitter's documentation I understand that for use the Rest Services i have to authenticate my app, so I have registered the app and requested the Access Token with "read only" option, and here start the problems.
I'm not able to access the Rest service, every time I have "Authentication error" as response.
The documentation on Twitter website is here: https://developer.twitter.com/en/docs/basics/authentication/overview/application-only
where are described the three steps for the application-only auth:
I looked for solution here:
Then on google i found this: http://rshankar.com/retrieve-list-of-twitter-followers-using-swift/
and this is my attempt:
1. first of all I created the func to encode consumer_key and consumer_secret
let consumerKey = "xxxxxxxxxxxxxxxx"
let consumerSecret = "xxxxxxxxxxxxxxxx"
let authUrl = "https://api.twitter.com/oauth2/token"
func getBase64EncodeString() -> String {
let consumerKeyRFC1738 = consumerKey.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let consumerSecretRFC1738 = consumerSecret.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let concatenateKeyAndSecret = consumerKeyRFC1738! + ":" + consumerSecretRFC1738!
let secretAndKeyData = concatenateKeyAndSecret.data(using: String.Encoding.ascii, allowLossyConversion: true)
let base64EncodeKeyAndSecret = secretAndKeyData?.base64EncodedString(options: NSData.Base64EncodingOptions())
return base64EncodeKeyAndSecret!
}
2. then the func to obtain bearerToken
func getBearerToken(completion:@escaping (_ bearerToken: String) -> Void) {
var request = URLRequest(url: URL(string: authURL)!)
request.httpMethod = "POST"
request.addValue("Basic " + getBase64EncodeString(), forHTTPHeaderField: "Authorization")
request.addValue("application/x-www-form-urlencoded;charset=UTF-8", forHTTPHeaderField:"Content-Type")
let grantType = "grant_type=client_credentials"
request.httpBody = grantType.data(using: String.Encoding.utf8, allowLossyConversion: true)
URLSession.shared.dataTask(with: request, completionHandler: { (data: Data?, response:URLResponse?, error: NSError?) -> Void in
do {
if let results: NSDictionary = try JSONSerialization .jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments ) as? NSDictionary {
if let token = results["access_token"] as? String {
completion(token)
} else {
print(results["errors"]!)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
} as! (Data?, URLResponse?, Error?) -> Void).resume()
}
3. and finally Authenticate API requests with the bearer token
func getResponseForRequest(url:String) {
var results:NSDictionary
getBearerToken(completion: { (bearerToken) -> Void in
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
let token = "Bearer " + bearerToken
request.addValue(token, forHTTPHeaderField: "Authorization")
URLSession.shared .dataTask(with: request, completionHandler: { (data: Data?, response:URLResponse?, error: NSError?) -> Void in
self.processResult(data!, response: response!, error: error)
} as! (Data?, URLResponse?, Error?) -> Void).resume()
})
}
At the moment i have a message error at the line:
} as! (Data?, URLResponse?, Error?) -> Void).resume()
in the getBearerToken func.
The error message is:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
so until i haven't verified if the authentication works.
Can someone help me?
Upvotes: 0
Views: 1171
Reputation: 223
use this:
var request = URLRequest(url: url)
request.httpMethod = HttpMethod.POST.rawValue
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("Basic \(base64)", forHTTPHeaderField: "Authorization")
request.httpBody = "grant_type=client_credentials".data(using: .utf8)
Upvotes: 1