Reputation: 396
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"];
Upvotes: 7
Views: 4199
Reputation: 15951
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
Upvotes: 1
Reputation: 6804
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]);
}
}];
}];
}
Upvotes: 3
Reputation: 1305
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
}
Upvotes: 2
Reputation: 396
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.
Upvotes: 7