Facebook Graph API将本地图像上传到墙上(Objective-C)

时间:2011-11-30 22:19:47

标签: objective-c facebook facebook-graph-api

我正在尝试将用户创建的本地照片从我的应用程序上传到用户的Facebook Wall。我正在使用Objective-C开发一个应用程序并使用PhFacebook库与社交网络进行交互,但我认为我的问题更可能来自于我与Facebook实际交互的有缺陷的使用。

的确,要在获得访问令牌后将状态上传到用户的个人资料,此代码运行良好:

NSMutableDictionary *variables = [NSMutableDictionary dictionaryWithCapacity:1];

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

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

但是,如果我尝试使用以下代码将照片直接上传到me/feed,系统会失败,因为图片未显示且周围文字为:

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];

我尝试将source密钥修改为imagephotopicturefiledata,但没有变更可以看出,source似乎是最正确的。

在阅读了有关上传照片的文档后http://developers.facebook.com/docs/reference/api/photo/,我了解到source参数对应的是URL。我已经尝试直接在用户的计算机上上传图像的数据或图像的本地路径,但我还没有找到一种方法来上传尚未上网的图像。我确信有办法做到这一点,即使上传文字暗示图像应该是本地的!

基本上,似乎我遇到了与此问题相反的问题:Upload a hosted image with Facebook's Graph API by url?

提前感谢任何可以提供帮助的人,我的Facebook好友开始对所有这些测试消息感到困惑:)

3 个答案:

答案 0 :(得分:3)

您还可以直接上传照片,无需制作网址。 这是示例代码 -

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;

}

这里post_vars是字典,描述如下 -

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"];

答案 1 :(得分:2)

我刚刚在帖子上尝试了这个方法:Facebook connect on iOS picture doesn't display with wall post它可能有助于你的事业。 然而,似乎这种行为与真正的“墙上画面”略有不同,因为这些图片会上传到您的应用相册而不是“墙上相册”。

当您使用Facebook应用在短时间内发布多张图片时,Facebook会提到“[YourFBName]已将多张图片添加到[ApplicationName]相册”(针对不同事件的“分组”墙贴)。

然而,当您使用FB界面直接在墙上发布多张图片时,即使它们都被添加到“墙上相册”中,它们也会始终显示为单独的帖子(墙上的帖子未在此处分组)。

答案 2 :(得分:2)

事实证明,您只能使用PhFacebook来处理更简单的请求。以下是我不得不在不使用PhFacebook的情况下将本地图像上传到Facebook Wall,以及在Mac上:

- 使用WebView和ASIHTTPRequest(http://www.capturetheconversation.com/technology/iphone-facebook-oauth2-graph-api)获取publish_stream权限集的Facebook访问令牌。

- 使用简单的ASIHTTPRequest实际上传图像:

    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];

你去吧!这个解决方案几乎比使用现有框架简单!唯一耗时的部分是构建WebView界面,但您可以从我发布的链接和使用类似(但略有不同)技术的PhFacebook.h中激发自己。