Swift NSObject序列化后无法在NodeJS中解析的问题求助
解决Swift序列化NSObject到NodeJS解析失败的问题
问题根源分析
- Swift端用
print(jsonString)会自动追加换行符,导致输出的JSON带多余\n,NodeJS解析时易因额外字符失败。 - NodeJS代码存在笔误:
JSON.parse(obj)使用了未定义的obj变量,且未将Buffer类型的data转为字符串。 - Swift中不必要的NSObject类型转换增加了类型安全风险,还可能引发序列化异常。
- stdout的
data事件可能分块触发,单个chunk未必是完整JSON,直接解析会失败。
修复步骤
1. 优化Swift代码,消除冗余转换与多余换行
修改getWindowBy函数,直接处理CGWindowList返回的字典类型,跳过不必要的NSObject转换:
func getWindowBy(windowNumber: Int) -> [String: Any]? { guard let windowList = CGWindowListCopyWindowInfo(.optionAll, 0) as? [[String: Any]] else { return nil } for window in windowList { if let number = window["kCGWindowNumber"] as? Int, number == windowNumber { return window } } return nil }
修改event函数,用fputs代替print避免自动加换行,同时增加类型安全检查:
func event(e: NSEvent?) { let winNum: Int = 5 guard let window = getWindowBy(windowNumber: e?.windowNumber ?? winNum) else { fputs("{}", __stdoutp) // 输出空JSON避免NodeJS无限等待 fflush(__stdoutp) return } do { let data = try JSONSerialization.data(withJSONObject: window, options: .withoutEscapingSlashes) guard let jsonString = String(data: data, encoding: .utf8) else { fputs("{}", __stdoutp) fflush(__stdoutp) return } // 直接输出纯JSON字符串,无额外换行 fputs(jsonString, __stdoutp) fflush(__stdoutp) } catch { fputs("{\"error\":\"\(error.localizedDescription)\"}", __stdoutp) fflush(__stdoutp) } }
2. 修复NodeJS代码,处理分块与正确解析
NodeJS端需要拼接分块数据,确保拿到完整JSON后再解析,同时修正笔误:
let jsonBuffer = ''; ipc.stdout.on('data', function (data) { jsonBuffer += data.toString().trim(); // 拼接并去除首尾空白字符 try { const parsedObj = JSON.parse(jsonBuffer); console.log("解析成功:", parsedObj); jsonBuffer = ''; // 解析完成后清空缓存 } catch (err) { // 解析失败说明数据不完整,继续等待下一个chunk console.log("等待完整数据..."); } });
额外提示
- 如果需要输出多段JSON,可以在Swift端输出每个JSON后追加换行符,NodeJS端按换行分割数据,能更可靠地处理多段输出。
- Swift中优先使用原生类型(如
[String: Any])而非NSObject/NSDictionary,减少类型转换风险,提升代码可读性。
内容的提问来源于stack exchange,提问作者vibhu
相关产品推荐
相关产品推荐

