【问题标题】:WKWebView evaluateJavaScript returns wrong JavaScript ObjectWKWebView evaluateJavaScript 返回错误的 JavaScript 对象
【发布时间】:2021-08-24 22:24:40
【问题描述】:

我正在制作一个混合应用程序并使用 WKWebView。 我需要将 JavaScript 对象传递给发射器命令以打开编辑对话框。 这是我的代码:

        let statDict: [String: Any] = [
            "income" : account.stat.income,
            "expense" : account.stat.expense,
            "summary" : account.stat.summary,
            "incomeShorten" : account.stat.incomeShorten,
            "expenseShorten" : account.stat.expenseShorten,
            "summaryShorten": account.stat.summaryShorten
            ]
        let accountDict: [String: Any] = [
            "id": account.id,
            "name": account.name,
            "description": "",
            "icon": account.icon,
            "currency": account.currency,
            "customer_contact_id": account.customer_contact_id ?? 0,
            "is_archived": account.is_archived,
            "sort": account.sort,
            "create_datetime": account.create_datetime,
            "update_datetime": account.update_datetime ?? "",
            "stat": statDict
        ]

        let accountData = try! JSONSerialization.data(withJSONObject: accountDict, options: JSONSerialization.WritingOptions(rawValue: 0))

        guard let accountString = String(data: accountData, encoding: .utf8) else {
            return
        }
        webView.evaluateJavaScript("function parse(string){ return JSON.parse(string)}") { result, error in
            if error == nil { // this is returns correct staff
                
            }
        }
        webView.evaluateJavaScript("parse('\(accountString)')") { object, error in
            if error == nil {
                let object = object as AnyObject
                print("parse object \(object)")
                
                webView.evaluateJavaScript("window.emitter.emit('openDialog', 'Account', \(object))") { (result, error) in
                    if error == nil { // here the error "Unexpected token '='..."
                        webView.evaluateJavaScript("window.emitter.on('closeDialog', function(){  window.webkit.messageHandlers.emitterMessage.postMessage('closeDialog'); })") { (result, error) in
                            if error == nil {
                                
                            }
                        }
                        webView.evaluateJavaScript("window.emitter.on('createAccount', function(){  window.webkit.messageHandlers.emitterMessage.postMessage('createAccount'); })") { (result, error) in
                            if error == nil {
                                
                            }
                        }
                    } else {
                        print(error as Any)
                    }
                }
            }
        }

函数返回的\(对象)如下所示:

    {
    "create_datetime" = "2021-08-24 19:19:28";
    currency = RUB;
    "customer_contact_id" = 1;
    description = "";
    icon = "";
    id = 7;
    "is_archived" = 0;
    name = "Business 111";
    sort = 0;
    stat =     {
        expense = 0;
        expenseShorten = 0;
        income = 300000;
        incomeShorten = 300K;
        summary = 300000;
        summaryShorten = 300K;
    };
    "update_datetime" = "";
}

但它应该是这样的:

{
  create_datetime: "2021-08-24 19:19:28",
  currency: "RUB",
  customer_contact_id: 1,
  description: "",
  icon: "",
  id: 7,
  is_archived: false,
  name: "Business 111",
  sort: 0,
  stat: {
    expense: 0,
    expenseShorten: "0",
    income: 300000,
    incomeShorten: "300K",
    summary: 300000,
    summaryShorten: "300K"
  },
  update_datetime: ""
}

对于这样的对象,编译器会生成错误 Unexpected token '='。需要一个标识符作为属性名称。

如果你在 js 编译器中运行 parse(string) 函数会返回正确的对象,但在 swift 中输出不正确。

如何将对象变为正确的形式?

【问题讨论】:

    标签: javascript swift wkwebview jsobject evaluatejavascript


    【解决方案1】:

    您正在尝试将 Swift 对象(在您的情况下为 NSMutableDictionary)的字符串插值表示传递给 Javascript。 相反,您可以直接将 JSON 表示传递给 JS 上下文,因为 JSON 是一个原生 Javascript 对象,它应该做您想要实现的目标:

        /// Sample emitter function that consumes object an prints its local parameter, also assigns it to sample object value in window.
        self.webView?.evaluateJavaScript(
            "window.emitter = (sampleObject) => { window.sampleObject = sampleObject;setTimeout(function(){console.log('Hello sampleObject : ',sampleObject.name); }, 7000);}"
        ) { result, error in
            if error == nil { // this is returns correct staff
                
            }
        }
        self.webView?.evaluateJavaScript("window.emitter(\(accountString));") { result, error in
            if error == nil {
                print("parse object \(result)")
                
            }
        }
    

    窗口中的结果:

    【讨论】:

    • 谢谢,可惜发射器不会读取 JSON,你需要传递一个 javascript 对象
    • 您面临的问题不是您当时在问题中提出的问题。我创建了一个虚拟发射器函数,它接受一个对象并将其分配给窗口,并将其“名称”值打印到控制台。 JSON 只是 JS 对象的上标,因为它的名称也是 Javascript 对象表示法的同义词,因此只要您不使用对象或函数作为值,序列化它应该可以工作。 (至少在您的示例中。)我不知道您的发射器功能是做什么的,所以除非您提供发射器功能,否则我无能为力。
    • 我可以在下一条评论中提供来自developit / mitt 库内嵌在本地 index.html 中的代码
    • !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).mitt=n()}(this,function(){return function(e){return{all:e=e||new Map,on:function(n,t){var f=e.get(n);f&&f.push(t)||e.set(n,[t])},off:function(n,t){var f=e.get(n);f&&f.splice(f.indexOf(t)>>>0,1)},emit:function(n,t){(e.get(n)||[]).slice().map(function(e){e(t)}),(e.get("*")||[]).slice().map(function(e){e(n,t)})}}}});window.emitter = mitt();
    猜你喜欢
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多