使用App Links Hosting API从iOS应用程序在Facebook上共享链接

时间:2014-06-11 07:19:01

标签: ios facebook opengraph applinks

我老老实实地花了几个小时试图让它发挥作用。不幸的是Facebook& App Link's documentation不够明确。甚至是App Links video from F8

应用要求:

  1. 分享一个指向FB的链接作为Open Graph故事,用户可以点击该故事将其直接带入我的应用程序并执行特定任务(我的应用程序需要从链接接收特定参数)
  2. 在没有FB登录的情况下共享FB链接(即通过共享对话框切换到本机iOS FB应用程序,而不是使用API​​调用)。
  3. 到目前为止的进展:

    我正在使用以下代码根据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(这是很好但没有正确的网址)

    // 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都将是动态的,并且每个用户都是唯一的在app中生成它。)

    请帮忙!

3 个答案:

答案 0 :(得分: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");
                                                     }
                                                 }];


    }

请注意&#34; customURL&#34;是一个遵循模式的NSString&#34;?variable1 = result1&amp; variable2 = result2 ...&#34;

答案 1 :(得分:1)

这适用于Graph v2.5和SDK 4.8。绝对不容易,没有记录。但感谢Tim For鼓舞人心。 我使用的是自定义图形对象,但我不知道它是如何使用默认图形对象的。 我也使用App Links主机,因为我没有网络应用程序。 我从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更有意义。图谱API资源管理器可用于了解您应发送的数据。

获得成功后,获取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) {}];

}

答案 2 :(得分:0)

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

Cannot get the new AppLinks to work on iOS or Android