解码包含数组的JSON字符串

时间:2018-04-12 07:31:38

标签: json swift macos decode encode

我使用下面的类中的JSONSerialization对JSON字符串进行编码和解码。我可以编码NSDictionaries& NSArrays和我可以解码使用NSDictionaries编码的字符串,但不能解码从数组编码的字符串,它是JSONSerialization.jsonObject(...的barfs) 我可以在没有阵列的情况下工作,但是如果知道为什么会这样,我会很高兴。赞赏的想法

let a = [1,2,3,4,5]  
let s = JSON.Encode( a )!
JSON.Decode( s ) // fails    

let a = ["a" : 1, "b" : 2, "c" : 3 ]  
let s = JSON.Encode( a )!
JSON.Decode( s ) // works

-

class JSON: NSObject {

   static func Encode( _ obj: Any ) -> String? {

       do {
           let data = try JSONSerialization.data(withJSONObject: obj, options:JSONSerialization.WritingOptions(rawValue: 0) )

           if let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
               return string as String
           }
           return nil
       } catch let error as NSError {
           return nil
       }
   }

   static func Decode( _ s: String ) -> (NSDictionary?) {

       let data = s.data(using: String.Encoding.utf8, allowLossyConversion: false)!
       do {
           // fails here to work on anything other than "{ a : b, c : d }"
           // hates any [1,2,3] arrays in the string
           let json = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
           return json
       } catch let error as NSError {
           return nil
       }

   }   

}

1 个答案:

答案 0 :(得分:1)

您将结果投射到词典,因此无法使用其他内容。

解决方案是使函数具有通用性并指定预期的返回类型。

我清理了一下代码,基本上如果它包含投掷 API,建议创建一个函数throw

class JSON {

    enum JSONError : Error { case typeMismatch }

    static func encode( _ obj: Any ) throws -> String {
        let data = try JSONSerialization.data(withJSONObject: obj)
        return String(data: data, encoding: .utf8)!
    }

    static func decode<T>( _ s: String ) throws -> T {
        let data = Data(s.utf8)
        guard let result = try JSONSerialization.jsonObject(with: data) as? T else {
           throw JSONError.typeMismatch 
        }
        return result
    }
}


let a = [1,2,3,4,5]
do {
    let s = try JSON.encode(a)
    let u : [Int] = try JSON.decode(s)
    print(u)
} catch { print(error) }

注意(一如既往):

在Swift中不要使用NSDictionaryNSStringNSError.mutableContainers完全没有意义。