我的问题是基于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用户点击链接并直接启动特定匹配。