简体   繁体   English

我如何解析 JSON 以将其转换为 Swift 中的对象数组?

[英]How can I parse JSON to convert this to an array of objects in Swift?

This is a sample of my json that is on my website:这是我网站上的 json 示例:

[{
    "id": "1",
    "day": "Saturday 3/10",
    "title": "title1",
    "description": "lorem ipsum dolor sit amet consectetur adipiscing elit",
    "image": ""
},
{
    "id": "2",
    "day": "Saturday 10/10",
    "title": "title2",
    "description": "lorem ipsum dolor sit amet consectetur adipiscing elit",
    "image": ""
},
{
    "id": "3",
    "day": "Saturday 17/10",
    "title": "title3",
    "description": "lorem ipsum dolor sit amet consectetur adipiscing elit",
    "image": ""
}]

And now I want to save every object in an array of objects but it's possible that there are more than three elements.现在我想将每个对象保存在一个对象数组中,但可能有三个以上的元素。 I think I have to use NSJsonSerialization because I have to get it from an url.我想我必须使用NSJsonSerialization因为我必须从 url 中获取它。

(I'm using swift 2) (我正在使用 swift 2)

There is an easy way to do this in Swift 4.x But I had a difficult time getting to the simple answer so I'll post it here.在 Swift 4.x 中有一种简单的方法可以做到这一点,但我很难找到简单的答案,所以我会把它贴在这里。

Step 1 : Create a class that matches your JSON and is derived from Codable.第 1 步:创建一个与您的 JSON 匹配并派生自 Codable 的类。 Here I arbitrarily name the class (that wraps your original JSON) as BlogPost .在这里,我随意将该类(包装您的原始 JSON)命名为BlogPost

You'll need to add an init method also您还需要添加一个 init 方法

class BlogPost : Codable{
    var id : Int
    var day : Date
    var title : String
    var description : String

    init (id : Int, day : Date, title : String, description : String){
         self.id = id;
         self.day = day;
         self.title = title;
         self.description = description;
    }
}

Step 2 : add a load method that will load your array.第 2 步:添加一个加载数组的加载方法。

It will take a filename (pointing to file with json) and return an array of BlogPost ([BlogPost])它将获取一个文件名(指向带有 json 的文件)并返回一个 BlogPost 数组([BlogPost])

 func loadJson(filename fileName: String) -> [BlogPost]? {
        if let url = Bundle.main.url(forAuxiliaryExecutable: fileName) {
            do {
                let data = try Data(contentsOf: url)
                let decoder = JSONDecoder()
                let allBlogPosts = try decoder.decode([BlogPost].self, from: data)
                return allBlogPosts
            } catch {
                print("error:\(error)")
            }
        }
        return nil
    }

} }

I think the tricky part is the type that you send to the decoder method.我认为棘手的部分是您发送给解码器方法的类型。 Since we want to decode an array of Decodable BlogPost objects we have to use: [BlogPost].self因为我们想要解码我们必须使用的 Decodable BlogPost 对象数组: [BlogPost].self

decoder.decode([BlogPost].self, from: data)

I would personally do this using NSArrays and NSDictionaries to reference each object in your JSON.我个人会使用 NSArrays 和 NSDictionaries 来引用 JSON 中的每个对象。 Something like this should suffice (let JSON be your JSON variable)这样的东西就足够了(让JSON成为你的 JSON 变量)

if let array = JSON as? NSArray {
    for obj in array {
        if let dict = obj as? NSDictionary {
            // Now reference the data you need using:
            let id = dict.valueForKey("id")
        }
    }
}

This worked for me:这对我有用:

if let JSONData = try? Data(contentsOf: url!) {
    do {
        let parsed = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as? NSArray
        for obj in parsed! {
            let obj = MyObject(json: obj as! NSDictionary)
            list.append(obj)
        }
    } catch let parseError {
        print(parseError)
    }
}

Another way is with https://github.com/Hearst-DD/ObjectMapper , you can easly make objects from JSON and convert them back to JSON另一种方法是使用https://github.com/Hearst-DD/ObjectMapper ,您可以轻松地从 JSON 生成对象并将它们转换回 JSON

class Event: Mappable {
    var id:String?
    var day:String?
    var title:String?
    var description:String?
    var image:String?

    required init?(map: Map){

    }

    func mapping(map: Map) {
        id             <- map["id"]
        day            <- map["day"]
        title          <- map["title"]
        description    <- map["description"]
        image          <- map["image"]
    }
}
// make event from JSON
let event = Mapper<Event>().map(JSON)
// to JSON
event.toJSON()

just simple example, I hope this will help to someone.只是一个简单的例子,我希望这会对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM