Posting image to twitter using twitterkit

2019-03-27 23:48发布

I am trying to post an image and tweet using Twitters new TwitterKit with a custom UI. The only documentation they provide is how to do it with their views.

so I can figure out how to do it without an image

NSMutableDictionary *message = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[params objectForKey:@"description"],@"status",@"true",@"wrap_links", nil];

NSURLRequest* request = [twAPIClient URLRequestWithMethod:@"POST" URL:@"https://api.twitter.com/1.1/statuses/update.json" parameters:message error:nil];

[twAPIClient sendTwitterRequest:request completion:^(NSURLResponse* response, NSData* data, NSError* connectionError){



}];

But their URLRequestWithMethod method isnt mutable. how would I add an image to it. You used to do it with the SLRequest with

[postRequest addMultipartData:UIImageJPEGRepresentation(image, 0.5) withName:@"media" type:@"image/jpeg" filename:@"image.png"];

4条回答
放我归山
2楼-- · 2019-03-28 00:19

As of about April 2016, Fabric's TwitterKit 2.0 (or newer) exposes a new method uploadMedia to cover the media uploading part. Here is some objc code that works for me.

(earlier)
self.userID = [[Twitter sharedInstance] sessionStore].session.userID;

- (void)tweetImage:(UIImage*)image {
        NSAssert([NSThread currentThread].isMainThread && self.userID, @"Twitterkit needs main thread, with self.userID set");
        if (!self.userID)
            return;
        NSString *tweetStr = @"Look at me! I'm tweeting! #hashtag";

        TWTRAPIClient *twitterClient = [[TWTRAPIClient alloc] initWithUserID:self.userID];
        NSData *imgData = UIImageJPEGRepresentation(image, 0.6f);
        if (!imgData) {
            NSAssert(false, @"ERROR: could not make nsdata out of image");
            return;
        }
        [twitterClient uploadMedia:imgData contentType:@"image/jpeg" completion:^(NSString * _Nullable mediaID, NSError * _Nullable error) {
            if (error) {
                NSAssert(false, @"ERROR: error uploading collage to twitter");
                return;
            }

            NSError *urlerror = nil;
            NSURLRequest *request = [twitterClient URLRequestWithMethod:@"POST" URL:@"https://api.twitter.com/1.1/statuses/update.json" parameters:@{ @"status":tweetStr, @"media_ids":mediaID } error:&urlerror];
            if (urlerror) {
                NSAssert(false, @"ERROR creating twitter URL request: %@", urlerror);
                return;
            }
            [twitterClient sendTwitterRequest:request completion:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
                if (!connectionError && ((NSHTTPURLResponse*)response).statusCode != 200) {
                    DDLogInfo(@"TwitterHelper tweetImage: non-200 response: %d. Data:\n%@", (int)((NSHTTPURLResponse*)response).statusCode, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                }
            }];
        }];
    }
查看更多
【Aperson】
3楼-- · 2019-03-28 00:21

Swift

func post (tweetString: String, tweetImage: NSData) {

    let uploadUrl = "https://upload.twitter.com/1.1/media/upload.json"
    let updateUrl = "https://api.twitter.com/1.1/statuses/update.json"
    let imageString = tweetImage.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
    let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod("POST",
        URL: uploadUrl, parameters: ["media": imageString], error: nil)
    Twitter.sharedInstance().APIClient.sendTwitterRequest(request, completion: { (urlResponse, data, connectionError) -> Void in

        if let mediaDict = self.nsdataToJSON(data!) {
            let validTweetString = TweetValidator().validTween(tweetString)
            let message = ["status": validTweetString, "media_ids": mediaDict["media_id_string"]]
            let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod("POST",
                URL: updateUrl, parameters: message, error:nil)

                Twitter.sharedInstance().APIClient.sendTwitterRequest(request, completion: { (response, data, connectionError) -> Void in
            })
        }
    })
}

func nsdataToJSON (data: NSData) -> AnyObject? {
    do {
        return try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil
}
查看更多
姐就是有狂的资本
4楼-- · 2019-03-28 00:24

I Have figured it out.

First you need to post the image to twitter.

NSString *media = @"https://upload.twitter.com/1.1/media/upload.json";

NSData *imageData = UIImageJPEGRepresentation(image, 0.9);

NSString *imageString = [corgiData base64EncodedStringWithOptions:0];               

NSURLRequest *request = [client URLRequestWithMethod:@"POST" URL:media parameters:@{@"media":imageString} error:&requestError];

[[[Twitter sharedInstance] APIClient] sendTwitterRequest:request completion:^(NSURLResponse *urlResponse, NSData *data, NSError *connectionError) {


}];

then in the response object you use the media_id_string and add that to the parameter of the code in my question.

So

NSMutableDictionary *message = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[params objectForKey:@"description"],@"status",@"true",@"wrap_links",mediaIDString, @"media_ids", nil];

NSURLRequest* request = [twAPIClient URLRequestWithMethod:@"POST" URL:@"https://api.twitter.com/1.1/statuses/update.json" parameters:message error:nil];

[twAPIClient sendTwitterRequest:request completion:^(NSURLResponse* response, NSData* data, NSError* connectionError){

 NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&parsingError];

}];

note the media_ids object that is from the response of the first request

NSMutableDictionary *message = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[params objectForKey:@"description"],@"status",@"true",@"wrap_links",[responseDict objectForKey:@"media_id_string"], @"media_ids", nil];

So you can just put that inside the completion block and it will post the image and tweet.

查看更多
We Are One
5楼-- · 2019-03-28 00:25

Swift 4 latest

1) Check login is done or not

let store = TWTRTwitter.sharedInstance().sessionStore
    if let store = store.session() {
        print("signed in as \(String(describing: store.authToken))");
        print("signed in as \(String(describing: store.authTokenSecret))");
        let postImage = UIImage(named: "testImage")
        let imageData = UIImagePNGRepresentation(postImage!) as Data?

        self.post(tweetString: "Test post image", tweetImage: (imageData! as NSData) as Data, withUserID: store.userID)
    }
    else {
        TWTRTwitter.sharedInstance().logIn(completion: { (session, error) in
            if (session != nil) {
                print("login first time in twitter as \(String(describing: session?.userName))");
            } else {
                print("error: \(String(describing: error?.localizedDescription))");
            }
        })
    }

2) To upload image with text

func post(tweetString: String, tweetImage: Data ,withUserID :String) {

    let uploadUrl = "https://upload.twitter.com/1.1/media/upload.json"
    let updateUrl = "https://api.twitter.com/1.1/statuses/update.json"
    let imageString = tweetImage.base64EncodedString(options: NSData.Base64EncodingOptions())

    let client = TWTRAPIClient.init(userID: withUserID)

    let requestUploadUrl = client.urlRequest(withMethod: "POST", urlString: uploadUrl, parameters: ["media": imageString], error: nil)

    client.sendTwitterRequest(requestUploadUrl) { (urlResponse, data, connectionError) -> Void in
        if connectionError == nil {
            if let mediaDict = self.nsDataToJson(data: (data! as NSData) as Data) as? [String : Any] {
                let media_id = mediaDict["media_id_string"] as! String
                let message = ["status": tweetString, "media_ids": media_id]

                let requestUpdateUrl = client.urlRequest(withMethod: "POST", urlString: updateUrl, parameters: message, error: nil)

                client.sendTwitterRequest(requestUpdateUrl, completion: { (urlResponse, data, connectionError) -> Void in
                    if connectionError == nil {
                        if let _ = self.nsDataToJson(data: (data! as NSData) as Data) as? [String : Any] {
                            print("Upload suceess to Twitter")
                        }
                    }
                })
            }
        }
    }
}

func nsDataToJson (data: Data) -> AnyObject? {
    do {
        return try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as AnyObject
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil
}

Note : install pod file pod 'TwitterKit'. You need to setup other minor things related to login in appdelegate and URL Schemes(above code is related to login and post image with text)

import TwitterKit

查看更多
登录 后发表回答