如何设置关联域/通用链接

问题描述

我试图在访问 www.example.com/success 时将用户重定向到已安装的应用程序,并在访问主页时显示横幅 www.example.com .

就我目前的植入而言,网址不会重定向和打开应用程序,网站也不会显示横幅。

我正在关注此处找到的文档https://developer.apple.com/documentation/safariservices/supporting_associated_domains

我的网站是一个简单的 create-react-app,主页由 Firebase 托管。

我做了以下事情:

  1. 将关联域添加到签名和功能 - applinks:website.com/success
  2. apple-app-site-association 文件添加到 /public/
  3. 修改 firebase.json 文件
  4. 链接到 index.html 中的文件

我用来验证的内容

https://branch.io/resources/aasa-validator/

https://search.developer.apple.com/appsearch-validation-tool

通过添加 www.example.com/success 链接到笔记和打开进行测试,它总是在 safari 中打开。我也试过重新安装应用程序并重新启动手机。

Apple API 验证

我已将带有关联域的新应用版本上传到商店

enter image description here

Branch.io

{
    "applinks": {
        "apps": [],"details": []
    }
}

访问www.example.com/apple-app-site-association

{ "activitycontinuation": { "apps": [ "team.com.example.com" ] },"applinks": { "apps": [],"details": [ { "appID": "team.com.example.com","paths": [ "/","/","/success","/success/",] },"webcredentials": { "应用”: [ “team.com.example.com”] } }

apple-app-site-association

{
  "activitycontinuation": {
      "apps": [
        "team.com.example.com"
      ]
  },"applinks": {
      "apps": [],"details": [
            {
                "appID": "team.com.example.com","paths": [
                  "/","/*","/success/*",]
            },]
  },"webcredentials": {
      "apps": [
        "team.com.example.com"
      ]
  }
}

Index.html

<link rel="apple-app-site-association file" href="%PUBLIC_URL%/apple-app-site-association">
<link rel="apple-app-site-association file" href="/apple-app-site-association">
<Meta name="App" content="app-id=XXX,app-argument=https://apps.apple.com/US/app/APP/idXXX,affiliate- data=optionalAffiliateData">

Firebase.json

{
  "hosting": {
    "public": "public","headers": [
      {
        "source": "/apple-app-site-association","headers": [
          {
            "key": "Content-Type","value": "application/json"
          }
        ]
      }
    ],"appAssociation": "NONE"
  }
}

设备控制台

安装应用程序时,我会在 Xcode 中监控设备控制台,查看 swdc 进程日志以查找与关联域或请求相关的任何内容。这是我找到的一些;

获取企业管理的关联域数据时出错。如果这 设备不是企业管理的,这是正常的:错误 Domain=SWCErrorDomain Code=1701 "获取关联域数据失败 来自 ManagedConfiguration 框架。” UserInfo={NSDebugDescription=无法从 ManagedConfiguration framework.,Line=298,Function=}

条目 { s = applinks,a =,d = au....ub....com,ua = 未指定, sa = Approved } 需要更新其 JSON,因为应用程序 PI 已更改

https://developer.apple.com/library/archive/qa/qa1916/_index.html

解决方法

apple-app-site-association 中需要有一个 appID:

{
  "applinks": {
    "apps": [],"details": [
    {
      "appID": "XXXXXXXXXX.com.example.UniveralLinks","paths": ["*"]
    }
    ]
  }
}

applinks 标签决定了哪些应用与网站相关联。将 apps 值保留为空数组。在 details 标签内是一组用于链接 appID 和 URL 路径的字典。为简单起见,您使用 * 通配符将本网站的所有链接与 UniversalLinks 应用程序相关联。您可以将路径值限制为特定文件夹或文件名。 appID 由您的团队 ID 和应用程序的捆绑 ID 组成,但您需要使用自己帐户的标识符。 在您创建 Apple 开发者帐户时,Apple 为您分配了一个团队 ID。您可以在 Apple 开发人员中心找到它。登录网站,点击“会员”,然后在“会员信息”部分查找团队 ID。

现在你有了 apple-app-site-association,它必须上传到网络服务器。 您必须对网站具有“写入权限”才能执行此操作。确保您正确设置了 apple-app-site-association 文件(在根目录或网络服务器上的 .well-known/ 中,并且没有重定向)。

您还必须为通用链接到 iOS 应用添加适当的权利。 如果您使用的是 Xcode:

  1. 选择项目。
  2. 选择目标。
  3. 选择“功能”选项卡。
  4. 滚动查看并开启关联域。

然后你可以添加例如applinks:www.mywebsite.in 在“功能 -> 关联域”下。

或者在您的权利文件中,您可以添加如下内容:

<key>com.apple.developer.associated-domains</key>
<array>   
    ...
    <string>applinks:www.mywebsite.in</string>
    ...
</array>

处理通用链接: 现在应用程序和网站正式相互了解,应用程序需要的只是在调用链接时处理链接的代码。

func application(
  _ application: UIApplication,continue userActivity: NSUserActivity,restorationHandler: @escaping ([UIUserActivityRestoring]?
) -> Void) -> Bool {
  
  // 1
  guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,let url = userActivity.webpageURL,let components = URLComponents(url: url,resolvingAgainstBaseURL: true) else {
      return false
  }
  
  // 2 // dig out component for deepLinking reference. 
  if let component = ItemHandler.sharedInstance.items
    .filter({ $0.path == components.path}).first {
    //handle navigation to page indicated by component
    return true
  }
  
  // 3
  if let webpageUrl = URL(string: "http://universal-links-final.example.com") {
    application.open(webpageUrl)
    return false
  }
  
  return false
}

每当用户点击与应用程序相关的通用链接时,iOS 都会调用此方法。以下是每个步骤的作用: 首先,您验证传入的 userActivity 是否具有预期的特征。最终,您希望获得活动的路径组件。否则,您将返回 false 以表明该应用程序无法处理该活动。 使用该路径,您可以查找与其匹配的已知视图控制器。如果找到,则为它显示视图控制器并返回 true。 如果找不到与路径匹配的视图控制器,则指示应用程序打开 URL,该 URL 将改用默认系统应用程序 — 很可能是 Safari。您还可以在此处返回 false 以表明该应用无法处理此用户活动。

,

首先在您的设备日志和您的 JSON 格式中,您似乎应该遵循此处显示的示例:https://developer.apple.com/documentation/safariservices/supporting_associated_domains

在您的日志中,它可能会显示来自其他应用程序的日志,这些应用程序也具有过时的 API 格式。不过,这应该不是什么大问题。

{
  "applinks": {
      "details": [
           {
             "appIDs": [ "ABCDE12345.com.example.app","ABCDE12345.com.example.app2" ],"components": [
               {
                  "#": "no_universal_links","exclude": true,"comment": "Matches any URL whose fragment equals no_universal_links and instructs the system not to open it as a universal link"
               },{
                  "/": "/buy/*","comment": "Matches any URL whose path starts with /buy/"
               },{
                  "/": "/help/website/*","comment": "Matches any URL whose path starts with /help/website/ and instructs the system not to open it as a universal link"
               },{
                  "/": "/help/*","?": { "articleNumber": "????" },"comment": "Matches any URL whose path starts with /help/ and which has a query item with name 'articleNumber' and a value of exactly 4 characters"
               }
             ]
           }
       ]
   },"webcredentials": {
      "apps": [ "ABCDE12345.com.example.app" ]
   },"appclips": {
        "apps": ["ABCED12345.com.example.MyApp.Clip"]
    }
}

第二步按照 Apple 的故障排除步骤和您的问题,我猜您的问题可能是第 7 步

  • 您的应用因以下任一情况返回 false UIApplicationDelegate 协议方法: 应用程序(:continueUserActivity:restorationHandler:),应用程序(:willFinishLaunchingWithOptions:),应用程序(_:didFINishLaunchingWithOptions:).

    这可能发生,如果你 解析传递给这些方法的 URL,并且您实现了 确定您的应用无法使用此网址的逻辑。

您尚未发布您如何处理 URL。您需要按照其他答案中的建议实施 UIUserActivityRestoring 方法才能使其工作。这是一个 SwiftUI 版本

ContentView()   
    .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
        
        print("Continue activity \(userActivity)")
        guard let url = userActivity.webpageURL else {
            return
        }
        
        print("User wants to open URL: \(url)")
        // TODO same handling as done in onOpenURL()

    }

同时添加

.onOpenURL { url in
    print("URL OPENED")
    print(url) // parse the url to get someAction to determine what the app needs do
    if url.relativeString == "example://success" {

    }
}

https://developer.apple.com/library/archive/qa/qa1916/_index.html