Arrays 将plist读入特定类型
使用此选项时:Arrays 将plist读入特定类型,arrays,swift,types,properties,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"
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>
但是,在申报时:
class City {
var icao: String
var name: String
// is this init() necessary?
init(icao: String, name: String) {
self.icao = icao
self.name = name
}
}
以及:
最后,我想使用:
// 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
[[String:String]]
是字典
数组的一种类型。但是,您的City
类只是一个包含两个String
对象的对象,而不是字典
类型。所以你不能投
let cities: [City] = {
guard let URL = Bundle.main.url(forResource: "cities", withExtension: "plist") else {
return []
}
var cities = [City]()
let myCites = NSArray(contentsOf: URL) as! [[String : String]]
for city in myCites {
cities.append(City(icao: city["icao"], name: city["name"]))
}
return cities
}()
不,没有内置的方法将plist数据直接转换为
城市
对象的数组。你需要自己去做
像现在一样加载plist。然后迭代该数组,得到每个小字典。提取这两个值并使用当前的init
创建一个City
实例,或者添加一个新的init
,该实例使用字典并让City
类自行设置
最后,您将使用迭代原始plist数组时创建的每个City
实例构建一个新数组
将所有这些功能包装到一个
Cities
类中可能是有意义的,该类知道如何读写plist文件,并使用City
实例列表。您可能会向类添加其他适当的逻辑来处理城市列表。这不会按原样编译,因为city[“someKey”]
返回一个可选值,但city init
方法不接受optionals。这是city
的定义。如果city[“someKey”]
是可选的,您应该定义someKey:String?
更好的方法是,安全地从字典中打开值,因为city init的参数不应该是可选的。请尝试在这里学习。你说城市不是一种类型,它是一种阶级。从Apple docs的值和引用类型:。。。第二个是“引用类型”,实例共享数据的一个副本,类型通常定义为类。
看到这一点,你还说城市不是一个类型吗?是的,它是一个引用类型
,这意味着它引用的是对象
。另外,我更新了上面的描述。关于您在上面的评论“更好,安全地展开…”,请评论编辑(新增在OP底部)不要用答案编辑您的问题。它否定了你问题的全部观点。
let city: City = cities[indexPath.row]
cell.icaoLabel?.text = city.icao
cell.airportNameLabel?.text = city.name
let cities: [City] = {
guard let URL = Bundle.main.url(forResource: "cities", withExtension: "plist") else {
return []
}
var cities = [City]()
let myCites = NSArray(contentsOf: URL) as! [[String : String]]
for city in myCites {
cities.append(City(icao: city["icao"], name: city["name"]))
}
return cities
}()