在iOS上使用Facebook应用程序链接时,如何将深层链接查询参数注入appLinkData?

时间:2015-01-14 21:19:37

标签: ios iphone facebook facebook-graph-api

我的问题是基于Jason Clark在2014年f8发表的声明,即应用链接旨在与深层链接技术并列。我有一个文字游戏应用程序在2013年发布到加拿大和澳大利亚使用Facebook的身份验证,但没有深层链接。对于美国市场推出,我的意图是添加Facebook深层链接。使用请求和提要对话框进行管理,以发送匹配标识符UUID,用于启动匹配,然后吹嘘当时的匹配(FriendSmash示例)以打开该匹配的游戏。我的日常工作受阻,我没有时间完成QA并支持向美国发射。去年夏天我升级了SDK(Facebook 3.14)并且url查询不再包含字符串'notif'以允许我解析匹配ID。因此,我从使用[FBSession.activeSession handleOpenURL:url]切换到当前[FBAppCall handleOpenURL:url ...]以及新FriendSmash示例中的一些其他代码。但是,从Facebook应用程序传递的URL不再包含'ref',因此不是'notif',这是记录利用我的深层链接内容的方法。我已经将我的项目更新到Facebook iOS SDK 3.21(部分由其他SDK预测,例如AWS不支持arm64)。

我目前使用以下代码发送吹嘘

- (void) sendBrag
{
    // This function will invoke the Feed Dialog to post to a user's Timeline and News Feed
    // It will attemnt to use the Facebook Native Share dialog
    // If that's not supported we'll fall back to the web based dialog.


    NSArray *friend = [[NSArray alloc] initWithObjects: bragMatch.opponentFacebookId, nil];
    NSString *linkURL = [NSString stringWithFormat:@"http://www.ruleofwords.com/?deeplink_matchno=%@", bragMatch.initiatorMatchNo];

    //NSString *linkURL = [NSString stringWithFormat:@"http://www.ruleofwords.com"];
    NSString *pictureURL = @"https://pacific-castle-1361.herokuapp.com/rowappicon.png";
    NSMutableString *msg = [[NSMutableString alloc]
                            initWithString:@"Just scored 0 points in Rule of Words. Good luck trying to beat that."];

    [msg replaceOccurrencesOfString:@"0" withString:bragMatch.initiatorMatchPoints
                            options:NSBackwardsSearch range: NSMakeRange(0, [msg length])];


    // Prepare the native share dialog parameters
    FBLinkShareParams *shareParams = [[FBLinkShareParams alloc] init];
    shareParams.friends = friend;
    shareParams.link = [NSURL URLWithString:linkURL];
    shareParams.name = @"Rule of Words Bragging Rights";
    shareParams.caption= msg;
    shareParams.picture= [NSURL URLWithString:pictureURL];
    shareParams.linkDescription = @"Rule of Words, the contagious photography word social game on iPhone.";

    if ([FBDialogs canPresentShareDialogWithParams:shareParams]){

        [FBDialogs presentShareDialogWithParams:shareParams
                                    clientState:nil
                                        handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
                                            if(error) {
                                                NSLog(@"Error publishing story.");
                                            } else if (results[@"completionGesture"] && [results[@"completionGesture"] isEqualToString:@"cancel"]) {
                                                NSLog(@"User canceled story publishing.");
                                            } else {
                                                NSLog(@"Story published.");
                                            }
                                        }];

    } else {

        // Prepare the web dialog parameters
        NSDictionary *params = @{
                                 @"to": bragMatch.opponentFacebookId,
                                 @"name" : shareParams.name,
                                 @"caption" : shareParams.caption,
                                 @"description" : shareParams.linkDescription,
                                 @"picture" : pictureURL,
                                 @"link" : linkURL
                                 };

        // Invoke the dialog
        [FBWebDialogs presentFeedDialogModallyWithSession:nil
                                               parameters:params
                                                  handler:
         ^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
             if (error) {
                 NSLog(@"Error publishing story %@.", error);
             } else {
                 if (result == FBWebDialogResultDialogNotCompleted) {
                     NSLog(@"User canceled story publishing.");
                 } else {
                     NSLog(@"Story published.");
                 }
             }}];
    }
}

(旁白 - 在我单步执行sendBrag代码时,FBDialogs canPresentShareDialogWithParams总是失败,所以每次默认为一个提要对话框。任何人都知道状态是什么,共享对话框的工作原理是什么?)

然后在我的AppDelegate中我有......

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    NSLog(@"app is %@ and url is %@ and sourceApp is %@", application, url, sourceApplication);
    // attempt to extract a token from the url
    return [FBAppCall handleOpenURL:url
                  sourceApplication:sourceApplication
                    fallbackHandler:^(FBAppCall *call) {
                        // If there is an active session
                        if (FBSession.activeSession.isOpen) {
                            // Check the incoming link
                            [self handleAppLinkData:call.appLinkData];
                        } else {
                            NSLog(@"Access Token is %@", call.accessTokenData);
                            if (call.accessTokenData) {
                              // If token data is passed in and there's
                              // no active session.
                              if ([self handleAppLinkToken:call.accessTokenData]) {
                                // Attempt to open the session using the
                                // cached token and if successful then
                                // check the incoming link
                                [self handleAppLinkData:call.appLinkData];
                              }
                            }
                        }
                    }];

- (void) handleAppLinkData:(FBAppLinkData *)appLinkData {

    NSURL *targetURL = appLinkData.targetURL;
    if (targetURL) {
        //NSURL *targetURL = [NSURL URLWithString:targetURLString];
        NSDictionary *targetParams = [self parseURLParams:[targetURL query]];
        NSString *ref = [targetParams valueForKey:@"ref"];
        // Check if ref parm is among incoming news feed link, otw attribution link
        if ([ref isEqualToString:@"notif"]) {
            // Get the request id
            NSString *requestIDParam = targetParams[@"request_ids"];
            NSArray *requestIDs = [requestIDParam
                                   componentsSeparatedByString:@","];

            // Get data (of last request) from Graph API call to request id endpoint
            // 
            [self notificationGet:requestIDs[[requestIDs count]-1]];
        }
    }
} 

- (void) notificationGet:(NSString *)requestid {
    __block NSString *title;
    __block NSString *message;

    [FBRequestConnection startWithGraphPath:requestid
                          completionHandler:^(FBRequestConnection *connection,
                                              id result,
                                              NSError *error) {
                if (! error) {
                if (result[@"data"]) 
                 {
                      title = [NSString stringWithFormat:
        @"%@ requests a match!", result[@"from"][@"name"]];
                          NSString *jsonString = result[@"data"];
              NSData *jsonData = [jsonString                                        dataUsingEncoding:NSUTF8StringEncoding];
                          if (!jsonData) {
                          NSLog(@"JSON decode error: %@", error);
                          return;
                          }
                          NSError *jsonError = nil;
                          NSDictionary *requestData =[NSJSONSerialization                               JSONObjectWithData:jsonData                                                                                                         options:0
                                                                                                                      error:&jsonError];
                        if (jsonError) {
                          NSLog(@"JSON decode error: %@", error);
                          return;
                        }
                        message = [NSString stringWithFormat:@"Match #: %@, Flashes: %@",
                                       requestData[@"deeplink_matchno"],
                                       requestData[@"flashes_gifted"]];
                       // set global opponentFacebookId for bragging
                      [[rowGlobals sharedGlobalVars]                                        setRowGlobal:requestData[@"deeplink_matchno"]
                                    forKey:@"deeplink_matchno"] ;

                        // Set up FB Deep Link Notification
                // homeViewController is registered for notification
                      [[NSNotificationCenter defaultCenter]
                         postNotificationName:FBDeepLinkNotification
                                       object:requestData[@"deeplink_matchno"]];
                       NSLog(@"successfully posted DeepLink notification") ;

                    } else {
                      title = [NSString stringWithFormat:@"%@ sent you a request",                      result[@"from"][@"name"]];
                        message = result[@"message"];
                    }

                                  // Delete the request notification
                    [self notificationClear:result[@"id"]];
            } else {
                title = @"General Deep Link Error" ;
                message = @"Error occured with Facebook FBRequest Connection. This Facebook notification likely has been previously processed." ;
            }
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil,
                                                    nil];
            [alert show];

        }];
}

现在我认识到我已经做了一些清理,以便将对话框设置与我解析appLinkData的方式保持一致,以便让我的NSNotification的matchId UUID在游戏中打开,但是我没有那么费心去清理它。

我在我的网站上尝试了很多元标记,但目前我只是在使用

<meta property=”al:ios:url” content=”ruleofwords”>

其中ruleofwords是我添加到应用的plist中的自定义网址。

但我似乎无法将除

之外的任何网址放在一起
NSString *linkURL = [NSString stringWithFormat:@"http://www.ruleofwords.com"];

将通过点击Facebook链接启动我的游戏......

当我使用

之类的东西时
NSString *urlLink = [NSString stringWithFormat:@"https://www.ruleofwords.com/?deeplink_matchNo=%@", bragMatch.initiatorMatchNo];

然后,Facebook只会启动我的网页,而没有自定义URL链接到我的游戏。

此外,Facebook不再直接推出它;它会显示我的网页,其中添加的链接显示为偏移括号应用链接徽标。(虽然不明确,但它在技术上遵循Facebook流程diagram)。触摸这个应用程序Link logo确实启动了我的游戏。这似乎是我的网站上是否有元标记(现在我可能有其他问题,因为我们只使用Godaddy网站建设者)。

以前在请求对话框中,我能够使用像我的匹配ID和礼物一样填充@“data”等值。

NSData *jsonData = [NSJSONSerialization
           dataWithJSONObject:@{
                                @"deeplink_matchno": bragMatch.initiatorMatchNo,
                                @"flashes_gifted": @"0"}
                        options:0
                        error:&error];
    if (!jsonData) {
        NSLog(@"JSON error: %@", error);
        return;
    }

    NSString *challengeStr = [[NSString alloc]
                              initWithData:jsonData
                              encoding:NSUTF8StringEncoding];

NSMutableDictionary *params = 
  [NSMutableDictionary dictionaryWithObjectsAndKeys:                                                            
     bragMatch.opponentFacebookId, @"to",
     @"Rule of Words Bragging", @"name",
     msg, @"caption",
     @"Rule of Words, the contagious photography word social game on iPhone.",
       @"description",
    urlLink, @"link",
    @"https://pacific-castle-6969.herokuapp.com/rowappicon.png", @"picture",
   challengeStr, @"data",
   nil];

    // Invoke the dialog
    //[self.facebook dialog:@"feed" andParams:params andDelegate:self];
    //[FBWebDialogs presentFeedDialogModallyWithSession:nil
    [FBWebDialogs presentRequestsDialogModallyWithSession:nil
                                                  message:msg
                                                    title:nil
                                               parameters:params
                                                  handler:
     ^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
         if (error) {
             // Case A: Error launching the dialog or publishing story.
             NSString *errormsg = [NSString stringWithFormat:@"Error encountered posting Facebook brag with error %@", error.localizedDescription];
             NSLog(@"%@", errormsg);
             UIAlertView *alert = [[UIAlertView alloc]
                                   initWithTitle:@"Facebook Brag Error"
                                   message:errormsg
                                   delegate:nil
                                   cancelButtonTitle:@"Ok"
                                   otherButtonTitles: nil];
             [alert show];
         } else {
             if (result == FBWebDialogResultDialogNotCompleted) {
                 // Case B: User clicked the "x" icon
                 NSLog(@"Player canceled Facebook brag post via x icon.");
             } else {
                 // Case C: Dialog shown and the user clicks Cancel or Share
                 NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
                 //if (![urlParams valueForKey:@"post_id"]) {
                if ([urlParams valueForKey:@"error_code"]) {
                // User clicked the Cancel button
                     NSLog(@"error message is %@", [urlParams valueForKey:@"error_message"]);
                     NSLog(@"Player canceled Facebook brag post via Cancel button.");
                 } else {
                     // User clicked the Share button
                     //NSString *postID = [urlParams valueForKey:@"post_id"];
                     NSString *postID = [urlParams valueForKey:@"request"];
                     NSLog(@"Player Successfuly Posted RoW Match via Facebook brag, id: %@", postID);
                 }
             }
         }
     }];

但是,我在该请求对话框的传递URL中不再有al_applink_data,它只有一个带有原始自定义URL的access_token。

网址为fb407545862655947://授权/#=的access_token&CAAFyqSpfj8sBAGxahmdTCl1D9fs5hZBt3OfKP2MHCtM8STHadqEjlyFnXDTNHScjsxZCI6q0H8ZAppNSqJIJt83uN4LemkfklLjOdPTv3JZBtg3xTVZBKOhzdOMaZCGob5x2FPddZBzmaZBhIaE8dIgNqPfi9IlEuwQ2oHq6tEgA1w1pNESnHuDyK9gD7vswAC93nO7cCmCT4KBgxI22UDB3nINYZA058g8AZD放大器; expires_in = 3600和sourceApp是com.facebook.Facebook

当我用

添加@“data”参数时
[FBWebDialogs presentFeedDialogModallyWithSession:…]

虽然这个参数被feed对话框接受,但我的url没有从我的@“data”参数获得我的匹配UUID或其他任何内容......

url是ruleofwords:///?al_applink_data =%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fwww.ruleofwords.com%5C%2F%22%2C%22extras%22% 3A%7B%22fb_ref%22%3A%22Default%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fbacktrack_id% 3Ddlr5p6iu_6a-OeUn%22%2C%22app_name%22%3A%22Facebook%22%7D%7D and sourceApp is com.facebook.Facebook

所以我不知道我应该如何注入内容特定信息,以便我可以用对手打开我的比赛,这是对手所要求或吹嘘的。我可能会在很久以前放弃,但我曾经做过深度链接工作(SDK 3.5?)。我想知道我是否应该在SDK的另一个版本级别进行深层链接。似乎Facebook平台已经显着改变了它打包appLinkData的方式。虽然Facebook的文档在过去两年中有所改进,但将这些文档放在一起所需的许多示例似乎并不是指同一级别的SDK。那么Facebook如何将内容注入appLinkData,以便我可以支持与SDK 3.21的深层链接?我想添加Bolts框架,但Jason暗示它是专为链接应用而设计的,这不是我的情况。

我可以直接输入我的iPhone Safari,例如'ruleofwords:// matchId = UUID',并让app委托解析出[url查询],这样我就可以实现与推送通知的深层链接,但我仍然喜欢能够让Facebook用户点击链接并直接启动特定匹配。

0 个答案:

没有答案