如何将 OC JSContext[@"makeNSColor"] 更改为 swift

Posted

技术标签:

【中文标题】如何将 OC JSContext[@"makeNSColor"] 更改为 swift【英文标题】:how to change OC JSContext[@"makeNSColor"] to swift 【发布时间】:2019-04-26 07:55:25 【问题描述】:

'JSContext'没有下标成员,oc可以,但是swift不行

我已经尝试过 swift 4

OC没问题,例如

JSContext *context = [[JSContext alloc] init];
context[@"makeNSColor"] = ^(NSDictionary *rgb)
float r = rgb[@"red"].floatValue;
float g = rgb[@"green"].floatValue;
float b = rgb[@"blue"].floatValue;
return [NSColor colorWithRed:(r / 255.f) green:(g / 255.f) blue:(b / 255.f) alpha:1.0];
;

Swift 是错误的:

var context = JSContext() as? JSContext     //Cannot assign value of type 'Any?' to type 'JSContext?'

        context!["makeNSColor"] =  rgb in     //Type 'JSContext' has no subscript member

            var r: Float = rgb?["red"].floatValue

            var g: Float = rgb?["green"].floatValue

            var b: Float = rgb?["blue"].floatValue

            return NSColor(red: CGFloat((r / 255.0)), green: CGFloat((g / 255.0)), blue: CGFloat((b / 255.0)), alpha: 1.0)

        

它有两个错误:无法分配“任何?”类型的值输入'JSContext?',输入'JSContext'没有下标成员,我不知道怎么解决,你能告诉我怎么解决吗,非常感谢。

我试图改变上下文!作为! NSMutableDictionary,或者[String,Any],但是还是报错,不能改

【问题讨论】:

您是否阅读过文档,是否在线搜索过解决方案?使用let context = JSContext()! 和使用objectForKeyedSubscript 来获得该值怎么样? 你在苹果论坛问过forums.developer.apple.com/thread/116063吗?从答案中给出的推荐链接nshipster.com/javascriptcore:“相反,您可以通过调用 setObject(_:forKeyedSubscript:) 方法将 Swift 值设置为 JSContext 中的变量。” 在 JS 中显示 makeNSColor 的定义或值。 【参考方案1】:

使用下面的 swift 等效

let colorHandle: @convention(block) ([String : Any]) -> UIColor =  rgb in
    let r = rgb["red"] as! CGFloat
    let g = rgb["green"] as! CGFloat
    let b = rgb["blue"] as! CGFloat

    return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1.0)


context?.setObject(colorHandle, forKeyedSubscript: "makeNSColor" as NSCopying & NSObjectProtocol)

【讨论】:

【参考方案2】:

我不知道makeNSColor 是什么对象。但是如果是var makeNSColor = red : 10/255, green : 10/255, blue : 255/255, a : 1;,这里有一个很好的例子,如何从字典makeNSColor创建UIColor:

    func f () 
        let context = JSContext()!
        let script = """
var makeNSColor = red : 10/255, green : 10/255, blue : 255/255, a : 1;
"""
        let cc = context.evaluateScript(script).context // result is
        let val = cc?.objectForKeyedSubscript("makeNSColor")
        guard let dict = val?.toDictionary() as? [String : CGFloat] else return
        let color = UIColor(displayP3Red: dict["red"] ?? 0, green: dict["green"] ?? 0, blue: dict["blue"] ?? 0, alpha: dict["a"] ?? 0)

        print(color)
    

如果你想在JS中创建makeNSColorDictionary,使用下一个函数:

    func addColor (r : Float, g : Float, b : Float) 
        let context = JSContext()!
        let script = """
var makeNSColor = red : \(r)/255, green : \(g)/255, blue : \(b)/255, a : 1;
"""
        let cc = context.evaluateScript(script).context // result is

        // next code only needed to check the `makeNSColor`
        let val = cc?.objectForKeyedSubscript("makeNSColor")
        guard let dict = val?.toDictionary() as? [String : CGFloat] else return
        let color = UIColor(displayP3Red: dict["red"] ?? 0, green: dict["green"] ?? 0, blue: dict["blue"] ?? 0, alpha: dict["a"] ?? 0)

        print(color)
    

【讨论】:

以上是关于如何将 OC JSContext[@"makeNSColor"] 更改为 swift的主要内容,如果未能解决你的问题,请参考以下文章

iOS JS 交互之利用系统JSContext实现 JS调用oc方法

JavaScriptCore

OC中如何将一个字符串截取成若干个数组对象

如何在 iOS 中停止 JSContext 评估?

IOS oc 关于如何读取本地JSON

从 JSContext 中获取 JS Promise/async 函数的值