无法让新的AppLink在iOS或Android上运行

时间:2014-05-09 07:46:00

标签: android ios facebook meta-tags applinks

更新#5下面的最新更新

我正在尝试为我的iOS和Android应用实施AppLink:http://applinks.org

我做了以下事情:

  1. 为我的应用设置自定义网址方案:inacho://
  2. 我的应用代表中的设置:- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
  3. 在我的网站http://www.nachorater.com添加元标记:
  4. <meta property="al:ios:app_store_id" content="581815579"/>
    <meta property="al:ios:app_name" content="iNacho" />
    <meta property="al:ios:url" content="inacho://default" />
    

    我已经通过输入类似inacho:// default的链接并点击它创建的链接来验证网址方案的效果很好。 WA-LA!它会打开我的应用程序。

    但是,当我尝试从Facebook或Quip点击指向www.nachorater.com的链接时,这两个应用程序都没有自动注意到该网站设置了这些应用程序链接并且只是在浏览器中加载了网站而不是试图打开我的应用程序。

    有人有这个工作吗?

    更新

    我遇到了一些问题,其中一些元标记不在&lt;头&gt;我的模板的一部分,我修复了它。

    现在来自iOS Facebook应用程序的链接:http://www.nachorater.com添加了一个漂亮的小弹出窗口,可让您打开iNacho应用程序中的URL,如下所示:

    screenshot

    但我的动态评论链接似乎没有用,但Ming指出的Debug应用程序显示meta标签看起来正确。

    例如,http://www.nachorater.com/getReview?reviewID=6396169718595584

    使用https://developers.facebook.com/tools/debug/og/object?q=http%3A%2F%2Fwww.nachorater.com%2FgetReview%3FreviewID%3D6396169718595584进行调试时

    元标记:

    meta tags

    更新#2:

    我在iNacho Facebook时间线上发布了一个新的nacho评论链接,然后尝试从Facebook Mobile应用程序点击它。

    它开始加载页面并弹出方便的指示器,让你在iNacho中打开应用程序但是一旦页面加载,指示器就会消失(在我点击它之前)。

    更新#3:

    从Facebook应用程序中,我现在可以为我的评论触发一个inacho URL,但这只是在我消失之前点击iNacho中打开的小弹出窗口。如果我在Facebook的内置Web视图中完全加载页面,那么小弹出窗口仍会消失。

    这是Applinks的问题吗?或Facebook应用程序的问题?或者通过设计和为什么?

    更新#4:

    我可能知道问题是什么。审核页面依次为nacho评论加载动态图像。因此,通过加载页面,它有一个img src标记,指向加载图像的动态URL。这是否被误认为某种“重定向”行为?

    img标签示例(已呈现):<img width="300" src="/getReviewImage?imageID=6125868501958656"></img>

    注意:有许多其他脚本/ ajax也会动态加载(Facebook和Twitter小部件等)。

    这是AppLinks或Facebook Mobile应用程序中的错误吗?它不应该关心像ajax和动态图像这样的后台加载对象吗?

    更新#5

    2014年7月15日 - 最新的Facebook应用程序仍在发生这种情况。当我点击从我的iNacho Facebook页面到我的iNacho网站的链接时,它会弹出选项,在页面完成加载之前在应用程序中打开它一瞬间。然后它隐藏了它。

    对于Twitter应用程序,它甚至不会给我弹出一瞬间。它似乎没有认识到链接是启用了appslink。

    另一方面Quip,我粘贴了一个nacho链接,当我第一次点击它时,它进入了内置的safari,无法在我的应用程序中打开。但是,当我第二次点击它时,它会直接打开我的应用程序。

    总结:到目前为止,似乎有些应用程序正在实现AppLinks导航部分不正确或其他。 Quip似乎有效,但即使是Facebook自己的应用程序似乎也没有用。

3 个答案:

答案 0 :(得分:8)

我遇到了与AppLinks相同的问题,并决定完全放弃它们,只使用facebook的应用程序链接主机:https://developers.facebook.com/docs/applinks/hosting-api

我的应用程序仅限移动设备,我误解了AppLinks最初的工作方式。我以为我可以将al_ios_*元标记放在单个通用网页上,但这是错误的。我的网站上的每个内容都需要有一个单独的页面,并且每个页面都需要有自己的AppLinks元标记,才能将该特定内容的URL发送回我的应用程序。

当我做错了,当我在Facebook上点击我的OpenGraph故事时,它会在网络浏览器中打开我的网站,底部工具栏中有一个动作图标我可以点击并可以选择打开我的应用程序。或者我必须在OpenGraph故事中精确点击我的应用程序的名称。这些快速切换到我的应用程序,但URL不会特定于我希望我的应用程序导航到的内容。此外,这两个选项都很糟糕 - 我只是想点击故事中的任何地方并直接进入我的应用程序,这就是为什么我们都在这里。

解决方案

我将以分享对话框为例,使用OpenGraph故事。

首先,您需要在服务器上创建托管应用程序链接,而不是在应用程序中。在创建OpenGraph故事或正在共享的任何内容之前,请打电话给您的服务器以完成2件事:

1。)进行API调用以创建新的Facebook应用程序链接,该链接将为您提供ID

2。)使用该ID进行第二次API调用以获取托管应用链接的URL

这必须在服务器上完成,因为这些API调用需要应用访问令牌,而不是用户访问令牌。此令牌具有应用级权限,而非用户级权限。您不能也不应该在您的移动应用程序中的任何位置存储您的Facebook应用程序密码,因为有人可以反编译您的应用程序并更改您的Facebook应用程序。不好。使用您的服务器,因为它可以安全地了解您的应用程序密码。

我的服务器端是PHP,所以这里是一个如何实现此目的的示例。处理API并不是一种特别愉快的体验,所以我希望它可以帮助其他人格式化请求:

# create a new facebook app link using cURL
$metadata = <what to handle in AppDelegate application:openURL:sourceApplication:annotation>;
$url = "https://graph.facebook.com/v2.1/app/app_link_hosts";
$ch = curl_init($url);

# create form post data
$deepLinkURL = "<myApp>://" . $metadata;
$iosArray = json_encode(array(array("url"          => $deepLinkURL,
                                    "app_store_id" => <appStoreId (number)>,
                                    "app_name"     => "<myAppName>")
                              )
                       );
$webFallbackArray = json_encode(array("should_fallback" => false));

$formQuery = http_build_query(array("access_token" => "<appId>|<appSecret>",
                                    "name"         => $metadata,
                                    "ios"          => $iosArray,
                                    "web"          => $webFallbackArray)
                              );

# options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $formQuery);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

# get response
$responseJson = curl_exec($ch);
curl_close($ch);

# decode response from facebook
$jsonResponse = json_decode($responseJson, true);
$appLinkId = "";

# get appLinkId
foreach ($jsonResponse as $key => $val) {

    # get status
    if($key == "id") {
        $appLinkId = $val;
    }
}

# if response is good, need to request canonical URL from appLinkId
$errorMessage = "";
$canonicalUrl = "";

if(!empty($appLinkId)) {

    # create another instance of cURL to get the appLink object from facebook using the ID generated by the previous post request
    $getAppLinkUrl = "https://graph.facebook.com/" . $appLinkId;
    $ch2 = curl_init();

    # cURL options
    $queryString = http_build_query(array("access_token" => "<appId>|<appSecret>",
                                          "fields"       => "canonical_url",
                                          "pretty"       => true)
                                    );
    curl_setopt($ch2, CURLOPT_URL, $getAppLinkUrl . "?" . $queryString);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

    # get response
    $urlResponseJson = curl_exec($ch2);
    curl_close($ch2);

    # decode response from facebook
    $urlJsonResponse = json_decode($urlResponseJson, true);

    # parse response to get canonical URL
    foreach ($urlJsonResponse as $key => $val) {
        # get canonical URL
        if($key == "canonical_url") {
            $canonicalUrl = $val;
        }
    }

    # check for result
    if(empty($canonicalUrl)) {
        $errorMessage = "Unable to retreive URL.";
    }

} else {
    $errorMessage = "Unable to publish appLink.";
}

# encode response back to your app
if(empty($errorMessage)) {
    $response = json_encode(array("result"        => "success",
                                  "canonical_url" => $canonicalUrl));
} else {
    $response = json_encode(array("result" => "failed",
                                  "errorMessage" => $errorMessage));
}

#send response back to your app

返回您的应用,一旦确认回复良好,请将您获得的规范网址作为url参数放在下面的[FBGraphObject openGraphObjectForPostWithType:中。现在,当您在Facebook应用程序中点击您的故事时,它将直接进入您的应用程序。没有网络废话。

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

// Create an object
id<FBGraphObject> object;

// set shareDialog parameters
FBOpenGraphActionParams *params = [[FBOpenGraphActionParams alloc] init];
params.action = action;
params.actionType = @"<myApp>:<myAction>";
params.previewPropertyName = @"<key>";
object = [FBGraphObject openGraphObjectForPostWithType:@"<myApp>:<myObject>"
                                                 title:<title>
                                                 image:<urlToPic>
                                                   url:<fb.me/xyz canonical URL>
                                           description:<someDescription>];

[action setObject:object forKey:@"<key>"];

etc...

答案 1 :(得分:5)

当我在使用我的应用程序时,Sweep,在应用程序花费了一定的时间后,我放了一个付费/共享墙。我遇到了同样的问题,即尽管有这样的承诺,但AppLinks实际上却真正吸引了Facebook。基于这个问题,我构建了一个名为branch.io的服务,为我提供链接,并自动为Android / iOS插入正确的AppLinks元标记。链接实际上按预期工作,就像疯了一样。它使用客户端JS和AppLinks的组合,使它们在每个webview和本机浏览器中正确重定向

以下是在iOS上创建共享链接的高级指南:

  1. 要开始使用,您只需在dashboard.branch.io的信息中心的任一商店中配置应用的位置即可。完成所有设置后,您将获得Branch应用程序密钥。

  2. pod“Branch”或者你可以在这里克隆开源代码: https://github.com/BranchMetrics/Branch-iOS-SDK

  3. 将分支键作为字符串添加到plist文件中,键为“branch_key”

  4. 使用适当的方法

  5. 将以下代码添加到AppDelegate

    在didFinishLaunchingWithOptions中:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // your other init code
        Branch *branch = [Branch getInstance];
        [branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {     // previously initUserSessionWithCallback:withLaunchOptions:
            if (!error) {
                // params are the deep linked params associated with the link that the user clicked before showing up
                // params will be empty if no data found
    
                // here is the data from the example below if a new user clicked on Joe's link and installed the app
                NSString *name = [params objectForKey:@"user"]; // returns Joe
                NSString *profileUrl = [params objectForKey:@"profile_pic"]; // returns https://s3-us-west-1.amazonaws.com/myapp/joes_pic.jpg
                NSString *description = [params objectForKey:@"description"]; // returns Joe likes long walks on the beach...
    
                // route to a profile page in the app for Joe
                // show a customer welcome
            }
        }];
    }
    

    在用于处理URI调用的openUrl中:

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
        // pass the url to the handle deep link call
        // if handleDeepLink returns YES, and you registered a callback in initSessionAndRegisterDeepLinkHandler, the callback will be called with the data associated with the deep link
        if (![[Branch getInstance] handleDeepLink:url]) {
            // do other deep link routing for the Facebook SDK, Pinterest SDK, etc
        }
        return YES;
    }
    
    1. 最后,要创建托管链接,它非常简单。您只需要调用getShortUrl来动态创建一个。您可以在链接中放置尽可能多的键和值(在initSession回调中检索)
    2. 您可以将此代码段放在想要创建链接的任何位置:

      NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
      
      [params setObject:@"Joe" forKey:@"user"];
      [params setObject:@"url.to.picture/mypic.png" forKey:@"profile_pic"];
      [params setObject:@"Joe likes long walks on the beach..." forKey:@"description"];
      
      // Customize the display of the link
      [params setObject:@"Joe's MyApp Referral" forKey:@"$og_title"];
      [params setObject:@"url.to.picture/mypic.png" forKey:@"$og_image_url"];
      [params setObject:@"Join Joe in MyApp - it's awesome" forKey:@"$og_description"];
      
      // Customize the redirect performance
      [params setObject:@"http://myapp.com/desktop_splash" forKey:@"$desktop_url"];
      
      Branch *branch = [Branch getInstance];
      [branch getShortURLWithParams:params andCallback:^(NSString *url, NSError *error) {
          // show the link to the user or share it immediately
      }];
      

      Android在方法调用和功能上非常相似,可以在网站上找到。

答案 2 :(得分:3)

抱歉,如果我的回答不完全符合您的预期,只是为了分享我们在网站和应用上所做的事情。

例如,我知道我们必须添加更多标签才能使其与推特卡一起使用,以下是我们页面中的元属性列表:

meta property="twitter:card" content=""
meta property="twitter:title" content=""
meta property="twitter:description" content=""
meta property="twitter:image:src" content=""
meta property="twitter:app:id:iphone" content=""
meta property="twitter:app:name:iphone" content="Marmiton"
meta property="twitter:app:url:iphone" content=""
meta property="twitter:app:id:googleplay" content=""
meta property="twitter:app:name:googleplay" content=""
meta property="twitter:app:url:googleplay" content=""

和甲骨文你也有:

meta property="al:iphone:app_store_id" content=""
meta property="al:iphone:app_name" content=""
meta property="al:iphone:url" content=""
meta property="al:android:package" content=""
meta property="al:android:app_name" content=""
meta property="al:android:url" content=""

我们还定义了facebook opengraph meta,例如fb:app_id。我之所以提到这一点,是因为当您在应用中收到深层链接时,您还会在applinks链接中找到facebook app id。

从我们测试的内容:

  • facebook不会直接在iOS上打开深层链接,而Android会为您提供应用选择。它有时会在屏幕底部显示蓝色弹出窗口,有时您只需在Facebook(safari)webview中点击分享按钮时在动作表中添加一个链接(仅在首次加载时) - &gt;此链接的演示取决于如何在Facebook上分享内容。

  • twitter在iOS上添加了卡内应用程序的链接。

不知道我可以添加更多内容。

希望它有所帮助。