如何在iOS应用中支持通用链接并设置服务器?

39

我该如何在我的应用程序中支持通用链接,以及如何设置我的服务器以支持通用链接?

3个回答

102

支持通用链接

当你支持通用链接时,iOS 9 用户可以点击指向你网站的链接,并且无缝重定向到已安装的应用程序,而不需要经过 Safari。如果用户没有安装该应用程序,则单击指向你网站的链接将在 Safari 中打开你的网站。

以下是如何设置自己的服务器,并处理应用程序中相应的链接。


设置服务器

你需要拥有一个在线运行的服务器。为了安全地将你的 iOS 应用程序与服务器关联起来,苹果要求你提供一个名为 apple-app-site-association 的配置文件。这是一个描述域和支持路由的 JSON 文件。

apple-app-site-association 文件需要通过 https://{domain}/apple-app-site-association 访问,不带任何重定向,并使用 HTTPS 协议。

文件内容如下:

{
"applinks": {
    "apps": [ ],
    "details": [
        {
            "appID": "{app_prefix}.{app_identifier}",
            "paths": [ "/path/to/content", "/path/to/other/*", "NOT /path/to/exclude" ]
        },
        {
            "appID": "TeamID.BundleID2",
            "paths": [ "*" ]
        }
    ]
}
}

注意 - 不要将.json附加到apple-app-site-association文件名中。

键如下:
apps: 其值应为一个空数组,并且必须存在。这是苹果公司的要求。
details: 是一个字典数组,每个 iOS 应用程序都支持网站的一个字典,包含有关应用程序、团队和捆绑 ID 的信息。

有三种定义路径的方式:
静态: 支持的整个路径已硬编码以标识特定链接,例如 /static/terms
通配符: 可使用 * 匹配动态路径,例如 /books/* 可匹配到任何作者页面的路径组合,? 在特定路径组件内使用,例如 books/1? 可用于匹配以 1 开头的任何书籍的 ID。
排除: 在路径前面添加 NOT 可以将该路径从匹配中排除。

在数组中提及路径的顺序很重要。较早索引具有更高优先级。一旦路径匹配成功,则停止评估,忽略其他路径。每个路径区分大小写。

支持多个域名

每个应用程序支持的域名都需要提供自己的 apple-app-site-association 文件。如果每个域名提供的内容不同,则文件的内容也将更改以支持各自的路径。否则,可以使用相同的文件,但需要在每个支持的域中都能访问该文件。

签署 App-Site-Association 文件

注意: 如果您的服务器使用HTTPS提供内容,则可以跳过本部分并转到应用程序设置指南。

如果您的应用程序针对 iOS 9 并且您的服务器使用HTTPS提供内容,则无需签署该文件。否则(例如在 iOS 8 上支持 Handoff 时),必须使用来自认可证书颁发机构的SSL证书进行签署。

注意: 这不是 Apple 提供的用于提交应用程序到 App Store 的证书。它应由第三方提供,并建议使用您用于HTTPS服务器的相同证书(尽管这不是必需的)。

要对该文件进行签署,请先创建并保存一个简单的 .txt 版本文件。然后,在终端中运行以下命令:

cat <unsigned_file>.txt | openssl smime -sign -inkey example.com.key -signer example.com.pem -certfile intermediate.pem -noattr -nodetach -outform DER > apple-app-site-association

这将在当前目录中输出已签名的文件。example.com.keyexample.com.pemintermediate.pem是你的证书颁发机构提供给你的文件。

注意:如果文件未经签名,则其应具有Content-Type为application/json。否则,它应该是application/pkcs7-mime。

使用苹果App搜索验证工具验证您的服务器
测试用于iOS 9搜索API的网页。输入URL,Applebot将爬行您的网页,并显示如何优化以获得最佳结果。 https://search.developer.apple.com/appsearch-validation-tool/

网站代码

网站代码可以在gh-pages分支上找到 https://github.com/vineetchoudhary/iOS-Universal-Links/tree/gh-pages


设置iOS应用程序

应用程序将针对iOS 9,并将使用Xcode 7.2与Objective-C。

启用通用链接

在应用程序端进行设置需要两件事:
1.配置应用程序的权限,并启用通用链接。
2.处理您的AppDelegate中的传入链接。

1.配置应用程序的权限,并启用通用链接。
配置应用程序权限的第一步是为您的App ID启用它。在Apple开发人员成员中心完成此操作。单击证书,标识符和资料文件,然后选择标识符。选择您的App ID(如果需要,请先创建),单击编辑并启用相关域权限。

接下来,通过单击相应的App ID获取App ID前缀和后缀。

App ID前缀和后缀应与苹果应用程序网站关联文件中的前缀和后缀匹配。

接下来,在Xcode中选择您的应用程序目标,单击功能,将相关域切换为打开状态。为应用程序支持的每个域添加一个以applinks:为前缀的条目。

例如:applinks:vineetchoudhary.github.io

以下是示例应用程序的外观:

注意:确保您选择了与成员中心注册的应用程序ID相同的团队和输入了相同的Bundle ID。还要确保通过选择文件并在“文件检查器”中,确保目标已选中来包含Xcode的授权文件。

在AppDelegate中处理传入链接

[UIApplicationDelegate application: continueUserActivity: restorationHandler:]方法在AppDelegate.m中处理传入链接。您可以解析此URL以确定应用程序中的正确操作。

例如,在示例应用程序中:

Objective-C

-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
    if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
        NSURL *url = userActivity.webpageURL;
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        UINavigationController *navigationController = (UINavigationController *)_window.rootViewController;
        if ([url.pathComponents containsObject:@"home"]) {
            [navigationController pushViewController:[storyBoard instantiateViewControllerWithIdentifier:@"HomeScreenId"] animated:YES];
        }else if ([url.pathComponents containsObject:@"about"]){
            [navigationController pushViewController:[storyBoard instantiateViewControllerWithIdentifier:@"AboutScreenId"] animated:YES];
        }
    }
    return YES;
}  

Swift:

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
      if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
          let url = userActivity.webpageURL!
          //handle url
      }
      return true
  }

iOS应用程序代码

该应用程序代码可以在https://github.com/vineetchoudhary/iOS-Universal-Links/的主分支中找到。

注意:

  1. 通常情况下,在Safari中点击任何支持的链接,或在UIWebView/WKWebView实例中,都应该打开应用程序。
  2. 对于iOS 9.2及以下版本,这仅适用于设备。 iOS 9.3(撰写本文时仍处于测试阶段)也支持模拟器。
  3. iOS记住用户在打开通用链接时的选择。如果他们点击顶部右侧的面包屑以在Safari中打开链接,则所有后续的点击都将把他们带到Safari而不是应用程序。他们可以通过在网站上选择"在应用程序中打开"横幅来切换回默认打开应用程序。

完成。 这就是通用链接的全部内容。


参考资料

  1. 在您的iOS应用中支持通用链接

很棒的教程@VineetChoudhary,我有一个问题。例如,如果我从Whatsapp打开一个URL会发生什么?通用链接是否应该起作用? 谢谢! - baquiax
感谢@VineetChoudhary提供这个很棒的答案。 我还有一个问题,我有一个通过HTTPS访问的网站,使用自签名证书,并在根目录下放置了app-site-association文件。 但仍然无法正常工作。所以我在考虑是不是自签名证书导致了问题。你觉得呢? - Ali
@Ali 我从未尝试过使用自签名证书的通用链接。你可以尝试使用 Github Pages https://pages.github.com/ 或 Firebase Hosting https://firebase.google.com/docs/hosting/。 - Vineet Choudhary
非常棒的教程,谢谢。我之前漏掉了域名前面的 applinks: 关键字。 - abhimuralidharan
Swift 3 AppDelegate 方法签名 - func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool - Aviv Ben Shabat
显示剩余19条评论

4

以下是基于Vineet Choudhary的答案,用Swift 3+处理通用链接的代码:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let url = userActivity.webpageURL {
        //handle URL
    }

    return true
}

在我的情况下,当我从浏览器中输入URL时无法工作,但当我从Messenger或WhatsApp中点击URL时可以正常工作。 - Pramod Tapaniya

2
如果你按照Vineet的帖子完成了一切仍然不起作用,尝试使用分发配置文件。我按照上面的帖子做了一切,但是必须发布一个分发配置文件才能使其正常工作。
使用开发配置文件,应用程序成功下载了AASA文件,但是我按下链接时它从未打开我的应用程序。
希望这有所帮助。

这可能是另一个有用的提示。您是否使用手动签名,而不是在“常规”选项卡中勾选“自动管理签名”,让Xcode为您进行签名设置? - CouchDeveloper
我们发现配置文件生成有误。我们在配置文件ID中添加了TeamID,导致出现了双重前缀。删除后,无论是开发还是分发配置文件,都可以解决错误。您可以尝试生成一个独特的、专门用于测试的配置文件。然后确保Xcode中的Bundle ID与配置文件中的相同,并手动签名。 - mystoev
@mystoev 这个是在开发版本上工作还是必须上传到测试版? - Francisco García
谢谢。如果这个代码行起作用:"paths": [""],但是带有NOT的变体不行,例如 "paths": ["NOT /forgotPassword", ""] 或者 "paths": ["*", "NOT /forgotPassword"],那么这个分发/开发档案就不是问题了,对吗?那么问题就在于其他方面,对吗? - Dalibor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接