You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WKWebView执行evaluateJavaScript返回JavaScript对象格式错误如何解决

问题根因

你遇到的语法错误本质是两个问题导致的:

  1. 你在Swift中打印的带=、分号格式的对象,是Swift/Objective-C对字典类型的默认调试输出格式,不是合法的JavaScript对象语法。你直接把Swift侧拿到的解析后对象用\(object)插值到JS执行字符串时,等于把这种不符合JS语法的内容直接插入到了JS代码中,自然会触发Unexpected token '='的语法错误。
  2. 额外的时序隐患:evaluateJavaScript是异步执行方法,你先后两次调用分别定义parse函数、执行parse(),很可能出现parse函数还没完成定义,后面的调用就已经执行的问题。

解决方案

你完全不需要把JSON解析后拿回Swift侧再传递给JS,直接利用已经序列化好的JSON字符串即可,因为标准JSON格式本身就是合法的JS对象字面量,可以直接在JS代码中使用。

修正后的代码

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,
    // 转成Bool类型,JSON序列化后会输出true/false而非0/1,符合你的预期格式
    "is_archived": Bool(truncating: account.is_archived as NSNumber),
    "sort": account.sort,
    "create_datetime": account.create_datetime,
    "update_datetime": account.update_datetime ?? "",
    "stat": statDict
]

do {
    let accountData = try JSONSerialization.data(withJSONObject: accountDict)
    guard var accountString = String(data: accountData, encoding: .utf8) else {
        return
    }
    // 转义JSON中的单引号,避免打断JS字符串
    accountString = accountString.replacingOccurrences(of: "'", with: "\\'")
    
    // 合并所有JS逻辑为一段,一次执行避免异步嵌套问题
    let jsCode = """
    const account = JSON.parse('\(accountString)');
    window.emitter.emit('openDialog', 'Account', account);
    window.emitter.on('closeDialog', function() {
        window.webkit.messageHandlers.emitterMessage.postMessage('closeDialog');
    });
    window.emitter.on('createAccount', function() {
        window.webkit.messageHandlers.emitterMessage.postMessage('createAccount');
    });
    """
    
    webView.evaluateJavaScript(jsCode) { _, error in
        if let error = error {
            print("JS执行错误: \(error)")
        }
    }
} catch {
    print("JSON序列化失败: \(error)")
}

额外优化建议

  • 不要使用try!处理JSON序列化,一旦序列化失败会直接导致App崩溃,改用do-catch捕获异常更安全。
  • 所有JS逻辑可以合并为一段一次执行,不需要多次调用evaluateJavaScript,既减少异步回调嵌套,也能避免不同JS执行片段的时序问题。
  • 如果需要输出布尔值类型的字段,在构造Swift字典时就把对应值转为Bool类型,JSONSerialization会自动将其序列化为JSON标准的true/false格式。

内容的提问来源于stack exchange,提问作者andrey leganov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:15:02