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

时间:2019-08-28 19:27:47

标签: json swift swifty-json

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

在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)
}

ParseJSON类:

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值。什么都没打印。 如果您发现我的代码中有任何错误或有更好的方法,请告诉我!

编辑:

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

  

{“请求”:{“内容”:{“重置”:{}},“ transactionId”:“ f7c4d630-552b-46d9-a37d-44450537b48d”}}

这是我的输出:

  

{\“ Response \”:{\“ transactionId \”:\“ \”,\“ content \”:{\“ Reset \”:{}}}}

1 个答案:

答案 0 :(得分:0)

问题不在于代码。考虑:

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”:{“ 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,然后再更改{{1} }遇到的错误(如果有的话),然后是throw的错误,您在调用catch的错误时可以优雅地处理所有运行时问题。但是在此诊断过程中,parse很有用,因为它将使调试器停在有问题的行,从而简化了诊断过程。

最重要的是,请求的格式必须与您期望的格式完全不同。请注意,它将对大小写,JSON格式错误等非常敏感。因此,通过查看SwiftyJSON提供的错误,您应该能够迅速缩小问题范围。


下面,您告诉我们fatalError是:

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> 。如果将其删除,它将起作用。

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

  

Error Domain = NSCocoaErrorDomain
  代码= 3840“垃圾最终。”
  UserInfo = {NSDebugDescription =垃圾。}

您需要弄清楚为什么JSONSerialization包含在有效负载的末尾,然后将其删除。