将plist读入特定类型

时间:2017-03-16 02:24:03

标签: arrays swift types properties

使用时:

let cities: [[String : String]] = {
    guard let URL = Bundle.main.url(forResource: "cities", withExtension: "plist") else {
        return []
    }
    return NSArray(contentsOf: URL) as! [[String : String]]
}()

来自:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>name</key>
        <string>Allentown, PA</string>
        <key>icao</key>
        <string>ABE</string>
    </dict>
    ....
</array>
</plist>

以后可以使用以下方法轻松访问这些值:

    // inside tableView(_ cellForRowAt:)
    city = cities[indexPath.row]
    cell.icaoLabel?.text = city["icao"]
    cell.nameLabel?.text = city["name"]

但是,在声明时:

class City {
    var icao: String
    var name: String

    // is this init() necessary?
    init(icao: String, name: String) {
        self.icao = icao
        self.name = name
    }
}

let cities: [City] = {
    guard let URL = Bundle.main.url(forResource: "cities", withExtension: "plist") else {
        return []
    }
    // ** No longer works
    return NSArray(contentsOf: URL) as! [City]
    // ** Doesn't work either
    return NSArray(contentsOf: URL)
}()

最终,我想使用:

    // inside tableView(_cellForRowAt:)
    city = cities[indexPath.row]
    cell icaoLabel?.text = city.icao
    cell nameLabel?.text = city.name

这是如何实现的?可以用这种方式进口plist吗?

编辑城市类

class City {
    var icao: String?
    var name: String?

    init(icao: String, name: String) {
        self.icao = icao
        self.name = name
    }

    static func loadCities() -> [City] {
        guard let URL = Bundle.main.url(forResource: "cities", withExtension: "plist") else {
            return []
        }
        let tempCities = NSArray(contentsOf: URL) as! [[String : String]]

        // now, create the desired cities array
        var cities = [City]()
        for city in tempCities {
            guard let icaoTemp = city["icao"], let nameTemp = city["name"] else {
                break
            }
            cities.append(City(icao: icaoTemp, name: nameTemp))
        }

        return cities
    }
}

访问值:

    let city: City = cities[indexPath.row]
    cell.icaoLabel?.text = city.icao
    cell.airportNameLabel?.text = city.name

2 个答案:

答案 0 :(得分:1)

( (0, a[0]), (1, a[1]) , (2, a[2]), ...)是一种[[String: String]]数组。但是,您的dictionary类只是一个包含两个City对象的对象,它不是String类型。所以你不能施展它。

dictionary

答案 1 :(得分:1)

不,没有内置的方法可以将plist数据直接转换为./processchecker.sh '/usr/sbin/mysqld' ./processchecker.sh '[/usr/sbin/]mysqld' (i tried using square brackets using online suggestions but failed) 个对象的数组。你需要自己做。

像现在一样加载plist。然后迭代该数组获取每个小字典。要么提取这两个值并使用当前的City创建一个City实例,要么添加一个新的init来获取字典并让init类自行设置。

最后,在迭代原始plist数组时,使用您创建的每个City实例构建一个新数组。

将所有这些功能包装到City类中可能是有意义的,该类知道如何读取和写入plist文件并使用Cities实例列表。您最终可能会在课程中添加其他适当的逻辑以使用城市列表。