如何在swift中解析JSON文件?

kmi*_*thi 85 ios swift

我有一个JSON文件,想要解析并使用表视图中的对象列表.任何人都可以共享代码来解析swift中的JSON文件.

aka*_*kyy 94

不可能更简单:

import Foundation

let jsonData: Data = /* get your json data */
let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
Run Code Online (Sandbox Code Playgroud)

  • 例如,`let jsonData = NSData.dataWithContentsOfFile(filepath,options:.DataReadingMappedIfSafe,error:nil)` (12认同)
  • @bubakazouba:遗憾的是我无法发表评论.几件事:1.Caroline已经提供了一个从文件中加载数据的片段(这是OP想要的).2.您的代码使用ASCII编码,丢失所有unicode符号,包括超英语语言支持. (7认同)
  • 这种方法的问题在于你最终得到了一堆基础对象.即NSString,NSNumber,NSArray,NSDictionary或NSNull.如果你想在你的代码中处理稍后输入的本机Swift,那么这会造成一种下行负担.特别是如果你有嵌套的字典和数组.有谁知道如何处理这个? (4认同)
  • 在iOS 8.1中加载文件的正确方法似乎是:`NSData(contentsOfFile:path)`.请参阅https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/instm/NSData/initWithContentsOfFile: (2认同)

Kir*_*odi 43

发出API请求

var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Run Code Online (Sandbox Code Playgroud)

准备回应

声明一个数组如下

var data: NSMutableData = NSMutableData()
Run Code Online (Sandbox Code Playgroud)

收到回复

1.

func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
   // Received a new request, clear out the data object
   self.data = NSMutableData()
}
Run Code Online (Sandbox Code Playgroud)

2.

func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
   // Append the received chunk of data to our data object
   self.data.appendData(data)
}
Run Code Online (Sandbox Code Playgroud)

3.

func connectionDidFinishLoading(connection: NSURLConnection!) {
   // Request complete, self.data should now hold the resulting info
   // Convert the retrieved data in to an object through JSON deserialization
   var err: NSError
   var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

   if jsonResult.count>0 && jsonResult["results"].count>0 {
      var results: NSArray = jsonResult["results"] as NSArray
      self.tableData = results
      self.appsTableView.reloadData()

   }
}
Run Code Online (Sandbox Code Playgroud)

当NSURLConnection收到响应时,我们可以期望代表我们调用didReceiveResponse方法.此时,我们只需通过说self.data = NSMutableData()来重置数据,从而创建一个新的空数据对象.

建立连接后,我们将开始在方法didReceiveData中接收数据.在这里传递的数据参数是我们所有丰富信息的来源.我们需要保留每个进入的块,因此我们将它附加到我们之前清除的self.data对象中.

最后,当连接完成后,所有的数据已被接收,connectionDidFinishLoading叫我们准备在我们的应用程序使用的数据.万岁!

这里的connectionDidFinishLoading方法使用NSJSONSerialization类从您的网址反序列化的结果,我们的原始数据转换成有用的Dictionary对象.


dan*_*gai 19

我刚刚编写了一个名为JSON的类,它使Swift中的JSON处理像ES5中的JSON对象一样简单.

将你的swift对象转换为JSON,如下所示:

let obj:[String:AnyObject] = [
    "array": [JSON.null, false, 0, "",[],[:]],
    "object":[
        "null":   JSON.null,
        "bool":   true,
        "int":    42,
        "double": 3.141592653589793,
        "string": "a ?\t?\n",
        "array":  [],
        "object": [:]
    ],
    "url":"http://blog.livedoor.com/dankogai/"
]

let json = JSON(obj)
json.toString()
Run Code Online (Sandbox Code Playgroud)

......或者字符串......

let json = JSON.parse("{\"array\":[...}")
Run Code Online (Sandbox Code Playgroud)

...或URL.

let json = JSON.fromURL("http://api.dan.co.jp/jsonenv")
Tree Traversal
Run Code Online (Sandbox Code Playgroud)

只需通过下标遍历元素:

json["object"]["null"].asNull       // NSNull()
// ...
json["object"]["string"].asString   // "a ?\t?\n"
json["array"][0].asNull             // NSNull()
json["array"][1].asBool             // false
// ...
Run Code Online (Sandbox Code Playgroud)

就像SwiftyJSON一样,如果下标条目不存在,您也不必担心.

if let b = json["noexistent"][1234567890]["entry"].asBool {
    // ....
} else {
    let e = json["noexistent"][1234567890]["entry"].asError
    println(e)
}
Run Code Online (Sandbox Code Playgroud)

如果您厌倦了下标,请添加您的方案,如下所示:

//// schema by subclassing
class MyJSON : JSON {
    init(_ obj:AnyObject){ super.init(obj) }
    init(_ json:JSON)  { super.init(json) }
    var null  :NSNull? { return self["null"].asNull }
    var bool  :Bool?   { return self["bool"].asBool }
    var int   :Int?    { return self["int"].asInt }
    var double:Double? { return self["double"].asDouble }
    var string:String? { return self["string"].asString }
}
Run Code Online (Sandbox Code Playgroud)

然后你去:

let myjson = MyJSON(obj)
myjson.object.null
myjson.object.bool
myjson.object.int
myjson.object.double
myjson.object.string
// ...
Run Code Online (Sandbox Code Playgroud)

希望你喜欢.

使用新的xCode 7.3+,将您的域添加到例外列表(如何将NSAppTransportSecurity添加到我的info.plist文件?)非常重要,请参阅此帖子以获取说明,否则您将收到传输权限错误.


Rob*_*ler 6

可编码

在斯威夫特4+强烈建议使用Codable代替JSONSerialization

Codable包括两个协议:DecodableEncodable. 此Decodable协议允许您以DataJSON 格式解码为符合此协议的自定义结构/类。

例如,想象一下我们有这个简单的情况Data(两个对象的数组)

let data = Data("""
[
    {"name":"Steve","age":56}, 
    {"name":"iPhone","age":11}
]
""".utf8)
Run Code Online (Sandbox Code Playgroud)

然后遵循struct并实施协议Decodable

struct Person: Decodable {
    let name: String
    let age: Int
}
Run Code Online (Sandbox Code Playgroud)

现在你可以解码你DataPerson使用数组,JSONDecoder其中第一个参数的类型符合Decodable并且应该Data解码这个类型

do {
    let people = try JSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
Run Code Online (Sandbox Code Playgroud)

...请注意,解码必须用try关键字标记,因为您可能会在命名时犯一些错误,然后您的模型无法正确解码...所以您应该将它放在 do-try-catch 块中


json中key与property name不同的情况:

  • 如果密钥在使用snake_case命名,你可以设置解码器的keyDecodingStrategyconvertFromSnakeCase从变化的关键property_name,以驼峰propertyName

    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let people = try decoder.decode([Person].self, from: data)
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您需要唯一的名称,您可以在声明键名称的结构/类中使用编码键

    let data = Data(""" 
    { "userName":"Codable", "age": 1 } 
    """.utf8)
    
    struct Person: Decodable {
    
        let name: String
        let age: Int
    
        enum CodingKeys: String, CodingKey {
            case name = "userName"
            case age
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


Cip*_*rau 5

这是在 Swift 2.0 中进行 JSON 和 NSData 之间转换的代码

// Convert from NSData to json object
func nsdataToJSON(data: NSData) -> AnyObject? {
    do {
        return try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil
}

// Convert from JSON to nsdata
func jsonToNSData(json: AnyObject) -> NSData?{
    do {
        return try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted)
    } catch let myJSONError {
        print(myJSONError)
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)