[英]Swift 5: How to read variables in plist files?
I searched a way (or a template) how to read variables which are stored in plist files.我搜索了一种方式(或模板)如何读取存储在 plist 文件中的变量。 I saw a few codes, but no code worked with the newest Swift version.
我看到了一些代码,但没有代码适用于最新的 Swift 版本。
I'm new to Swift, I actually don't check exactly how it works.. Could anyone be so nice and give me an example?我是 Swift 的新手,实际上我并没有确切地检查它是如何工作的。谁能这么好给我举个例子?
I have a CollectionView and want to display the strings in my plist file.我有一个 CollectionView 并想在我的 plist 文件中显示字符串。 That's my plist file:
那是我的 plist 文件:
For every animal key (dictionary type) two sub keys (name and picture).对于每个动物键(字典类型)两个子键(名称和图片)。 Root --> Animals --> Animals1
根 --> 动物 --> Animals1
All Keys expept "name" and "picture" are dictionaries.所有 Keys exppt "name" 和 "picture" 都是字典。 Now I want to get the dictionaries and show the name and the picture in my collection view.
现在我想获取字典并在我的收藏视图中显示名称和图片。 Later I will add more vars.
稍后我将添加更多变量。 I hope it's understandable:'D
我希望这是可以理解的:'D
The incomplete code I have:我的不完整代码:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let path = Bundle.main.path(forResource: "Animals", ofType:"plist")!
let dict = NSDictionary(contentsOfFile: path)
SortData = dict!.object(forKey: "Animals") as! [Dictionary]
}
Your property list format is not very convenient.您的属性列表格式不是很方便。 As you want an array anyway create the property list with an array for key
animals
(and name all keys lowercased)因为你想要一个数组,无论如何创建一个带有关键
animals
数组的属性列表(并将所有键命名为小写)
<?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">
<dict>
<key>animals</key>
<array>
<dict>
<key>name</key>
<string>Tiger</string>
<key>picture</key>
<string>tiger_running</string>
</dict>
<dict>
<key>name</key>
<string>Jaguar</string>
<key>picture</key>
<string>jaguar_sleeping</string>
</dict>
</array>
</dict>
</plist>
Then create two structs然后创建两个结构体
struct Root : Decodable {
let animals : [Animal]
}
struct Animal : Decodable {
let name, picture : String
}
and the data source array和数据源数组
var animals = [Animal]()
And decode the stuff并解码这些东西
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let url = Bundle.main.url(forResource: "Animals", withExtension:"plist")!
do {
let data = try Data(contentsOf: url)
let result = try PropertyListDecoder().decode(Root.self, from: data)
self.animals = result.animals
} catch { print(error) }
}
PropertyListDecoder
and PropertyListSerialization
are state of the art in Swift. PropertyListDecoder
和PropertyListSerialization
是 Swift 中最先进的。 The NSDictionary/NSArray
API is objective-c-ish and outdated. NSDictionary/NSArray
API 是客观的和过时的。
You could use PropertyListSerialization or NSDictionary as you have done.您可以像以前一样使用 PropertyListSerialization 或 NSDictionary。 Here most probably you have gone wrong due to some other reason.
在这里,您很可能由于其他原因而出错。
class ViewController: UIViewController {
var animals = [String: Any]()
override func viewDidLoad() {
super.viewDidLoad()
fetchAnimals() // or fetchPropertyListAnimals()
fetchPropertyListAnimals()
}
func fetchAnimals() {
guard let path = Bundle.main.path(forResource: "Animals", ofType: "plist") else {
print("Path not found")
return
}
guard let dictionary = NSDictionary(contentsOfFile: path) else {
print("Unable to get dictionary from path")
return
}
if let animals = dictionary.object(forKey: "Animals") as? [String: Any] {
self.animals = animals
} else {
print("Unable to find value for key named Animals")
}
}
func fetchPropertyListAnimals() {
var propertyListFormat = PropertyListSerialization.PropertyListFormat.xml
guard let path = Bundle.main.path(forResource: "Animals", ofType: "plist") else {
print("Path not found")
return
}
guard let data = FileManager.default.contents(atPath: path) else {
print("Unable to get data from path")
return
}
do {
if let animals = try PropertyListSerialization.propertyList(from: data, options: .mutableContainersAndLeaves, format: &propertyListFormat) as? [String: Any] {
self.animals = animals
} else {
print("Unable to find value for key named Animals")
}
} catch {
print("Error reading plist: \(error), format: \(propertyListFormat)")
}
}
}
/*
//Use: let plistData = Bundle().parsePlist(ofName: "Your-Plist-Name")
---------- OR ---------
guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
let myDict = NSDictionary(contentsOfFile: path) else {
return nil
}
let value = myDict.value(forKey: "CLIENT_ID") as! String?
*/
extension Bundle {
func parsePlist(ofName name: String) -> [String: AnyObject]? {
// check if plist data available
guard let plistURL = Bundle.main.url(forResource: name, withExtension: "plist"),
let data = try? Data(contentsOf: plistURL)
else { return nil }
// parse plist into [String: Anyobject]
guard let plistDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: AnyObject] else {
return nil
}
return plistDictionary
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.