简体   繁体   English

将 iOS 事件传递给 Ionic/Capacitor webview

[英]pass iOS event to Ionic/Capacitor webview

I am looking for a way to pass an event to the frontend of an Ionic/Capacitor app from iOS/Swift, The end goal is to retro-fit this code so that I can process a 3rd party push notification provider.我正在寻找一种方法将事件从 iOS/Swift 传递到 Ionic/Capacitor 应用程序的前端,最终目标是改造此代码,以便我可以处理 3rd 方推送通知提供程序。 The flow is that the app loads and passes the notification data to my Capacitor plugin so that I can make use of the bridge methods (maybe I can do this from AppDelegate directly ?) and in my plugin I have an observable ready to receive the notification which it then passes to a method that executes the events as per the Capacitor documentation, however no event every gets fired and no alert pops, potentially this is because the AppDelegate and plugin loads before the webview but in that care Im not sure how to process this.流程是应用程序加载并将通知数据传递给我的 Capacitor 插件,以便我可以使用bridge方法(也许我可以直接从 AppDelegate 执行此操作?)并且在我的插件中我有一个 observable 准备好接收通知然后它传递给一个根据电容器文档执行事件的方法,但是没有任何事件被触发并且没有警报弹出,这可能是因为 AppDelegate 和插件在 webview 之前加载但在那种情况下我不知道如何处理这个。

AppDelegate.swift AppDelegate.swift

  func applicationDidBecomeActive(_ application: UIApplication) {
    let nc = NotificationCenter.default
    nc.post(name: Notification.Name("TestingEvents"), object: nil)
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was
  }

MyPlugin.swift MyPlugin.swift

    public override func load() {
        let nc = NotificationCenter.default
            nc.addObserver(self, selector: #selector(handleSignal), name: Notification.Name("TestingEvents"), object: nil)
    }

    @objc func handleSignal() {
        self.bridge.triggerWindowJSEvent(eventName: "myCustomEvent")
        self.notifyListeners("myPluginEvent", data: [:])
    }

and my app.component.ts和我的 app.component.ts

      window.addEventListener('myCustomEvent', () => {
        console.log("ATTEMPTILE PUSH")
        alert("myCustomEvent 2 ")
      });            
      Plugins.myPlugin.addListener("myPluginEvent", (info: any) => {
        console.log("myPluginEvent was fired");
        alert("myPluginEvent 2 ")
      });

What you can do to archive this (one Solution i used in a Plugin):你可以做些什么来存档这个(我在插件中使用的一个解决方案):

Your Plugin has a js File in the www Folder, which manages the Functions.您的插件在www文件夹中有一个js文件,用于管理功能。 In this File you can create Methods to create listener, remove listener, fireEvent:在此文件中,您可以创建方法来创建侦听器、删除侦听器、fireEvent:

exports._listener = {};

/**
 * Fire event with given arguments.
 *
 * @param [ String ] event The event's name.
 * @param [ Array<Object> ] The callback's arguments.
 *
 * @return [ Void ]
 */
exports.fireEvent = function (event)
{
    var args     = Array.apply(null, arguments).slice(1),
        listener = this._listener[event];

    if (!listener)
        return;

    for (var i = 0; i < listener.length; i++)
    {
        var fn    = listener[i][0],
            scope = listener[i][1];

        fn.apply(scope, args);
    }
};

/**
 * Register callback for given event.
 *
 * @param [ String ] event The event's name.
 * @param [ Function ] callback The function to be exec as callback.
 * @param [ Object ] scope The callback function's scope.
 *
 * @return [ Void ]
 */
exports.on = function (event, callback, scope)
{
    if (typeof callback !== "function")
        return;

    if (!this._listener[event])
    {
        this._listener[event] = [];
    }

    var item = [callback, scope || window];

    this._listener[event].push(item);
};

/**
 * Unregister callback for given event.
 *
 * @param [ String ] event The event's name.
 * @param [ Function ] callback The function to be exec as callback.
 *
 * @return [ Void ]
 */
exports.un = function (event, callback)
{
    var listener = this._listener[event];

    if (!listener)
        return;

    for (var i = 0; i < listener.length; i++)
    {
        var fn = listener[i][0];

        if (fn == callback)
        {
            listener.splice(i, 1);
            break;
        }
    }
};

Maybe you have to edit these a bit, to match for what you want.也许您必须对这些进行一些编辑,以匹配您想要的内容。 Then you need the Connection to your Native Code, this could be archived with calling a Methode on Plugin startup like this:然后你需要连接到你的本机代码,这可以通过在插件启动时调用 Methode 来存档,如下所示:

channel.onCordovaReady.subscribe(function () {
  cordova.exec(function(event) {
    // Callback from Native Code received. Fire to JS Listeners
    this.fireEvent(event);
  }, null, 'YourPluginName', 'init', []);
}

then you need a Function (Objective-C as i don't so Swift much) called init(), which just saves the CallbackId:那么你需要一个名为 init() 的函数(Objective-C,因为我不太喜欢 Swift),它只保存了 CallbackId:

- (void) init:(CDVInvokedUrlCommand *)command
{
    self.eventCallbackId = command.callbackId;
    return;
}

Then you can emit something to the CallbackId via:然后你可以通过以下方式向 CallbackId 发出一些东西:

CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"event"];
[self.commandDelegate sendPluginResult:result callbackId:self.eventCallbackId];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM