elliottbolzan
elliottbolzan

Reputation: 1077

Facebook Graph API Upload Local Image to Wall (Objective-C)

I'm trying to upload a local, user created photo from my application to the user's Facebook Wall. I'm developing an app in Objective-C and using the PhFacebook library to interact with the social network, but I think it's more likely my problem is coming from my flawed use of the actual interaction with Facebook.

Indeed, to upload a status to the user's profile, after having gotten an access token, this code works perfectly well:

NSMutableDictionary *variables = [NSMutableDictionary dictionaryWithCapacity:1];

[variables setObject:@"This is a test." forKey:@"message"];

[fb sendRequest:@"me/feed" params:variables usePostRequest:YES];

However, if I attempt to upload a photo directly to the me/feed, using the following code, it fails systematically, as the image isn't shown and the surrounding text is:

NSString *path = @"some/path/to/some/image/on/my/computer";

NSMutableDictionary *variables = [NSMutableDictionary dictionaryWithCapacity:2];

[variables setObject:@"This is a test." forKey:@"message"];

[variables setObject:path forKey:@"source"];

[fb sendRequest:@"me/feed" params:variables usePostRequest:YES];

I've tried modifying the source key to image, photo, picture, file, and data, but no changes could be seen, and source seems to be the most correct.

After having read the documentation about uploading photos: http://developers.facebook.com/docs/reference/api/photo/, I've understood that the source parameter corresponds to a URL. I've tried directly uploading the image's data or the image's local path on the user's computer, but I still haven't found a way to upload an image that isn't already on Internet. I'm sure there's a way to do this, even the word upload implies that the image should be local !

Essentially, it seems I'm having the opposite of this problem: Upload a hosted image with Facebook's Graph API by url?.

Thanks in advance to anyone who can help, my Facebook friends are starting to be puzzled over all these test messages :)

Upvotes: 0

Views: 5788

Answers (3)

Honey Jain
Honey Jain

Reputation: 61

You Can also upload the photo directly there is no need of making a url . here is the sample code-

NSString *urlString = [NSString stringWithFormat:@"https://graph.facebook.com/%@", @"facebook id"];
NSURL *url = [NSURL URLWithString:urlString];
NSString *boundary = @"----1010101010";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary]
         dataUsingEncoding:NSUTF8StringEncoding]];
NSEnumerator *enumerator = [post_vars keyEnumerator];
NSString *key;
NSString *value;
NSString *content_disposition;
while ((key = (NSString *)[enumerator nextObject])) {

    //if it's a picture (file)...we have to append the binary data
    if ([key isEqualToString:@"file"]) {
        NSData *picture_data = UIImagePNGRepresentation([post_vars objectForKey:key]);
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"media\";\r\nfilename=\"media.png\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:picture_data];
    } else {
        value = (NSString *)[post_vars objectForKey:key];

        content_disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [body appendData:[content_disposition dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[value dataUsingEncoding:NSUTF8StringEncoding]];

    }
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];    
[body appendData:access_token] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:@"%d", body.length] forHTTPHeaderField: @"Content-Length"];    
NSData *data_reply;
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:delegate startImmediately:YES];
[conn start];
BOOL flag = YES;
NSString *stringResponse = [[NSString alloc] initWithData:data_reply encoding:NSUTF8StringEncoding];
NSError *err = [[NSError alloc] init];
if (err != nil) {
    NSData *dataStr = [stringResponse dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableDictionary *data = [NSJSONSerialization JSONObjectWithData:dataStr options:kNilOptions error:&err];
    if([data objectForKey:@"Error"]!=nil){
    }
}iscr
stringResponse = nil;
data_reply = nil;

}

In this the post_vars is dictionary which is describe as below -

NSMutableDictionary *post_vars = [NSMutableDictionary dictionaryWithCapacity:4];

[post_vars setObject:@"this is a message" forKey:@"message"];
[post_vars setObject:@"name" forKey:@"name"];
[post_vars setObject:@"description" forKey:@"description"];
[post_vars setObject:imagename forKey:@"file"];

Upvotes: 3

elliottbolzan
elliottbolzan

Reputation: 1077

Turns out, you can only use PhFacebook for simpler requests. Here is what I had to do upload a local image to the Facebook Wall, without using PhFacebook, and on a Mac:

-Get a Facebook Access Token with the publish_stream permission set using a WebView and ASIHTTPRequest (http://www.capturetheconversation.com/technology/iphone-facebook-oauth2-graph-api).

-Make a simple ASIHTTPRequest to actually upload the image:

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/me/photos?access_token=%@", access_token]];

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];

    [request addFile:@"/path/tolocalimage/" forKey:@"file"];

    [request setPostValue:[NSString stringWithFormat:@"This is a test."] forKey:@"message"];

    [request startAsynchronous];

And there you go ! This solution almost seems simpler than using existing frameworks ! The only time-consuming part is building the WebView interface, but you can simply inspire yourself from the link I posted and PhFacebook.h, which uses a similar (yet slightly different) technique.

Upvotes: 2

Pelpotronic
Pelpotronic

Reputation: 560

I just tried the method on the post here: Facebook connect on iOS picture doesn't display with wall post and it might help your cause. However, it seems that the behaviour is slightly different from a real "wall picture post", since the pictures are uploaded to your application photo album instead of the "wall album".

When you post several pictures within a few moments using a Facebook app, Facebook mentions that "[YourFBName] has added several pictures to the [ApplicationName] album" (a "grouped" wall post for different events).

Whereas when you post several pictures on the wall using the FB interface directly, even though they are all added to the "Wall album", they are always shown as separate posts (wall posts are not grouped here).

Upvotes: 2

Related Questions