2017-09-12 60 views
4

我在JSContext內執行JavaScript SDK,但無法從SDK的任何異步函數中獲取值。我可以從JSContext中獲得JavaScript承諾,但我無法弄清楚如何解決它。我已經嘗試了很多方法從承諾中獲得價值,但每一個都失敗了。從JSContext中的JS Promise /異步函數獲取值

如果我嘗試像下面我得到[object Promise]回:

return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300,() => resolve([1, 2, 3])) })")! 

如果我連鎖then直接到JS我得到[object Promise]還是:

return self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300,() => resolve([1, 2, 3])) }).then(val => val.json())") 

如果我嘗試調用方法從斯威夫特,我仍然得到[object Promise]

let jsPromise = self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300,() => resolve([1, 2, 3])) })") 
let promiseResult = jsPromise?.invokeMethod("then", withArguments: ["val => { return val.json() }"]) 
return promiseResult! 

如果我宣佈承諾之外的JS變量,則該值從斯威夫特調用then調用傳遞給它,我得到的設置它的原始值(如預期,但值得一試):

self.jsContext.evaluateScript("let tempVar = 'Nothing has happened yet!'") 
let jsPromise = self.jsContext.evaluateScript("new Promise(resolve => { setTimeout(300,() => resolve([1, 2, 3])) })") 
let promiseResult = jsPromise?.invokeMethod("then", withArguments: ["val => { tempVar = val }"]) 
let tempVar = self.jsContext.evaluateScript("tempVar") 
return tempVar! 

如果我嘗試使用頂級await和解決承諾給一個變量,然後將變量出JSContext的,IU得到EXC_BAD_INSTRUCTION錯誤:事先

let jsPromise = self.jsContext.evaluateScript("let someVar = await new Promise(resolve => { setTimeout(300,() => resolve([1, 2, 3])) })") 
return self.jsContext.evaluateScript("someVar")! 

謝謝,對不起,如果我錯過了一些東西,對Swift來說還很新。

+0

如果您使用斷點進行調試,您在對象中看到了什麼? –

回答

2

在嘲笑JSContext中的Promise工作流程時存在一些問題。 JSContext中沒有setTimout,setInterval等函數。

但是,您可以通過將塊傳入JSContext來從Javascript調用Swift代碼。這是一段代碼片斷,它顯示瞭如何找出JSContext中的錯誤。

var logValue = "" { 
    didSet { 
     print(logValue) 
    } 
} 
//block we can pass to JSContext as JS function 
let showLogScript: @convention(block) (String) -> Void = { value in 
    logValue = value 
} 
let jsContext = JSContext() 

//set exceptionHandler block 
jsContext?.exceptionHandler = { 
    (ctx: JSContext!, value: JSValue!) in 
    print(value) 
} 
//make showLog function available to JSContext 
jsContext?.setObject(unsafeBitCast(showLogScript, to: AnyObject.self), forKeyedSubscript: "showLog" as (NSCopying & NSObjectProtocol)) 

jsContext!.evaluateScript("showLog('this is my first name')") //this works 
jsContext!.evaluateScript("showLog(setTimeout.name)") //it has issue