我正在使用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 \”:{}}}}
答案 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
包含在有效负载的末尾,然后将其删除。