JSON作为数据的一种存储格式,具有简洁,便于读写的优点。Swift内部就提供了对JSON格式数据进行解析的库,使用也比较简单,但也有些使用时需要注意的点。


以官网提供的landmark为例,解析landmarkData.json,其数据如下

[
    {
        "name": "Turtle Rock",
        "category": "Rivers",
        "city": "Twentynine Palms",
        "state": "California",
        "id": 1001,
        "isFeatured": true,
        "isFavorite": true,
        "park": "Joshua Tree National Park",
        "coordinates": {
            "longitude": -116.166868,
            "latitude": 34.011286
        },
        "description": "...",
        "imageName": "turtlerock"
    },
    {
        "name": "Silver Salmon Creek",
        "category": "Lakes",
        "city": "Port Alsworth",
        "state": "Alaska",
        "id": 1002,
        "isFeatured": false,
        "isFavorite": false,
        "park": "Lake Clark National Park and Preserve",
        "coordinates": {
            "longitude": -152.665167,
            "latitude": 59.980167
        },
        "description": "...",
        "imageName": "chilkoottrail"
    },
    ......
    {
        "name": "Lake Umbagog",
        "category": "Lakes",
        "city": "Errol",
        "state": "New Hampshire",
        "id": 1012,
        "isFeatured": false,
        "isFavorite": false,
        "park": "Umbagog National Wildlife Refuge",
        "coordinates": {
            "longitude": -71.056816,
            "latitude": 44.747408
        },
        "description": "...",
        "imageName": "umbagog"
    }
]

构建数据对象

关键步骤就是构建一个与之相匹配的DataObject,注意属性名称(区分大小写)和类型均要与Json文件中相对应。以下是与landmarkData.json相对应的DataObject

struct Landmark:Hashable,Codable,Identifiable{
    var id:Int
    var name:String
    var park:String
    var state:String
    var description:String
    
    private var imageName:String
    //image为计算属性
    var image:UIImage{
        Image(imageName)
    }
    
    private var coordinates:Coordinates
    struct Coordinates:Hashable,Codable{
        var latitude:Double
        var longitude:Double
    }
    
    var locationCoordinate:CLLocationCoordinate2D{
        CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longitude)
    }
}

Json文件中的出现的Key不一定要全部在DataObject中声明,但是DataOject中除了计算属性外的属性均要在Json文件中出现(属性名称和类型有一个不匹配就会报错,无法解析)

解析JSON数据

加载Json文件并解析(要求数据对象遵循Codable协议)
相关代码

func load<T:Decodable>(_ filename:String)->T{
    let data:Data
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)else{
        fatalError("Couldn't find \(filename) in main bundle.")
    }
    
    do{
        data = try Data(contentsOf: file)
    }catch{
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }
    
    do{
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    }catch{
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}
Last modification:September 4th, 2023 at 10:12 pm
If you think my article is useful to you, please feel free to appreciate