【问题标题】:Using App Links Hosting API for link shared on Facebook from iOS app使用 App Links Hosting API 从 iOS 应用程序在 Facebook 上共享链接
【发布时间】:2014-06-11 07:19:01
【问题描述】:

老实说,我已经花了好几个小时试图让它发挥作用。不幸的是Facebook & App Link's documentation 不够清楚。甚至App Links video from F8

应用要求:

  1. 将 FB 链接作为 Open Graph 故事分享,用户可以单击该链接将其直接带入我的应用并执行特定任务(我的应用需要从链接接收特定参数)
  2. 无需登录 FB 即可共享到 FB 的链接(即通过共享对话框并切换到本机 iOS FB 应用,而不是使用 API 调用)。

目前的进展:

我正在使用以下代码根据FB developer's website under Publishing iOS SDK. 创建托管应用链接(因为我只有移动内容)

NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"{My app name}", @"name",
                            {custom URL}, @"al:iphone:url",
                            @"{app store ID}", @"al:iphone:app_store_id",
                            @"{My app name}", @"al:iphone:app_name",
                            @"{\"should_fallback\": false}", @"web",
                            fbAccessToken, @"access_token",
                            nil
                            ];

/* make the API call */
[FBRequestConnection startWithGraphPath:@"/{FB app id}/app_link_hosts"
                             parameters:params
                             HTTPMethod:@"POST"
                      completionHandler:^(
                                              FBRequestConnection *connection,
                                              id result,
                                              NSError *error
                                              ) {
                              /* handle the result */
                              NSLog(@"Result = %@",result);
                              if(error) NSLog(@"error = %@",error);
                          }];

接下来我将 OG 故事发布到 FB(这帖子很好,但没有正确的 url)

// Create OG object
id<FBGraphObject> object =
[FBGraphObject openGraphObjectForPostWithType:@"{app name}:{FB object_name}"
                                        title:@"Test Link"
                                        image:@"https://cdn3.iconfinder.com/data/icons/picons-social/57/56-apple-512.png" // hosted wallpaper with unique id for background
                                          url:nil // Assuming I need to put the url to the app link host object here??

                                  description:@"Click to on this test link!"];

// Create an action
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];

// Link the object to the action
[action setObject:object forKey:@"{FB object name}"];

// Check if the Facebook app is installed and we can present the share dialog
FBOpenGraphActionParams *params = [[FBOpenGraphActionParams alloc] init];
params.action = action;
params.actionType = @"{app name}:{FB action name}";

// If the Facebook app is installed and we can present the share dialog
if([FBDialogs canPresentShareDialogWithOpenGraphActionParams:params]) {
    // Show the share dialog
    [FBDialogs presentShareDialogWithOpenGraphAction:action
                                          actionType:@"{app name}:{FB action name}"
                                 previewPropertyName:@"{FB object name}"
                                             handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
                                                 if(error) {
                                                     // An error occurred, we need to handle the error
                                                     // See: https://developers.facebook.com/docs/ios/errors
                                                     NSLog(@"Error publishing story: %@", error.description);
                                                 } else {
                                                     // Success
                                                     NSLog(@"result %@", results);
                                                 }
                                             }]; 
}

为了在有人点击 FB OG 故事中的链接时处理传入的 URL,我已根据 FB 文档将以下代码添加到 AppDelegate.m - 请参阅 Handling incoming links

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

    BOOL urlWasHandled =
    [FBAppCall handleOpenURL:url
           sourceApplication:sourceApplication
             fallbackHandler:
     ^(FBAppCall *call) {
         // Parse the incoming URL to look for a target_url parameter
         NSString *query = [url query];
         NSDictionary *params = [self parseURLParams:query];
         // Check if target URL exists
         NSString *appLinkDataString = [params valueForKey:@"al_applink_data"];
         if (appLinkDataString) {
             NSError *error = nil;
             NSDictionary *applinkData =
             [NSJSONSerialization JSONObjectWithData:[appLinkDataString dataUsingEncoding:NSUTF8StringEncoding]
                                             options:0
                                               error:&error];
             if (!error &&
                 [applinkData isKindOfClass:[NSDictionary class]] &&
                 applinkData[@"target_url"]) {
                 NSString *targetURLString = applinkData[@"target_url"];
                 // Show the incoming link in an alert
                 // Your code to direct the user to the
                 // appropriate flow within your app goes here
                 [[[UIAlertView alloc] initWithTitle:@"Received link:"
                                             message:targetURLString
                                            delegate:nil
                                   cancelButtonTitle:@"OK"
                                   otherButtonTitles:nil] show];
             }
         }
     }];
    return urlWasHandled;
}

// A function for parsing URL parameters
- (NSDictionary*)parseURLParams:(NSString *)query {
    NSArray *pairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    for (NSString *pair in pairs) {
        NSArray *kv = [pair componentsSeparatedByString:@"="];
        NSString *val = [[kv objectAtIndex:1]
                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [params setObject:val forKey:[kv objectAtIndex:0]];
    }
    return params;
}

有没有人能够让这个工作?我仍然不清楚托管的 App Link 是如何工作的以及放在哪里(我假设它应该在调用 FBGraphObject openGraphObjectForPostWithType 方法时进入'url'参数。

我真的不想创建一个网站来存储所有网址并添加 App Link 元标记(我必须通过应用程序完成所有这些操作,因为每个 App Link 对每个用户来说都是动态且唯一的从应用程序中生成它)。

请帮忙!

【问题讨论】:

  • 您能否包含上述任何代码 sn-ps 发出的请求的结果?我有几点观察:1.)我们要求应用程序链接主机调用具有应用程序访问令牌(而不是用户访问令牌),因此通常不应在移动客户端上发出这些请求。 2.) 对于 OG 对象,您应该使用我们在创建应用链接主机后提供的 fb.me url(有关如何获取 fb.me url - developers.facebook.com/docs/applinks/hosting-api 的文档,请参阅此文档)
  • @MingLi 感谢您的指导!我现在可以使用应用访问令牌。将做一些测试,看看我是否可以将自定义 URL 正确地传递回我的应用程序。应用可以拥有多少个应用链接主机以及它们的活动时间是否有限制?
  • @MingLi 我的应用现在可以使用托管的应用链接发布到 OG。当我单击 iOS FB 中的链接时,它会切换到我的应用程序,但是 NSString *query = [url query](在 AppDelegate 中)返回 null,尽管返回了大量 url?这是基于来自 FB 开发者页面的代码。有什么想法可能是错的吗?
  • 嗯,奇怪,你能把网址发给我,让我看看吗?
  • @MingLi 不知道有什么方法可以在这里私信你,所以我已经通过 FB 将它以消息的形式发送给你(将在你的“其他”文件夹中)。希望没问题。

标签: ios facebook facebook-opengraph applinks


【解决方案1】:

在 FB 的 MingLi 的帮助下,我设法使用以下代码使其工作:

- (void)shareToOpenGraphCountdownInvite
{
    NSURL *url = [NSURL URLWithString:@"https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id={insert your FB app ID here}&client_secret={insert client secret here}"];
    NSString *fullToken = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSArray *components = [fullToken componentsSeparatedByString:@"="];
    FBAppAccessToken = [components objectAtIndex:1];

    NSDictionary *paramsForAppLinksHost = [NSDictionary dictionaryWithObjectsAndKeys:
                                           FBAppAccessToken, @"access_token",
                                           @"{your app name}", @"name",
                                           @"{your app's custom url}", @"al:ios:url",
                                           @"{app store ID}", @"al:ios:app_store_id",
                                           @"{your app name}", @"al:ios:app_name",
                                           @"{\"should_fallback\": false}", @"web",
                                           nil
                                           ];

    [FBRequestConnection startWithGraphPath:@"/{FB app ID}/app_link_hosts"
                                 parameters:paramsForAppLinksHost
                                 HTTPMethod:@"POST"
                          completionHandler:^(
                                              FBRequestConnection *connection,
                                              id result,
                                              NSError *error
                                              ) {
                              AppLinksHostURL_ID = [result objectForKey:@"id"]; // store this ID in an NSString
                              [self postOGStoryWithCustomURL];
                              if(error) NSLog(@"error = %@", error.description);

                          }];
}

- (void)postOGStoryWithCustomURL
{
    NSString *urlString = [NSString stringWithFormat:@"https://fb.me/%@/%@", AppLinksHostURL_ID, customURL];

    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[self pathForS3ObjectWithFilename:previewImageFilename]]]];

    // Create OG object
    id<FBGraphObject> object =
    [FBGraphObject openGraphObjectForPostWithType:@"timeflyz:countdown_invite"
                                            title:eventBeingShared.eventName
                                            image:image
                                              url:urlString // fb.me app links hosted url here
                                      description:@"{insert description here}"];

    // Create an action
    id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];

    // Link the object to the action
    [action setObject:object forKey:@"countdown_invite"];

    // Check if the Facebook app is installed and we can present the share dialog
    FBOpenGraphActionParams *params = [[FBOpenGraphActionParams alloc] init];
    params.action = action;
    params.actionType = @"timeflyz:create";

    // If the Facebook app is installed and we can present the share dialog
    if([FBDialogs canPresentShareDialogWithOpenGraphActionParams:params]) {
        // Show the share dialog
        [FBDialogs presentShareDialogWithOpenGraphAction:action
                                              actionType:@"timeflyz:create"
                                     previewPropertyName:@"countdown_invite"
                                                 handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
                                                     if(error) {
                                                         // An error occurred, we need to handle the error
                                                         // See: https://developers.facebook.com/docs/ios/errors
                                                         NSLog(@"Error publishing story: %@", error.description);
                                                     } else {
                                                         //                                                         NSLog(@"result %@", results);
                                                         if([[results objectForKey:@"completionGesture"] isEqualToString:@"post"]) {
                                                             NSLog(@"Posted successfully!");
                                                             [[NSNotificationCenter defaultCenter] postNotificationName:@"showShareSuccessfullMessage" object:self userInfo:nil];
                                                         } else
                                                             NSLog(@"Something else happened - user didn't post");
                                                     }
                                                 }];


    }

请注意,“customURL”是一个遵循“?variable1=result1&variable2=result2...”模式的 NSString

【讨论】:

  • 您不应在客户端使用/存储 FB 应用程序密码。您应该在服务器端创建 AppLinks URL,然后从客户端查询 AppLinks URL。
  • 这也是我的要求...无需登录即可共享打开的图表故事...但是即使使用您的方法,我也得到了没有我的自定义参数的 URL。收到的 URL 类似于 fb://bridge/ogshare?version=20140410&cipher=。有任何想法吗?除了让我的 FB 应用程序正确之外,我是否需要在任何地方注册?
  • 更不用说共享对话框对我有用,但唯一的问题是我希望 target_URL 回来进行自定义处理,这在此处缺少。这就是我的问题。
  • @Tim 你能和我们分享你的代码吗,我正在尝试在 ios 8 中实现 facebook 深度链接。你的帮助将拯救我。
  • 嗨,在 facebook 上分享帖子时出现错误:发布故事时出错:错误 Domain=com.facebook.Facebook.platform Code=102 “操作无法完成。(com.facebook .Facebook.platform error 102.)" UserInfo=0x155d4620 {error_code=102, error_description=发布时出错。, app_id=568617263271525, error_reason=操作无法完成。 (FBAPIErrorDomain 错误 200。)}
【解决方案2】:

这适用于 Graph v2.5 和 SDK 4.8。绝对不容易,也没有记录。但感谢蒂姆的启发。 我正在使用自定义图形对象,我不知道它如何与默认图形对象一起使用。 由于我没有网络应用程序,因此我也在使用 App Links Host。 我从 Graph API Explorer 获得了 {app_access_token},选择您的应用然后获取应用访问令牌

首先,我在 Facebook 开发人员(您的 Facebook 应用程序)上创建了图表故事、动作和对象类型。确保您在 info.plist 中为您的应用提供了一个应用查询方案 LSApplicationQueriesSchemes 应该包含一个指向您的应用的方案,我将其称为 {app_scheme}。

然后在我的 iOS 应用中,我为每个共享创建一个新链接。

- (void)createAppLinkHost:(void(^)(NSString* appLinkURL))success error:(void(^)(NSError* error))failure{

NSString *url = [NSString stringWithFormat:@"{app_scheme}://%li",self.object.identifier];
NSString *appAccessToken = {app_access_token};
NSString *iosLink = [NSString stringWithFormat:@"[{\"url\":\"%@\",\"app_name\":\"%@\",\"app_store_id\":%i},]",url,@"{app_name}",{app_store_id_int}];
NSDictionary *appLinkHostParams = @{@"access_token":appAccessToken,
                                    @"name":@"{link name}",
                                    @"web":@"{\"should_fallback\": false}",
                                    @"ios":iosLink
                                    };

FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]initWithGraphPath:@"/{fb_appId}/app_link_hosts"
                                                              parameters:appLinkHostParams
                                                             tokenString:appAccessToken
                                                                 version:@"v2.5"
                                                              HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    if (!error) {
        NSString *appLinkHostId = [result objectForKey:@"id"];
        NSString *urlString = [NSString stringWithFormat:@"https://fb.me/%@", appLinkHostId];
        success(urlString);
    }
    else{
        NSLog(@"--ERROR-- [FACEBOOK APP LINK HOST] %@",error);
        failure(error);
    }
}];

}

如果有错误,请检查。来自 App Link 主机的错误比 Facebook SDK 的其余部分更有意义。 Graph API Explorer 有助于了解您应该发送哪些数据。

一旦你获得成功,获取 AppLinkHost 并分享它。

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"fbauth2://"]]){
[self createAppLinkHost:^(NSString *appLinkURL) {
    SURL *imageURL = [NSURL URLWithString:self.activity.imageURL];;
    FBSDKSharePhoto *photo = [FBSDKSharePhoto photoWithImageURL:imageURL userGenerated:NO];
    //Custom objects needs to be set from facebook first.
    //Set object properties
    NSDictionary *properties = @{
                                 @"og:type": @"{namespace}:{graph_object}",
                                 @"og:title": @"title",
                                 @"og:description": @"body",
                                 @"og:image": @[photo],
                                 @"og:url":appLinkURL,
                                 @"fb:app_id":@"{fb_appId}",
                                 @"{namespace}:{custom_property}":@(self.object.identifier), //optional
                                 };            
    //Create GraphObject
    FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];

    //Create Action
    FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:@"{namespace}:{graph_action}" object:object key:@"{namespace}:{graph_object}"];

    FBSDKShareOpenGraphContent *openGraphcontent = [[FBSDKShareOpenGraphContent alloc] init];
    openGraphcontent.action = action;
    openGraphcontent.previewPropertyName = @"{namespace}:{graph_object}";

    [FBSDKShareDialog showFromViewController:self withContent:openGraphcontent delegate:self];
} error:^(NSError *error) {}];

}

【讨论】:

    【解决方案3】:

    我没有足够的代表发表评论,但如果您仍然卡住,请查看此答案:

    Cannot get the new AppLinks to work on iOS or Android

    【讨论】:

      猜你喜欢
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多