获取iOS和Android的app下载渠道和相关参数的方式

时间:2024-03-16 11:31:50

1. iOS

1.1 Deep Link

  • 作用:Deep Link 允许应用响应特定的链接,直接打开应用内的某个特定内容或页面。这意味着用户可以通过点击一个链接,直接跳转到应用内部的某个具体位置,而不是每次都从应用的首页开始。
  • 配置:开发者需要在应用内配置URL schemes,并处理传入的URL来决定打开应用时显示哪个界面。
  • 限制:Deep Link 主要限制在应用已安装的情况下有效。如果应用未安装,用户点击链接会发生什么,完全取决于开发者的处理逻辑(例如,可以跳转到App Store)。

1.2 Universal Link

  • 作用:Universal Link 是一种更先进的链接方式,不仅支持深链接到应用内部的特定内容,还能在应用未安装时打开网页链接。这提供了更为流畅的用户体验,因为它可以智能地决定是打开网页还是应用内容。
  • 配置:开发者需要在自己的服务器上配置一个文件(apple-app-site-association 或 AASA 文件),并在应用的Info.plist中声明对应的域名。这样,iOS系统可以验证链接是否应该打开应用,并自动处理。
  • 优势:Universal Link 支持的场景更广泛,提供了更好的用户体验。如果应用已安装,它可以直接打开应用内的相关内容;如果未安装,链接会打开网页版内容。此外,Universal Link 还支持搜索引擎索引,有利于提高内容的可发现性。

总的来说,Universal Link 是 Apple 推荐的链接方案,它在用户体验和技术实现上都比传统的 Deep Link 更加先进和完善。但在某些情况下,根据应用的需求和特定场景,开发者可能仍然需要使用 Deep Link。

1.3 代码获取外部链接带过来的参数

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // 确认是不是由 Universal Link 触发的
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL {
        // 解析 URL 来获取需要的参数
        handleUniversalLink(url: url)
    }
    return true
}

func handleUniversalLink(url: URL) {
    // 这里是解析 URL 和查询参数的逻辑
    // 例如,你可以使用 URLComponents 类来解析 URL
    let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
    if let queryItems = components?.queryItems {
        for item in queryItems {
            print("\(item.name) = \(item.value ?? "")")
            // 根据参数名称处理相应的逻辑
        }
    }
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    // 确认是不是由 Universal Link 触发的
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *url = userActivity.webpageURL;
        // 解析 URL 来获取需要的参数
        [self handleUniversalLink:url];
    }
    return YES;
}

- (void)handleUniversalLink:(NSURL *)url {
    // 解析 URL 和查询参数的逻辑
    NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
    NSArray *queryItems = components.queryItems;
    for (NSURLQueryItem *item in queryItems) {
        NSLog(@"%@ = %@", item.name, item.value);
        // 根据参数名称处理相应的逻辑
    }
}



2.Android

2.1 Intent Filters

  • 作用:Intent Filters 类似于 iOS 中的 Deep Link。它们允许 Android 应用响应外部的意图(Intent),如从网页中打开应用的特定页面。通过在应用的 manifest 文件中声明 Intent Filters,开发者可以指定应用可以处理的 URL。
  • 配置:开发者需要在 AndroidManifest.xml 文件中为相应的 Activity 配置 Intent Filter,包括指定要匹配的动作(Action)、数据(Data)和类别(Category)。
  • 限制:就像 Deep Link,如果应用未安装,点击链接将不会有任何作用,除非开发者在网页上提供了额外的逻辑来引导用户下载应用。

2.2 App Links

  • 作用:App Links 是 Android 对 Universal Links 的答案。它允许应用在用户设备上更为无缝地处理网页链接,实现在应用和网页之间的*跳转。当点击一个链接时,系统会智能地判断是打开浏览器还是直接打开应用内的对应内容,即使应用未安装,也能优雅地回退到网页视图。
  • 配置:为了使用 App Links,开发者需要在应用的 AndroidManifest.xml 中添加相应的 Intent Filter,并且必须在服务器上托管一个特定的 JSON 文件(assetlinks.json),用于验证应用是否有权处理网站的链接。
  • 优势:App Links 提供了更加直接和安全的方式来处理深度链接,包括在应用未安装时的情况,从而提供更好的用户体验。它也支持通过 HTTPS 进行验证,确保了链接的安全性。

总结来说,Android 的 App Links 和 Intent Filters 分别与 iOS 的 Universal Link 和 Deep Link 相当。App Links 提供了一个更为先进和流畅的用户体验,使得在应用和网页之间的跳转更加无缝,同时也增加了链接的安全性和可靠性。

2.3 代码获取外部链接带过来的参数

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 获取意图
    Intent intent = getIntent();
    String action = intent.getAction();
    Uri data = intent.getData();

    // 检查是否是由深度链接激活的
    if (Intent.ACTION_VIEW.equals(action) && data != null) {
        String channelId = data.getQueryParameter("channelId");
        // 使用渠道ID做相应的处理
    }
}


3.服务器根目录下的文件

3.1 iOS的apple-app-site-association文件

官网解释

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


    "appclips": {
        "apps": ["ABCED12345.com.example.MyApp.Clip"]
    }
}

3.2 Android的assetlinks.json文件

官方文档,上传到服务器的路径是https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.app",
    "sha256_cert_fingerprints":
    ["YOUR_APP_CERTIFICATE_SHA256_FINGERPRINT"]
  }
}]
  • relation: 定义了与目标的关系类型。对于深度链接,通常使用 “delegate_permission/common.handle_all_urls” 来表示应用有权限处理所有相关的 URL。
  • target: 描述了目标应用的详情。
  • namespace: 对于 Android 应用,这里总是 “android_app”。
  • package_name: 应用的包名,比如 “com.example.app”。
  • sha256_cert_fingerprints: 应用签名证书的 SHA-256 指纹数组。你需要将 “YOUR_APP_CERTIFICATE_SHA256_FINGERPRINT” 替换为你的应用签名证书的实际 SHA-256 指纹。
    确保替换 package_name 和 sha256_cert_fingerprints 中的值为你的实际应用信息。你可以使用如下命令来获取应用签名证书的 SHA-256 指纹:
keytool -list -v -keystore your_keystore_path -alias your_alias_name