Search code examples
javascriptswifttvosapple-tvtvml

How should I map tvOS AppDelegate's applicationWillEnterForeground to a javascript function?


I'm following Apple's Sample project for Playing Media in a Client-Server App.

func executeRemoteMethod(_ methodName: String, completion: @escaping (Bool) -> Void) {
    appController?.evaluate(inJavaScriptContext: { (context: JSContext) in
        let appObject : JSValue = context.objectForKeyedSubscript("App")

        if appObject.hasProperty(methodName) {
            appObject.invokeMethod(methodName, withArguments: [])
        }
        }, completion: completion)
}

The method is getting called during Application lifecycle events like this:

func applicationWillEnterForeground(_ application: UIApplication) {

    executeRemoteMethod("onWillEnterForeground", completion: { (success: Bool) in
        // ...
    })
}

I'm wondering how it's working. Is this so that the native iOS codebase can communicate the lifecycle event to the Javascript code? When I put a breakpoint I see executeRemoteMethod function getting called. But I don't think it's actually doing anything. How can I map it to a js function? Do I have to create a new js file or just create a new function in my application.js file?


Solution

  • Thanks to reading this tutorial. I learned:

    In the block beginning, we first get a reference to our JavaScript “App” object. Then, we test the existence of a property with the method name that was passed to us. If it exists, we invoke the method. Although the current implementation doesn’t pass arguments to the method, we could modify it to do that as well if needed. Finally, the completion block that was passed to us is executed when the execution of the JavaScript method has been completed That similar to how the function is already written inside application.js:

    In its tutorial the application.js looks like this:

    App.onLaunch = function(options) {
        var alert = createAlert("Hello World!", "Welcome to tvOS");
        navigationDocument.pushDocument(alert);
    }
    
    App.onWillResignActive = function() {
    }
    
    App.onDidEnterBackground = function() {
    }
    
    App.onWillEnterForeground = function() {
    }
    
    App.onDidBecomeActive = function() {
    }
    
    App.onWillTerminate = function() {
    }
    
    var createAlert = function(title, description) {
        var alertString = `<?xml version="1.0" encoding="UTF-8" ?>
            <document>
              <alertTemplate>
                <title>${title}</title>
                <description>${description}</description>
              </alertTemplate>
            </document>`
    
        var parser = new DOMParser();
    
        var alertDoc = parser.parseFromString(alertString, "application/xml");
    
        return alertDoc
    }
    

    As a result I just have to add the following inside application.js then it will get called upon AppDelegates's WillEnterForeGround callback.

    App.onWillEnterForeground = function(options) {
        console.log("something")
    }