简体   繁体   English

使用 Facebook iOS SDK 在用户的墙上张贴照片

[英]Post photo on user's wall using Facebook iOS SDK

I'm trying to upload a photo from the camera to a user's Facebook wall.我正在尝试将相机中的照片上传到用户的 Facebook 墙上。 I'm not entirely sure what the correct strategy is, but from reading around it seems the thing to do is upload the photo to an album, and then someone post on the wall a link to that album/photo.我不完全确定正确的策略是什么,但从周围阅读看来,要做的事情是将照片上传到相册,然后有人在墙上发布指向该相册/照片的链接。 Ideally this would involve the dialog, but from what I can tell that's not possible.理想情况下,这将涉及对话,但据我所知,这是不可能的。

I've managed to upload a photo to an album, and get back an ID for that photo, but I'm not sure what to do after that.我已经设法将照片上传到相册,并取回了该照片的 ID,但我不知道之后该怎么做。

Can anyone provide some straightforward code for achieving this?谁能提供一些简单的代码来实现这一点?

Bonus question: Is it possible to post the photo to the application wall, as well (or instead)?额外的问题:是否可以将照片发布到应用程序墙上,以及(或替代)?

Edit: Graph API is preferable, but anything that works at this stage is good.编辑:图表 API 是可取的,但在这个阶段工作的任何东西都是好的。

I did this in three steps我分三步完成了这个

1 post picture to album (returns imageID) 1 张照片到相册(返回 imageID)

2 use imageID to request metadata for imageID 2 使用imageID请求imageID的元数据

3 use the 'link' field (not the 'source' field) as a link to the image in a post to the user's wall 3 使用“链接”字段(不是“来源”字段)作为帖子中图片的链接到用户的墙

The downside is that there are now two posts to the wall, one for the image, and one for the actual post.缺点是现在墙上有两个帖子,一个用于图像,一个用于实际帖子。 I haven't figured out yet how to post a picture to an album, without also a wall post appearing (ideally it would just be the 2nd post that appears)我还没有弄清楚如何将图片发布到相册,而不会出现墙贴(理想情况下它只是出现的第二个帖子)

Step 1:步骤1:

- (void) postImageToFacebook {

    appDelegate = (ScorecardAppDelegate *)[[UIApplication sharedApplication] delegate];

    currentAPICall = kAPIGraphUserPhotosPost;

    UIImage *imgSource = {insert your image here};
    NSString *strMessage = @"This is the photo caption";
    NSMutableDictionary* photosParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                         imgSource,@"source",
                                         strMessage,@"message",
                                         nil];

    [appDelegate.facebook requestWithGraphPath:@"me/photos"
                                     andParams:photosParams
                                 andHttpMethod:@"POST"
                                   andDelegate:self];     

    // after image is posted, get URL for image and then start feed dialog
    // this is done from FBRequestDelegate method
}

Step 2 (kAPIGraphUserPhotosPost) & step 3 (kAPIGraphPhotoData):第 2 步(kAPIGraphUserPhotosPost)和第 3 步(kAPIGraphPhotoData):

- (void)request:(FBRequest *)request didLoad:(id)result {

    if ([result isKindOfClass:[NSArray class]] && ([result count] > 0)) {
        result = [result objectAtIndex:0];
    }

    switch (currentAPICall) {
        case kAPIGraphPhotoData: // step 3
        {
            // Facebook doesn't allow linking to images on fbcdn.net.  So for now use default thumb stored on Picasa
            NSString *thumbURL = kDefaultThumbURL;
            NSString *imageLink = [NSString stringWithFormat:[result objectForKey:@"link"]];    

            currentAPICall = kDialogFeedUser;
            appDelegate = (ScorecardAppDelegate *)[[UIApplication sharedApplication] delegate];


            NSMutableDictionary* dialogParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                     kAppId, @"app_id",
                                     imageLink, @"link",
                                     thumbURL, @"picture",
                                     @"Just Played Wizard etc etc", @"name",
                                     nil];

            [appDelegate.facebook dialog:@"feed" 
                               andParams:dialogParams 
                             andDelegate:self];


            break;
        }
        case kAPIGraphUserPhotosPost: // step 2
        {

            NSString *imageID = [NSString stringWithFormat:[result objectForKey:@"id"]];            
            NSLog(@"id of uploaded screen image %@",imageID);

            currentAPICall = kAPIGraphPhotoData;
            appDelegate = (Scorecard4AppDelegate *)[[UIApplication sharedApplication] delegate];

            [appDelegate.facebook requestWithGraphPath:imageID
                                           andDelegate:self];
            break;
        }
    }
}

I've modified the code to show just the Facebook stuff condensed.我已修改代码以仅显示压缩的 Facebook 内容。 If you want to check if the post is successful you'll want something like this:如果你想检查帖子是否成功,你会想要这样的东西:

- (void)dialogDidComplete:(FBDialog *)dialog {
    switch (currentAPICall) {
        case kDialogFeedUser:
        {
            NSLog(@"Feed published successfully.");
            break;
        }
    }
}

脸书帖子

The blue text in the Facebook post is whatever you put in the "name" parameter in Step 3. Clicking on the blue text in Facebook will take you to the photo posted in Step 1, in an album in Facebook (Facebook creates a default album for your app if you don't specify an album). Facebook 帖子中的蓝色文本是您在第 3 步中输入“名称”参数的任何内容。单击 Facebook 中的蓝色文本将带您到第 1 步中发布的照片,在 ZD85544FCE4FCE408 的默认相册中创建一个默认相册(Facebook如果您未指定专辑,则适用于您的应用程序)。 In my app's case it's the full-sized image of the scorecard (but could be any image, eg from the camera).在我的应用程序中,它是记分卡的全尺寸图像(但可以是任何图像,例如来自相机的图像)。 Unfortunately I couldn't figure out a way to make the thumb image a live link, but it's not very readable so a default thumb works in my case.不幸的是,我想不出一种方法来使拇指图像成为实时链接,但它的可读性不是很好,因此默认拇指适用于我的情况。 The part in the Facebook post (in black font) that says "First game of the year..." is entered by the user. Facebook 帖子(黑色字体)中写着“年度第一场比赛......”的部分由用户输入。

It's clearer what you wish to do - post a photo to FB, and guarantee that a post goes on the user's wall/stream.更清楚您想要做什么 - 将照片发布到 FB,并保证帖子会出现在用户的墙上/流中。

Unfortunately, there are some things in the way.不幸的是,有一些事情在路上。

FB Graph API appears to only allow you to post EITHER a picture to an album, or post to the wall directly, linking to a picture already existing somewhere on the web. FB Graph API 似乎只允许您将图片发布到相册,或直接发布到墙上,链接到 web 某处已经存在的图片。 In the first case, a post in the stream will probably be made, but FB appears to consolidate multiple posts in some manner so as to keep the user's stream from being bombarded.在第一种情况下,stream 中可能会发一个帖子,但 FB 似乎以某种方式合并了多个帖子,以防止用户的 stream 被轰炸。 The mechanism for this is not documented anywhere I could see.我能看到的任何地方都没有记录这种机制。

In the second case, you might think you could get away with posting to an album, and then explicitly posting a link to the album.在第二种情况下,您可能认为您可以通过发布到相册,然后明确发布指向该相册的链接而侥幸。 You can add a parameter to the original album post, "no_story" with a value of 1, and suppress the wall post that might be made while you prepare to make an explicit one.您可以在原始专辑帖子中添加一个参数“no_story”,值为 1,并在您准备制作显式帖子时抑制可能发布的墙帖。 However, FB will not have the source URL for a newly posted image for a while, AND, it doesn't appear to like URLs that include its own content delivery network, returning an error.但是,FB 暂时不会有新发布的图片的来源 URL,而且,它似乎不喜欢包含自己的内容交付网络的 URL,返回错误。 You might think to simply put status update in the stream, talking about the post, However, the Graph API is also limited to 25 such direct feed posts per day per app, to prevent spamming.您可能会认为只是将状态更新放在 stream 中,谈论帖子,但是,图表 API 也仅限于每个应用每天 25 个此类直接提要帖子,以防止垃圾邮件。

One solution would be to post to something like Flickr, get the URL of the image, and then post to the wall.一种解决方案是发布到 Flickr 之类的内容,获取图像的 URL,然后发布到墙上。 FB's preferred solution appears to be to use the FB dialogs that are part of the mobile toolkit - essentially little web pages much like the OAuth screen. FB 的首选解决方案似乎是使用作为移动工具包一部分的 FB 对话框 - 基本上是很小的 web 页面,很像 OAuth 屏幕。

Personally, I plan to simply post to the album as above, and live with FB's idea of how the user should be notified.就个人而言,我打算像上面那样简单地发布到相册,并接受 FB 关于如何通知用户的想法。 Curious how you choose to proceed.好奇你如何选择继续。

I'm not sure what part isn't working for you, since you are posting and getting an ID back, but here is what I did in a quick and dirty way, in case someone reaches here via Google.我不确定哪个部分不适合您,因为您正在发布并取回 ID,但这是我以一种快速而肮脏的方式所做的,以防有人通过 Google 到达这里。

This is an HTTP POST function, and the binary data of the file goes up as multipart mime.这是一个 HTTP POST function,文件的二进制数据作为多部分 mime 上升。

I'm a big fan of the ASIHTTPRequest library available here .我非常喜欢这里提供的 ASIHTTPRequest 库。

**UPDATE: 10/22/2012 ** - AFNetworking has replaced ASIHTTPRequest in my code in the past few months. **更新:2012 年 10 月 22 日 ** - 在过去的几个月里,AFNetworking 在我的代码中替换了 ASIHTTPRequest。 Available on GitHub here GitHub 可在此处获得

Facebooks docs are confusing, partly because they are incomplete and partly because they can be wrong. Facebook 的文档令人困惑,部分原因是它们不完整,部分原因是它们可能是错误的。 You'll probably tear some hair out figuring out exactly what post value to set for a caption or something, but this recipe puts a photo into an album, and that goes into the feed.您可能会费力地弄清楚要为标题或其他内容设置什么帖子值,但是这个食谱将照片放入相册,然后进入提要。

You still need to set up the Facebook OAuth stuff in the basic way - I happened to do that in the app delegate, so I grab the Facebook object from there to get my access token. You still need to set up the Facebook OAuth stuff in the basic way - I happened to do that in the app delegate, so I grab the Facebook object from there to get my access token. I made sure to ask for the "publish_stream" permission when I authenticated, like this:当我进行身份验证时,我确保请求“publish_stream”权限,如下所示:

[facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil] delegate:self];

This will create or add to an album called "YOUR_APP_NAME Photos", and will appear in the user's feed.这将创建或添加到名为“YOUR_APP_NAME 照片”的相册,并将出现在用户的供稿中。 You can put it in any album, including the "Wall" album, by getting the ID of that album and changing the URL to http://graph.facebook.com/THE_ID_OF_THE_ALBUM/photos . You can put it in any album, including the "Wall" album, by getting the ID of that album and changing the URL to http://graph.facebook.com/THE_ID_OF_THE_ALBUM/photos .

Here's the basic method:这是基本方法:

-(void) postImageToFB:(UIImage *) image
{

    NSData* imageData = UIImageJPEGRepresentation(image, 90);
    Facebook* fb = [(uploadPicAppDelegate *)[[UIApplication sharedApplication] delegate] facebook   ];


    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"https://graph.facebook.com/me/photos"]];
    [request addPostValue:[fb accessToken] forKey:@"access_token"];
    [request addPostValue:@"image message" forKey:@"message"];
    [request addData:imageData forKey:@"source"];

    [request setDelegate:self];
    [request startAsynchronous];  
}

Using the Facebook provided iOS library looks like this:使用 Facebook 提供的 iOS 库如下所示:

-(void) postImageToFB:(UIImage *) image
{

    NSData* imageData = UIImageJPEGRepresentation(image, 90);
    Facebook* fb = [(uploadPicAppDelegate *)[[UIApplication sharedApplication] delegate] facebook   ];

    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:[fb accessToken],@"access_token",
                                    @"message text", @"message",
                                    imageData, @"source",
                                    nil];
    [fb requestWithGraphPath:@"me/photos" 
                   andParams:params 
               andHttpMethod:@"POST" 
                 andDelegate:self];


}

Using Facebook SDK 3.0:使用 Facebook SDK 3.0:

 - (void)postPhotoThenOpenGraphAction {
    FBRequestConnection *connection = [[FBRequestConnection alloc] init];

    // First request uploads the photo.
    FBRequest *request1 = [FBRequest 
        requestForUploadPhoto:self.selectedPhoto];
    [connection addRequest:request1
        completionHandler:
        ^(FBRequestConnection *connection, id result, NSError *error) {
            if (!error) {
            }
        }
            batchEntryName:@"photopost"
    ];

    // Second request retrieves photo information for just-created 
    // photo so we can grab its source.
    FBRequest *request2 = [FBRequest 
        requestForGraphPath:@"{result=photopost:$.id}"];
    [connection addRequest:request2
         completionHandler:
        ^(FBRequestConnection *connection, id result, NSError *error) {
            if (!error &&
                result) {
                NSString *source = [result objectForKey:@"source"];
                [self postOpenGraphActionWithPhotoURL:source];
            }
        }
    ];

    [connection start];
}

They follow this post with an OpenGraph action publish ( [self postOpenGraphActionWithPhotoURL:source]; ), but if you just want the image on the user's wall, you wont need that.他们使用 OpenGraph 操作发布 ( [self postOpenGraphActionWithPhotoURL:source]; ) 关注这篇文章,但如果您只想要用户墙上的图像,则不需要它。

More info: https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/publish-open-graph-story/#step7更多信息: https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/publish-open-graph-story/#step7

Yay,.耶,。 FB SDK 3.0 rocks: No more AppDelegate.facebook :) FB SDK 3.0 摇滚:不再有 AppDelegate.facebook :)

I searched far and wide for a solution that worked on the latest APIs, until I came across this:我广泛搜索了适用于最新 API 的解决方案,直到遇到以下问题:

http://xcodenoobies.blogspot.co.uk/2012/09/how-to-upload-photo-and-update-status.html http://xcodenoobies.blogspot.co.uk/2012/09/how-to-upload-photo-and-update-status.html

By far the clearest solution I've come across, simple and works with the latest API.到目前为止,我遇到的最清晰的解决方案,简单且适用于最新的 API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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