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
包含在有效负载的末尾并将其删除。
我正在使用 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
包含在有效负载的末尾并将其删除。