SwiftyJSON - 无法从 JSON 字符串中获取 transactionId

SwiftyJSON - Unable to get transactionId from JSON String

我正在使用 CocoaAsyncSocket 从使用 JSON 的服务器 API 检索消息。我能够获取数据并将其转换为可打印的字符串,但我无法做的是使用 Swifty 从我尝试解析已有的 JSON 字符串中检索一个值 (transactionId) JSON。我知道还有其他类似的帖子,但 none 已经解决了我的问题。

在ViewController中:

func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {

    guard let msg = String(data: data, encoding: .utf8) else { return }

    var response = " "
    if msg.contains("Reset") {
        transactionID = ParseJSON().parse(message: msg)

        response = String(format: "{\"Response\":{\"transactionId\":\"%@%\",\"content\":{\"Reset\":{}}}}", transactionID)
        socket.write((response.data(using: .utf8))!, withTimeout: -1, tag: 0)
    }

    socket?.readData(withTimeout: -1, tag: 0)
}

解析JSON class:

func parse (message: String) -> String {
    var parsedMessage = " "

    let json = JSON(parseJSON: message)
    let transactionId = json["Request"]["transactionId"].stringValue
    parsedMessage = transactionId

    print(parsedMessage)

    return parsedMessage
}

显示的结果是一个空的 transactionId 值。没有打印或任何东西。 如果您在我的代码中发现任何错误或有更好的方法,请告诉我!

编辑:

这是我试图解析的字符串:

{"Request": {"content": {"Reset": {}}, "transactionId": "f7c4d630-552b-46d9-a37d-44450537b48d"}}

这是我的输出:

{\"Response\":{\"transactionId\":\"\",\"content\":{\"Reset\":{}}}}

问题不在于代码。考虑:

func parse(message: String) -> String {
    let json = JSON(parseJSON: message)
    return json["Request"]["transactionId"].stringValue
}

let input = """
    {"Request": {"content": {"Reset": {}}, "transactionId": "f7c4d630-552b-46d9-a37d-44450537b48d"}}
    """

let transactionID = parse(message: input)

print("transactionId:", transactionID)

let response = String(format: "{\"Response\":{\"transactionId\":\"%@\",\"content\":{\"Reset\":{}}}}", transactionID)

print("response:", response)

如您所料,上述结果是:

transactionId: f7c4d630-552b-46d9-a37d-44450537b48d

response: {"Response":{"transactionId":"f7c4d630-552b-46d9-a37d-44450537b48d","content":{"Reset":{}}}}

所以我怀疑输入的 message 与您预期的不太一样。所以我可能建议添加一些错误处理,这样你就可以准确地诊断哪里出了问题:

func parse(message: String) -> String {
    let json = JSON(parseJSON: message)
    if let error = json.error {
        fatalError("JSON parsing error: \(error)")
    }

    let request = json["Request"]
    if let error = request.error {
        fatalError("request error: \(error)")
    }

    let transactionId = request["transactionId"]
    if let error = transactionId.error {
        fatalError("transactionId error: \(error)")
    }

    return transactionId.stringValue
}

现在,在实践中,您可能不会使用 fatalError,而是会进行一些优雅的错误处理(例如,将 parse 更改为 throws,然后 throw 遇到的错误(如果有的话),然后 catch 您调用 parse 的错误并优雅地处理任何 运行 时间问题)。但在此诊断过程中,fatalError 很有用,因为它会在有问题的行停止调试器,从而简化诊断过程。

最重要的是,请求的形式不能完全符合您的期望。请注意,它对大小写、格式错误 JSON 等非常敏感。因此,通过查看 SwiftyJSON 提供的错误,您应该能够很快缩小问题范围。


下面,你告诉我们Data是:

<7b225265 71756573 74223a20 7b22636f 6e74656e 74223a20 7b225265 73657422
 3a207b7d 7d2c2022 7472616e 73616374 696f6e49 64223a20 22643937 36303036
 622d3130 38302d34 3864652d 39323232 2d623139 63363663 35303164 31227d7d
 00>

问题是最后一个字节 0x00。如果你删除它,它会起作用。

FWIW,当我将该十六进制字符串转换回 Data 并通过 JSONSerialization 将其 运行 时,它确认了诊断:

Error Domain=NSCocoaErrorDomain
Code=3840 "Garbage at end."
UserInfo={NSDebugDescription=Garbage at end.}

您需要弄清楚为什么 0x00 包含在有效负载的末尾并将其删除。