Swift中如何获取JSContext evaluateScript执行结果的类型?
解决JSContext执行结果的JS类型判断问题
你遇到的核心问题是混淆了Swift原生类型和JSContext中JavaScript值的类型——evaluateScript返回的是JSValue实例,它是JS值在Swift中的包装器,所以直接用Swift的类型转换或type(of:)肯定得不到你想要的JS层面的类型。
下面给你两种可靠的解决方案,完全不需要解析输入字符串,能准确处理像array.length返回数字这类复杂场景:
方法1:利用JSValue的内置类型判断属性
JSValue本身提供了一系列布尔属性,直接对应JS的基本类型判断,使用起来非常直观:
let context = JSContext()! let userInput = "[1,2,3].length" // 示例用户输入 guard let ans = context.evaluateScript(userInput) else { print("执行失败或结果为空") return } // 逐一判断JS类型 if ans.isNumber { print("执行结果的JS类型是:Number") } else if ans.isString { print("执行结果的JS类型是:String") } else if ans.isArray { print("执行结果的JS类型是:Array") } else if ans.isBoolean { print("执行结果的JS类型是:Boolean") } else if ans.isObject { print("执行结果的JS类型是:Object") } else if ans.isUndefined { print("执行结果的JS类型是:Undefined") } else if ans.isNull { print("执行结果的JS类型是:Null") }
这种方法的优点是无需额外调用JS代码,纯Swift层面就能完成判断,性能也更好。
方法2:调用JavaScript的typeof运算符
如果需要更灵活的类型字符串(比如直接拿到"number""string"这类标准JS类型名),可以在JS环境中直接调用typeof来判断执行结果的类型:
let context = JSContext()! let userInput = "[1,2,3].length" guard let ans = context.evaluateScript(userInput) else { print("执行失败或结果为空") return } // 在JS中执行typeof判断当前结果 guard let typeScript = context.evaluateScript("typeof arguments[0]"), let jsType = typeScript.call(withArguments: [ans])?.toString() else { print("无法获取类型") return } print("执行结果的JS类型是:\(jsType)") // 输出 "number"
这种方法完全模拟了JS原生的类型判断逻辑,能覆盖所有JS支持的类型场景,包括你提到的复杂结构返回值。
为什么你之前的方法失败?
再解释下你尝试的方法无效的原因:
ans as? String失败:因为ans是JSValue实例,不是Swift的String类型——即使它包装的是JS字符串,也需要调用ans.toString()才能转换成Swift字符串。type(of: ans) == type(of: 1)失败:type(of: ans)得到的是JSValue.Type,和Swift的Int.Type完全是两个不同的类型体系,自然不可能相等。
内容的提问来源于stack exchange,提问作者Anters Bear
相关产品推荐
相关产品推荐

