如何在Swift中解析JSON并将其转换为对象数组?

13

这是我网站上的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": ""
}]

现在我想要将一个对象数组中的每个对象都保存起来,但可能会有超过三个的元素。我认为我必须使用 NSJsonSerialization,因为我需要从 URL 获取它。

(我正在使用Swift 2)


1
你是如何尝试做到这一点的?(可以展示一些代码),你遇到了什么问题? - bolnad
你的实际问题是什么? - Lucas Huang
我该如何将在线JSON文件中的对象保存到数组中? - SeppeDev
你看过NSJSONSerialization了吗? - Paulw11
4个回答

9
在Swift 4.x中有一种简单的方法来实现这个,但我曾经花费了很多时间才找到答案,所以我在这里发布它。

步骤1:创建一个与您的JSON匹配且派生自Codable的类。在这里,我随意将包装您原始JSON的类命名为BlogPost

您还需要添加一个初始化方法。
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;
    }
}
步骤2:添加一个load方法,用于加载你的数组。
它将接受一个指向包含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
    }

我认为棘手的部分是发送到解码器方法的类型。由于我们想要解码一组可解码的BlogPost对象,因此我们必须使用:[BlogPost].self

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

1
从Swift 5开始,在可编码的结构体中不需要显式的init - 编译器会自动生成它。 - iago849

8

我个人会使用NSArray和NSDictionary引用你的JSON中的每个对象。下面这样做应该足够了(让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")
        }
    }
}

我认为问题在于如何通过NSJSONSerialization将JSON解析为数组和字典。 - Paulw11
这段代码可以正常运行,但不是我想要的直接结果。但它对我有所帮助。谢谢! - SeppeDev
@Cailean Wilkinson,您能否解释一下“让JSON成为您的JSON变量”是什么意思?JSON变量的值将是什么? - deltami

1
这对我起作用了:
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)
    }
}

0
另一种方法是使用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()

只是一个简单的例子,希望这能对某人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接