簡體   English   中英

在tvOS應用中從Swift調用JS函數時,“ TypeError:undefined不是對象”

[英]“TypeError: undefined is not an object” when calling JS function from Swift in tvOS app

我在陷入困境的tvOS應用中從Swift調用JS函數時遇到錯誤。

我已經設置了可以正常從JS調用Swift的函數,但是當嘗試從Swift調用JS函數時,我在Safari調試器中收到以下錯誤:

TypeError: undefined is not an object
(anonymous function)
JSValueToObject
-[JSValue callWithArguments:]
_TFFC13tvOSShortGame11AppDelegate17callPlayVideoInJSFS0_FSST_U_FCSo9JSContextT_
_TTRXFo_oCSo9JSContext_dT__XFdCb_dS__dT__
-[IKAppContext _doEvaluate:]
-[IKAppContext _evaluate:]
__41-[IKAppContext evaluate:completionBlock:]_block_invoke
-[IKAppContext _sourcePerform]
IKRunLoopSourcePerformCallBack
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
__CFRunLoopDoSources0
__CFRunLoopRun
CFRunLoopRunSpecific
CFRunLoopRun
-[IKAppContext _jsThreadMain]
__NSThread__start__
_pthread_body
_pthread_body
thread_start

相關的快速代碼如下:

//From JS to Swift
//call this method once after setting up your appController.
func createGetVimeoURL(){

    //allows us to access the javascript context
    appController?.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in

        //this is the block that will be called when javascript calls getVimeoURL(str)
        let getVimeoURL : @convention(block) (String) -> Void = {
            (videoName : String) -> Void in

            //5. return the vimeo url to the JS code for the passed in videoName
            self.getTempVimeoURL(videoName)
        }

        //this creates a function in the javascript context called "getVimeoURL".
        //calling getVimeoURL(str) in javascript will call the block we created above.
        evaluation.setObject(unsafeBitCast(getVimeoURL, AnyObject.self), forKeyedSubscript: "getVimeoURL")
        }, completion: {(Bool) -> Void in
            //evaluation block finished running

    })
}
//From Swift to JS
//when callPlayVideoInJS() is called, playVideo(url) will be called in JavaScript.
func callPlayVideoInJS(url : String){

    //allows us to access the javascript context
    appController!.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in

        //get a handle on the "playVideo" method that you've implemented in JavaScript
        let playVideo = evaluation.objectForKeyedSubscript("playVideo")

        //Call your JavaScript method with an array of arguments
        playVideo.callWithArguments([url])

        }, completion: {(Bool) -> Void in
            //evaluation block finished running
    })
}

//4. getTempVimeoURL from videoName
func getTempVimeoURL (videoName : String) -> String {
        return  "http://techslides.com/demos/sample-videos/small.mp4"      
}

以及應該由swift(我手動創建)調用的javascript函數:

playVideo: function (url) {
  if(url) {
    //2
    var player = new Player();
    var playlist = new Playlist();
    var mediaItem = new MediaItem("video", url);

    player.playlist = playlist;
    player.playlist.push(mediaItem);
    player.present();
  }
}

當我在appController didFinishLaunchingWithOptions中調用createGetVimeoURL時,會創建getVimeoURL javascript函數。

但是我無法弄清楚為什么我在調用callPlayVideoInJS時收到javascript錯誤,但這可能很簡單!

任何幫助表示贊賞。

看來您沒有使用objectForKeyedSubscript訪問適當的JS方法

更改

let playVideo = evaluation.objectForKeyedSubscript("vimeoVideoURL")

let playVideo = evaluation.objectForKeyedSubscript("playVideo")

[更新]您還需要確保可以從適當的上下文和范圍訪問playVideo方法。 嘗試將playVideo方法放入application.js中

var playVideo = function (url) {
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM