简体   繁体   中英

Use SLRequest to post image in tweet - Image not shown

I'm trying to upload an image (from an iOS device) to a user's twitter account programmatically using SLRequest. The Tweet text is uploaded in the tweet, but the image never appears. The response status code is 200.

Obviously the basics work ok, otherwise the tweet would not be shown in the user's stream at all and I have checked that the image is found and that the (NSData) variable contains the expected number of bytes.

Check out the following code - As you can see form the commented out code, I have tried various different modifications without success... Any thoughts/help appreciated!

- (void) postToTwitter:(NSString *)postMessage withImageNamed:(NSString *)imageName {

    // Get Twitter account
    ACAccountStore *smAccount = [[ACAccountStore alloc] init];
    ACAccountType *smType = [smAccount accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    NSDictionary *postOptions = nil;

    // Attempt to post the postMessage
    [smAccount requestAccessToAccountsWithType:smType options:postOptions completion:^(BOOL accessGranted, NSError *error) {

        // Access code block

        if (accessGranted) {

            NSLog(@"Access permitted");

            NSArray *smAccountList = [smAccount accountsWithAccountType:smType];

            if ([smAccountList count] > 0) {

                // Get the first Twitter account
                ACAccount *postingAccount = [smAccountList lastObject];

                // Create the post request
                //SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"] parameters:[NSDictionary dictionaryWithObject:postMessage forKey:@"status"]];
                //SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"] parameters:nil];
                SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"] parameters:nil];

                // Add image to post
                // TODO - Check which to use >
                UIImage *postImage = [UIImage imageNamed:imageName];
                //UIImage *postImage = [UIImage imageWithContentsOfFile:imageName];
                //NSData *imageData = UIImageJPEGRepresentation (postImage, 0.5f); // Set compression

                NSData *imageData = UIImagePNGRepresentation(postImage);

                //[postRequest addMultipartData:imageData withName:@"media" type:@"image/png" filename:@"image.png"];
                [postRequest addMultipartData:imageData withName:@"media[]" type:@"multipart/form-data" filename:@"image.png"];

                // Add text
                [postRequest addMultipartData:[postMessage dataUsingEncoding:NSUTF8StringEncoding] withName:@"status" type:@"multipart/form-data" filename:nil];

                // Execute the post
                [postRequest setAccount:postingAccount];
                [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {

                    // Post code block
                    if (error) {

                        NSLog(@"Post failed - %@", error);

                        if (_delegate && [_delegate respondsToSelector:@selector(didNotPost:)])
                            [_delegate didNotPost:self];
                    } else {

                        NSLog(@"Post complete");

                        if (_delegate && [_delegate respondsToSelector:@selector(didPost:)])
                            [_delegate didPost:self];
                    }
                }];
            }
        } else {

            NSLog(@"Access denied - %@", error);

            if (_delegate && [_delegate respondsToSelector:@selector(didNotPost:)])
                [_delegate didNotPost:self];
        }


    } ];
}

And this is the response:

(lldb) po urlResponse
<NSHTTPURLResponse: 0x7fb9bf80> { URL: https://api.twitter.com/1.1/statuses/update.json } { status code: 200, headers {
    "Cache-Control" = "no-cache, no-store, must-revalidate, pre-check=0, post-check=0";
    "Content-Disposition" = "attachment; filename=json.json";
    "Content-Encoding" = gzip;
    "Content-Length" = 751;
    "Content-Type" = "application/json;charset=utf-8";
    Date = "Thu, 02 Apr 2015 17:14:20 GMT";
    Expires = "Tue, 31 Mar 1981 05:00:00 GMT";
    "Last-Modified" = "Thu, 02 Apr 2015 17:14:20 GMT";
    Pragma = "no-cache";
    Server = "tsa_b";
    "Set-Cookie" = "lang=en";
    Status = "200 OK";
    "Strict-Transport-Security" = "max-age=631138519";
    "x-access-level" = "read-write";
    "x-connection-hash" = 6f61f3c96ba990931cca3fa950a42b38;
    "x-content-type-options" = nosniff;
    "x-frame-options" = SAMEORIGIN;
    "x-response-time" = 51;
    "x-transaction" = b2c77803db7e996d;
    "x-tsa-request-body-time" = 426;
    "x-twitter-response-tags" = BouncerCompliant;
    "x-xss-protection" = "1; mode=block";
} }

At the time I post this, update_with_media is deprecated. While it works now, it maybe stopped suddenly in the future - this risks your app to not working anymore in the future.

After much reading on the Twitter's API documentation, I managed to make it work without using "update_with_media".

The process involved to upload an image (or video) is:

  1. Use /media/upload.json SLRequest to first upload the media (image or video). Use nil parameters and add the image using "addMultipartData" method of SLRequest.

  2. Call performRequestWithHandler on that SLRequest.

  3. Wait for response from twitter to get the "Media ID" from the responseData (convert the data into JSON format) and retrieve "media_id_string" into an NSString.

  4. Initiate another SLRequest with /statuses/update.json and attach the Media ID (key:media_ids) into the parameters dictionary together with the status text (key:status).

NSDictionary *parameters = @{@"status": @"See my image:",
                                                    @"media_ids": mediaID };
  1. Call performRequestWithHandler on the second SLRequest to submit the tweet.

For detail code please see here on my tutorial blog: http://xcodenoobies.blogspot.my/2016/01/how-to-using-slrequest-to-upload-image.html

So after much pain, I realised that I was posting to the wrong twitter API. The following modification made this work.

SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update_with_media.json"] parameters:nil];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM