这可能非常简单,但我不熟悉使用JSON。
我从OSC消息的参数中收到此JSON字符串:
{"status":"ok","address":"\/workspaces","data":[{"version":"4.2.1","displayName":"Untitled Workspace","uniqueID":"82688E14-5E8F-428E-A781-8ABC920A5515","hasPasscode":false}]}
我正在尝试将其转换为字典,因此我可以处理数据。我在Stack Overflow上尝试了很多答案,但this one似乎最相关。但是,它会抛出错误“数据无法读取,因为它的格式不正确。”
有人可以告知为什么这个字符串的格式错误吗?
这是我的代码:
func didReceive(_ message: OSCMessage){
let jsonString = String(describing: message.arguments[0]!)
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
let dict = convertToDictionary(text: jsonString)
print(dict as Any)
}
非常感谢!
丹
编辑:我修改了代码以删除可能导致错误的“\”。但是,它仍然会使用以下代码抛出相同的错误:
func didReceive(_ message: OSCMessage){
let jsonString = message.arguments[0] as! String
let jsonStringEdit = jsonString.replacingOccurrences(of: "\\", with: "")
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
let dict = convertToDictionary(text: jsonStringEdit)
print(dict as Any)
}
编辑2:
解决!
字符串末尾似乎有某种null / non-printable字符。我现在通过在解析之前删除它来解决了这个问题。我已使用此代码将其删除:
jsonString.remove(at: jsonString.index(before: jsonString.endIndex))
感谢大家的建议!
答案 0 :(得分:0)
答案 1 :(得分:0)
这有效:
let jsonStr = """
{
"status":"ok",
"address":"\\/workspaces",
"data":[{
"version":"4.2.1",
"displayName":"Untitled Workspace",
"uniqueID":"82688E14-5E8F-428E-A781-8ABC920A5515",
"hasPasscode":false
}]
}
"""
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
let dict = convertToDictionary(text: jsonStr)
print(dict as Any)
我必须在地址值中添加一个额外的反斜杠转义字符,以便在操场上工作。这可能会导致您的问题。
答案 2 :(得分:0)
因为如果从服务接收字符串,字符串应该是可解析的。但是,如果您尝试将其用作代码而不进一步转义,则会混淆Swift解析器。但是,因为使用[String:Any]
是如此令人难以置信的混乱(更不用说unSwifty :-)我建议你自己帮忙并尝试Codable
协议。这样你可能会在游乐场结束这样的事情:
import Cocoa
let jsonData = """
{"status":"ok","address":"\\/workspaces","data":[{"version":"4.2.1", "displayName":"Untitled Workspace","uniqueID":"82688E14-5E8F-428E-A781-8ABC920A5515","hasPasscode":false}]}
""".data(using: .utf8)!
struct InnerData : Codable {
let version: String
let displayName: String
let uniqueID: String
let hasPasscode: Bool
}
struct AddressData : Codable {
let status: String
let address: String
let data: [InnerData]
}
do {
let adrData = try JSONDecoder().decode(AddressData.self, from:jsonData)
print(adrData)
} catch {
print(error)
}
完美解析(给定转义的\
)并且在此之后将更好地处理。请注意,如果从某个服务获取字符串(包括\
),则不需要转义。如果仍然无效,请发布错误消息(以及它出现的确切行)。
我刚把它添加到我的游乐场:
let jsonData2 = """
{"status":"ok","address":"/workspaces","data":[{"version":"4.2.1","displayName":"Untitled Workspace 1","uniqueID":"FE329024-DC98-4197-9B3F-2509851A1E50","hasPasscode":false}]}
""".data(using: .utf8)!
do {
let adr = try JSONDecoder().decode(AddressData.self, from:jsonData2)
print(adr.data[0].uniqueID)
} catch {
print(error)
}
因此,您提供的String
完美解析,但 的String
似乎包含一些Garbage at end.
,如错误消息所示。您可能会尝试迭代其最终字符并打印出他们的代码点,如果您给出的代码首先是ASCII,ISO-8859-1或其他一些编码,这可能很容易指出一些编码问题。不幸的是推测这些东西,但它们可能很难转换成StackOverflow格式,因为我们在这里都是Unicode。在其他编码中重新解释Strings
可能会导致任何数量的奇怪行为,但对我来说,它通常会在立即生成String
时失败并显示错误。
从定义中访问InnerData
结构只是简单明了。由于您的data
标记包含Array
InnerData
,因此您必须在访问其内部属性之前对其进行下标,如上所述。除此之外,它不会更自然。