首页 > 解决方案 > WKWebView evaluateJavaScript 返回错误的 JavaScript 对象

问题描述

我正在制作一个混合应用程序并使用 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 中输出不正确。

如何将对象带入正确的形式?

标签: javascriptswiftwkwebviewjsobjectevaluatejavascript

解决方案


您正在尝试将 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)")
            
        }
    }

结果在窗口: 使用通过 swift 发送的参数对象调用发射器函数的结果


推荐阅读