2

I am trying to send a POST request to Twitter API to grab a bearer_token as part of application-only authentication. I've followed their documentation (https://dev.twitter.com/oauth/application-only) to URL encode and concatenate by my consumer key and consumer secret. I've then put that in a string called auth_string which you'll see in the request. I've also followed the documentation to add static header values to the request. The problem is passing the HTTPBody as "grant_type=client_credentials" (the way Twitter requires in the documentation).

I tried three approaches for this:

  1. I tried passing it as a string and that did not work, the build fails because I guess I can't pass that type to HTTPBody.
  2. I tried converting the string to NSData prior to sending the request like this: Creating NSData from NSString in Swift - but that doesn't seem to work either - when I print that NSData variable to the console it looks like this: "httpbody: Optional(<6772616e 745f7479 70653d63 6c69656e 745f6372 6564656e 7469616c 73>)", and when I print the request just prior to making it I don't even see anything in the body - only see the header fields I set before.
  3. I tried making a NSDictionary object like this approach: http://jamesonquave.com/blog/making-a-post-request-in-swift/#jumpSwift but again I cannot see the proper body in the request prior to sending it, and I do not get the right response from the Twitter endpoint.

Any tips are greatly appreciated! The code below shows the second approach I listed above.

//auth_string is used as authorization field in header of http request
    let auth_string:NSString = "Basic \(key_sec_base64)"

    let http_body = "grant_type=client_credentials".dataUsingEncoding(NSUTF8StringEncoding)

    var bearer_token_request = NSMutableURLRequest(URL: NSURL(string: "https://api.twitter.com/oauth2/token"))
    var bearer_token_session = NSURLSession.sharedSession()
    bearer_token_request.HTTPMethod = "POST"

    var err: NSError?

    bearer_token_request.addValue("application/x-www-form-urlencoded;charset=UTF-8", forHTTPHeaderField: "Content-Type")
    bearer_token_request.addValue((auth_string), forHTTPHeaderField: "Authorization")
    bearer_token_request.addValue("gzip", forHTTPHeaderField: "Accept-encoding")
    bearer_token_request.addValue("api.twitter.com", forHTTPHeaderField: "Host")
    bearer_token_request.HTTPBody = http_body

    println("httpbody: \(bearer_token_request.HTTPBody)")

    println(bearer_token_request)

    let task = bearer_token_session.dataTaskWithRequest(bearer_token_request, completionHandler: {(data, response, error) in
        println(data)

    })

    task.resume()
Community
  • 1
  • 1
bkopp
  • 478
  • 1
  • 8
  • 20

1 Answers1

1

when I print that NSData variable to the console it looks like this: "httpbody: Optional(<6772616e 745f7479 70653d63 6c69656e 745f6372 6564656e 7469616c 73>)",

It is because it is an optional type: the type is Optional<NSData>

If you do println(data!), it will get rid of the Optional<> part.

And then you will probably need to convert data back to string to see the data as you would have expected ("grant_type=client_credentials")

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • oh cool this was easy I actually just used your suggestion on the end result that I was getting back from Twitter and they actually are sending me the JSON response I need when I convert it back to a string! – bkopp Oct 12 '14 at 17:11