【问题标题】:Parse iOS Universal Links with Nativescript Angular?使用 Nativescript Angular 解析 iOS 通用链接?
【发布时间】:2019-09-23 12:33:15
【问题描述】:

按照苹果文档和 Branch 的文档here,我在我的 Nativescript Angular (iOS) 应用程序中设置了一个有效的通用链接。但是,应用打开时如何解析链接?

例如,当有人通过链接打开应用程序时,我想让我的应用程序读取链接,以便它可以转到应用程序的正确页面。

this answer 中有一些有用的代码,但我不断收到错误。这可能是因为代码是用 vanilla JS 编写的,我没有正确地将它翻译成 Angular。 “_extends”和“routeUrL”的使用都会给我带来错误。

如果没有更多代码,Nativescript url-handler 插件似乎无法工作。

所以,在设置了通用链接,并安装了 nativescript url-handler 插件之后,我在 app.module.ts 中输入了以下内容:

const Application = require("tns-core-modules/application");

import { handleOpenURL, AppURL } from 'nativescript-urlhandler';
declare var NSUserActivityTypeBrowsingWeb

if (Application.ios) {   
  const MyDelegate = (function (_super) {

   _extends(MyDelegate, _super);
    function MyDelegate() {
      _super.apply(this, arguments);
    }
    MyDelegate.prototype.applicationContinueUserActivityRestorationHandler = function (application, userActivity) {
      if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
        this.routeUrl(userActivity.webpageURL);
      }
      return true;
    };
    MyDelegate.ObjCProtocols = [UIApplicationDelegate];
    return MyDelegate;
  })(UIResponder);
  Application.ios.delegate = MyDelegate;
}

...
export class AppModule {

ngOnInit(){
        handleOpenURL((appURL: AppURL) => {
            console.log('Got the following appURL = ' + appURL);
        });
    } 
}

问题似乎主要在于“_extends”和“_super.apply”。例如,我收到此错误:

'NativeScript encountered a fatal error: TypeError: undefined is not an object (evaluating '_extends')

编辑:注意nativescript-urlhandler 插件是no longer being updated. 有谁知道如何用Nativescript 解析通用链接?

【问题讨论】:

  • 第一个插件是在 3 个月前最近更新的,当我上次检查时它曾经支持查询参数。您所指的 SO 线程至少有一年的历史。按照插件文档进行操作,如果遇到任何问题,请发布完整的错误日志。
  • 我确实遵循了插件文档但没有成功。其他人也有类似的问题:github.com/hypery2k/nativescript-urlhandler/issues/88
  • 请分享可以重现问题的示例项目。
  • 查看编辑中的代码以获取更多详细信息。请注意,该插件专门针对深层链接。该文档未涉及通用链接,并且不清楚该插件是否完全适用于通用链接。说“只看插件文档”不是一个合适的答案。如果您的反对意见只是 bc “插件已更新,但线程较旧”,请删除。 SO线程仍然相关。昨天刚刚更新。
  • 我自己没有机会测试通用链接,但插件已经实现了。所以如果你有一个示例项目,也许我可以看看。

标签: nativescript


【解决方案1】:

我想出了一个方法来让它工作:

大体思路是使用iOS App Delegate方法:applicationContinueUserActivityRestorationHandler。

应用委托的 Nativescript 文档中的语法对我不起作用。您可以查看该文档here

这似乎有效:

--一旦您设置了通用链接,遵循here 之类的文档,现在您希望您的应用程序读取(“处理”)被点击以打开应用程序的链接的详细信息:

编辑:此代码示例将所有内容放在 app.module.ts 中的一个位置。但是,大多数情况下,最好将内容移出 app.module 并放入单独的服务中。在讨论here 中有执行此操作的示例代码。 所以下面有工作代码,但请记住,最好将此代码放在单独的服务中。

app.module.ts

    declare var UIResponder, UIApplicationDelegate
    if (app.ios) {
        app.ios.delegate = UIResponder.extend({
            applicationContinueUserActivityRestorationHandler: function(application, userActivity) {
                if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
                    let tappedUniversalLink = userActivity.webpageURL
                    console.log('the universal link url was = ' + tappedUniversalLink)
                } 
                return true;
            }
        },
        {
           name: "CustomAppDelegate",
            protocols: [UIApplicationDelegate]
        });
   }

注意:要让 NSUserActivity/Application Delegate 的内容与 typescript 一起使用,我还需要下载 tns-platforms-declarations 插件,并配置应用程序。所以:

$ npm i tns-platforms-declarations

references.d.ts

/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />

上面的代码使我能够在链接打开应用程序时阅读被点击的通用链接的详细信息。

从那里,您可以确定要如何处理这些信息。例如,如果您想根据通用链接的详细信息导航到应用的特定页面,那么我发现这是可行的:

app.module.ts

    import { ios, resumeEvent, on as applicationOn, run as applicationRun, ApplicationEventData } from "tns-core-modules/application";

    import { Router } from "@angular/router";

    let univeralLinkUrl = ''

    let hasLinkBeenTapped = false

    if (app.ios) {
       //code from above, to get value of the universal link
        applicationContinueUserActivityRestorationHandler: function(application, userActivity) {
                if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
                   hasLinkBeenTapped = true  
                   universalLinkUrl =  userActivity.webpageURL
                } 
                return true;
        },

            {
                name: "CustomAppDelegate",
                protocols: [UIApplicationDelegate]
            });

    }

    @ngModule({...})

    export class AppModule {
       constructor(private router: Router) {

            applicationOn(resumeEvent, (args) => {
               if (hasLinkBeenTapped === true){
                   hasLinkBeenTapped = false  //set back to false bc if you don't app will save setting of true, and always assume from here out that the universal link has been tapped whenever the app opens
                   let pageToOpen = //parse universalLinkUrl to get the details of the page you want to go to
                   this.router.navigate(["pageToOpen"])
                } else {
                    universalLinkUrl = '' //set back to blank
                    console.log('app is resuming, but universal Link has not been tapped') 
                }
            })
        }
    }

【讨论】:

    【解决方案2】:

    您可以使用nativescript-plugin-universal-links 插件来做到这一点。 它支持处理现有的应用程序委托,因此如果您确实有另一个实现应用程序委托的插件,它们都可以工作。

    这是文档中的用法示例:

    import { Component, OnInit } from "@angular/core";
    import { registerUniversalLinkCallback } from "nativescript-plugin-universal-links";
    
    @Component({
      selector: "my-app",
      template: "<page-router-outlet></page-router-outlet>"
    })
    export class AppComponent {
      constructor() {}
    
      ngOnInit() {
        registerUniversalLinkCallback(ul => {
          // use the router to navigate to the screen
        });
      }
    }
    

    并且回调将收到一个看起来像这样的ul(通用链接)参数

    {
      "href": "https://www.example.com/blog?title=welcome",
      "origin": "https://www.example.com",
      "pathname": "/blog",
      "query": {
         "title": "welcome"
      }
    }
    

    免责声明:我是插件的作者。

    【讨论】:

      猜你喜欢
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 2010-09-12
      • 1970-01-01
      相关资源
      最近更新 更多