Leandro Navatta
Leandro Navatta

Reputation: 101

Trouble with creating tweet programmatically

I've used Fabric (fabric.io) to integrate it with Twitter and the login and Auth works just fine, but I need to create and send tweets via code and the Twitter Kit only let you use a visual composer.

After a lot of trial and error, I got to this code using their documentation as bases (docs.fabric.io/ios/twitter/access-rest-api.html#constructing-a-twitter-request-manually)

    @IBAction func send(sender: UIButton) {
    self.tweetText.resignFirstResponder()
    let client = TWTRAPIClient()
    let statusesShowEndpoint = "https://api.twitter.com/1.1/statuses/update.json"
    let params = ["status": "Vamos ver se vai?"] //this is just test parameter
    var clientError : NSError?

    let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod("POST", URL: statusesShowEndpoint, parameters: params, error: &clientError)
   /* println(request.allHTTPHeaderFields)
    println(request.HTTPMethod)
    println(request.URL)*/

    client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
        if (connectionError == nil) {
            var jsonError : NSError?
            let json : AnyObject? = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &jsonError)
        }
        else {
            println("Error: \(connectionError)")
        }
    }


}

But I get these errors:

Error: Optional(Error Domain=TwitterAPIErrorDomain Code=220 "Request failed: forbidden (403)" UserInfo=0x7aa35c70 {NSLocalizedFailureReason=Twitter API error : Your credentials do not allow access to this resource. (code 220), NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: forbidden (403)})

As you can see, I've tried to debug to see if the headers comply with Twitter's REST API and they're okay

     Optional([Content-Length: 32, 
Authorization: OAuth oauth_timestamp="1443339227",oauth_version="1.0",
    oauth_consumer_key="deleted",
    oauth_signature="deleted",
    oauth_token="deleted",
    oauth_nonce="9ACAF7BE-E789-46A5-9B3B-5F5AB02EFB85",
    oauth_signature_method="HMAC-SHA1", Accept-Encoding: gzip, Content-Type: application/x-www-form-urlencoded;charset=UTF-8, User-Agent: Fabric/X.Y.Z (Really Long Tweets/1; iPhone Simulator; iOS 8.4; Scale/2.00) TwitterKit/1.11.1])
    Optional("POST")
    Optional(https://api.twitter.com/1.1/statuses/update.json)

I tried using the visual composer that they give you to see if the problem was with my App but it works just fine and posts on my Twitter timeline, so i Think it can't be the API keys, the type of permission (it has read and write permissions) or the credentials. I tried changing this code so it makes a GET request and it worked, I think the problem is with the POST and the REST API, something isn't matching

I need to make this programmaticaly because I need to get a big text, break it up and send it in form of several tweets at once, otherwise I would just use their composer and be done with it

Upvotes: 1

Views: 2114

Answers (1)

Leandro Navatta
Leandro Navatta

Reputation: 101

Okay, so I discovered the problem. The problem was with

let client = TWTRAPIClient()

This created a guest client, not authenticated. You need to pass the user ID so you can authenticate the user, so here's the new code (it's working)

@IBAction func send(sender: UIButton) {
    self.tweetText.resignFirstResponder()
    let store = Twitter.sharedInstance().sessionStore
    if let userid = store.session()?.userID {
        let client = TWTRAPIClient(userID: userid)
        let statusesShowEndpoint = "https://api.twitter.com/1.1/statuses/update.json"
        let params = ["status": "Terceiro teste?"]
        var clientError : NSError?

        let request = client.URLRequestWithMethod("POST", URL: statusesShowEndpoint, parameters: params, error: &clientError)
        client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
            if (connectionError == nil) {
                var jsonError : NSError?
                let json : AnyObject? = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &jsonError)
            }
            else {
                println("Error: \(connectionError)")
            }
        }
    } 
}

Upvotes: 9

Related Questions