Swift 5: Как читать переменные в файлах plist? - PullRequest
0 голосов
/ 22 марта 2020

Я искал способ (или шаблон), как читать переменные, которые хранятся в файлах plist. Я видел несколько кодов, но ни один код не работал с последней версией Swift.

Я новичок в Swift, на самом деле я не проверяю, как именно он работает. Может ли кто-нибудь быть таким милым и дать мне пример?

У меня есть CollectionView и я хочу отобразить строки в моем файле plist. Это мой файл plist:

Для каждого ключа животного (тип словаря) две субключи (имя и изображение). Root -> Животные -> Животные1

Все ключи, кроме «name» и «picture», являются словарями. Теперь я хочу получить словари и показать имя и изображение в виде моей коллекции. Позже я добавлю больше переменных. Я надеюсь, что это понятно: 'D

У меня есть неполный код:

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]
}

Ответы [ 2 ]

1 голос
/ 22 марта 2020

Ваш формат списка свойств не очень удобен. В любом случае, если вам нужен массив, создайте список свойств с массивом для ключа 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>

Затем создайте две структуры

struct Root : Decodable {
    let animals : [Animal]
}

struct Animal : Decodable {
    let name, picture : String
}

и данные исходный массив

var animals = [Animal]()

И декодируемые вещи

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 и PropertyListSerialization являются современными в Swift. API NSDictionary/NSArray является объективным - c -i sh и устаревшим.

0 голосов
/ 22 марта 2020

Вы можете использовать PropertyListSerialization или NSDictionary, как вы уже сделали. Здесь, скорее всего, вы ошиблись по какой-то другой причине.

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)")
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...