web-dev-qa-db-fra.com

Comment obtenir un plist en tant que dictionnaire dans Swift?

Je m'amuse avec le nouveau langage de programmation Swift d'Apple et j'ai quelques problèmes ...

Actuellement, j'essaie de lire un fichier plist. Dans Objective-C, je ferais ce qui suit pour obtenir le contenu en tant que NSDictionary:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];

Comment obtenir un plist en tant que dictionnaire dans Swift?

Je suppose que je peux obtenir le chemin du plist avec:

let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")

Quand cela fonctionne (si c'est correct?): Comment puis-je obtenir le contenu en tant que dictionnaire?

Aussi une question plus générale:

Est-il possible d’utiliser les classes NS * par défaut? Je pense que oui ... ou est-ce que je manque quelque chose? Autant que je sache, le framework par défaut NS * est-il toujours valide et utilisable?

164
Sebastian

Dans Swift 3.0 Lecture depuis Plist.

func readPropertyList() {
        var propertyListForamt =  PropertyListSerialization.PropertyListFormat.xml //Format of the Property List.
        var plistData: [String: AnyObject] = [:] //Our data
        let plistPath: String? = Bundle.main.path(forResource: "data", ofType: "plist")! //the path of the data
        let plistXML = FileManager.default.contents(atPath: plistPath!)!
        do {//convert the data to a dictionary and handle errors.
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListForamt) as! [String:AnyObject]

        } catch {
            print("Error reading plist: \(error), format: \(propertyListForamt)")
        }
    }

Lire Plus COMMENT UTILISER LES LISTES DE PROPRIÉTÉS (.PLIST) DANS Swift .

32
Ashok R

Vous pouvez toujours utiliser NSDictionaries dans Swift:

Pour Swift 4

 var nsDictionary: NSDictionary?
 if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
    nsDictionary = NSDictionary(contentsOfFile: path)
 }

Pour Swift 3+

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
   let myDict = NSDictionary(contentsOfFile: path){
    // Use your myDict here
}

Et les anciennes versions de Swift

var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
    myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
    // Use your dict here
}

Les NSClasses sont toujours disponibles et parfaitement utilisables dans Swift. Je pense qu'ils vont probablement vouloir se concentrer bientôt sur Swift, mais pour le moment, les API Swift ne disposent pas de toutes les fonctionnalités des NSClasses de base.

239
Connor

Voici ce que je fais si je veux convertir une liste .plist en dictionnaire Swift: 

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
  if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
    // use Swift dictionary as normal
  }
}

Édité pour Swift 2.0:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
    // use Swift dictionary as normal
}

Edité pour Swift 3.0:

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
        // use Swift dictionary as normal
}
137
pheedsta

Swift 4.0

Vous pouvez maintenant utiliser le protocole Decodable pour décoder une .plist dans une structure personnalisée. Je vais donner un exemple élémentaire, pour les structures .plist plus compliquées, je recommande de lire Decodable/Encodable (une bonne ressource est ici: https://benscheirman.com/2017/06/Swift-json/ ) .

Commencez par configurer votre structure au format de votre fichier .plist. Pour cet exemple, considérons une liste .plist avec un dictionnaire de niveau racine et 3 entrées: 1 chaîne avec la clé "name", 1 int avec la clé "age" et 1 booléen avec la clé "single". Voici la structure:

struct Config: Decodable {
    private enum CodingKeys: String, CodingKey {
        case name, age, single
    }

    let name: String
    let age: Int
    let single: Bool
}

Assez simple. Maintenant la partie cool. En utilisant la classe PropertyListDecoder, nous pouvons facilement analyser le fichier .plist dans une instanciation de cette structure:

func parseConfig() -> Config {
    let url = Bundle.main.url(forResource: "Config", withExtension: "plist")!
    let data = try! Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try! decoder.decode(Config.self, from: data)
}

Pas beaucoup plus de code à craindre, et tout est dans Swift. Mieux encore, nous avons maintenant une instanciation de la structure de configuration que nous pouvons facilement utiliser: 

let config = parseConfig()
print(config.name) 
print(config.age)
print(config.single) 

Ceci imprime la valeur des clés "name", "age" et "single" dans la liste .plist.

29
ekreloff

Cette réponse utilise des objets natifs Swift plutôt que NSDictionary. 

Swift 3.0

//get the path of the plist file
guard let plistPath = Bundle.main.path(forResource: "level1", ofType: "plist") else { return }
//load the plist as data in memory
guard let plistData = FileManager.default.contents(atPath: plistPath) else { return }
//use the format of a property list (xml)
var format = PropertyListSerialization.PropertyListFormat.xml
//convert the plist data to a Swift Dictionary
guard let  plistDict = try! PropertyListSerialization.propertyList(from: plistData, options: .mutableContainersAndLeaves, format: &format) as? [String : AnyObject] else { return }
//access the values in the dictionary 
if let value = plistDict["aKey"] as? String {
  //do something with your value
  print(value)
}
//you can also use the coalesce operator to handle possible nil values
var myValue = plistDict["aKey"] ?? ""
20
Tommie C.

Je travaillais avec Swift 3.0 et je voulais apporter une réponse à la syntaxe mise à jour. De plus, et peut-être plus important encore, j’utilise l’objet PropertyListSerialization pour faire le gros du travail, ce qui est beaucoup plus souple que le simple NSDictionary car il permet à Array de constituer le type de racine du plist.

Vous trouverez ci-dessous une capture d'écran du plist que j'utilise. C'est un petit} compliqué, afin de montrer la puissance disponible, mais cela fonctionnera pour toute combinaison autorisée de types de plist.

 Sample plist file Comme vous pouvez le constater, j'utilise un tableau de dictionnaires String: String pour stocker une liste de noms de sites Web et leur URL correspondante.

J'utilise l'objet PropertyListSerialization, comme mentionné ci-dessus, pour faire le gros du travail pour moi. De plus, Swift 3.0 est devenu plus "Swifty" et tous les noms d'objet ont perdu le préfixe "NS".

let path = Bundle.main().pathForResource("DefaultSiteList", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

Après que le code ci-dessus s'exécute, la variable plist sera de type Array<AnyObject>, mais nous savons de quel type il s'agit vraiment afin de pouvoir le transtyper au type correct:

let dictArray = plist as! [[String:String]]
// [[String:String]] is equivalent to Array< Dictionary<String, String> >

Et maintenant, nous pouvons accéder aux différentes propriétés de notre Array of String: String Dictionnaires de manière naturelle. Espérons les convertir en structures ou classes fortement typées;)

print(dictArray[0]["Name"])
16
Nick

Il est préférable d'utiliser des dictionnaires et des tableaux natifs, car ils ont été optimisés pour une utilisation avec Swift. Cela dit, vous pouvez utiliser des cours NS ... à Swift et je pense que cette situation le justifie. Voici comment vous le mettriez en œuvre:

var path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")
var dict = NSDictionary(contentsOfFile: path)

Jusqu'à présent (à mon avis), c'est le moyen le plus simple et le plus efficace d'accéder à un plist, mais à l'avenir, je pense qu'Apple ajoutera davantage de fonctionnalités (comme l'utilisation de plist) dans les dictionnaires natifs.

8
67cherries

Swift - Lecture/écriture de pliste et fichier texte ....

override func viewDidLoad() {
    super.viewDidLoad()

    let fileManager = (NSFileManager .defaultManager())
    let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

    if (directorys != nil){
        let directories:[String] = directorys!;
        let dictionary = directories[0]; //documents directory


        //  Create and insert the data into the Plist file  ....
        let plistfile = "myPlist.plist"
        var myDictionary: NSMutableDictionary = ["Content": "This is a sample Plist file ........."]
        let plistpath = dictionary.stringByAppendingPathComponent(plistfile);

        if !fileManager .fileExistsAtPath(plistpath){//writing Plist file
            myDictionary.writeToFile(plistpath, atomically: false)
        }
        else{            //Reading Plist file
            println("Plist file found")

            let resultDictionary = NSMutableDictionary(contentsOfFile: plistpath)
            println(resultDictionary?.description)
        }


        //  Create and insert the data into the Text file  ....
        let textfile = "myText.txt"
        let sampleText = "This is a sample text file ......... "

        let textpath = dictionary.stringByAppendingPathComponent(textfile);
        if !fileManager .fileExistsAtPath(textpath){//writing text file
            sampleText.writeToFile(textpath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
        } else{
            //Reading text file
            let reulttext  = String(contentsOfFile: textpath, encoding: NSUTF8StringEncoding, error: nil)
            println(reulttext)
        }
    }
    else {
        println("directory is empty")
    }
}
8
Nithin Sathyan

Swift 2.0: Accéder à Info.Plist

J'ai un dictionnaire nommé CoachMarksDictionary avec une valeur booléenne dans Info.Plist. Je veux accéder à la valeur bool et la rendre vraie.

let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  if let CoachMarksDict = dict["CoachMarksDictionary"] {
       print("Info.plist : \(CoachMarksDict)")

   var dashC = CoachMarksDict["DashBoardCompleted"] as! Bool
    print("DashBoardCompleted state :\(dashC) ")
  }

Écrire à la pliste:

Depuis une liste personnalisée: - (Créer à partir d'un fichier, d'un nouveau fichier, d'une ressource, d'une liste de propriétés, de trois propriétés nommées: DashBoard_New, DashBoard_Draft, DashBoard_Completed)

func writeToCoachMarksPlist(status:String?,keyName:String?)
 {
  let path1 = NSBundle.mainBundle().pathForResource("CoachMarks", ofType: "plist")
  let coachMarksDICT = NSMutableDictionary(contentsOfFile: path1!)! as NSMutableDictionary
  var coachMarksMine = coachMarksDICT.objectForKey(keyName!)

  coachMarksMine  = status
  coachMarksDICT.setValue(status, forKey: keyName!)
  coachMarksDICT.writeToFile(path1!, atomically: true)
 }

La méthode peut être appelée comme 

self.writeToCoachMarksPlist(" true - means user has checked the marks",keyName: "the key in the CoachMarks dictionary").
8
A.G

peut réellement le faire en 1 ligne 

    var dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Config", ofType: "plist"))
4
KennyVB

Converti en une extension pratique via la réponse de Nick:

extension Dictionary {
    static func contentsOf(path: URL) -> Dictionary<String, AnyObject> {
        let data = try! Data(contentsOf: path)
        let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

        return plist as! [String: AnyObject]
    }
}

usage:

let path = Bundle.main.path(forResource: "plistName", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let dict = Dictionary<String, AnyObject>.contentsOf(path: url)

Je serais prêt à parier que cela fonctionnerait également pour créer une extension similaire pour Arrays

4
mredig

Vous pouvez lire le plist en langue rapide de la manière suivante:

let path = NSBundle.mainBundle().pathForResource("PriceList", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)

Lire la valeur du dictionnaire unique:

let test: AnyObject = dict.objectForKey("index1")

Si vous voulez obtenir un dictionnaire multi-dimensionnel complet dans plist:

let value: AnyObject = dict.objectForKey("index2").objectForKey("date")

Voici le plist:

<plist version="1.0">
<dict>
<key>index2</key>
<dict>
    <key>date</key>
    <string>20140610</string>
    <key>amount</key>
    <string>110</string>
</dict>
<key>index1</key>
<dict>
    <key>amount</key>
    <string>125</string>
    <key>date</key>
    <string>20140212</string>
</dict>
</dict>
</plist>
4
imti

dans mon cas, je crée une NSDictionary appeléeappSettingset j'ajoute toutes les clés nécessaires. Pour ce cas, la solution est:

if let dict = NSBundle.mainBundle().objectForInfoDictionaryKey("appSettings") {
  if let configAppToken = dict["myKeyInsideAppSettings"] as? String {

  }
}
2
jose920405

Swift 3.0

if let path = Bundle.main.path(forResource: "config", ofType: "plist") {
    let dict = NSDictionary(contentsOfFile: path)

    // use dictionary
}

La meilleure façon de faire cela à mon avis.

2
quemeful

Voici une version un peu plus courte, basée sur la réponse de @connor

guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
    let myDict = NSDictionary(contentsOfFile: path) else {
    return nil
}

let value = dict.value(forKey: "CLIENT_ID") as! String?
2
Bence Pattogato

Vous pouvez l'utiliser, je crée une extension simple pour Dictionary dans github https://github.com/DaRkD0G/LoadExtension

extension Dictionary {
    /**
        Load a Plist file from the app bundle into a new dictionary

        :param: File name
        :return: Dictionary<String, AnyObject>?
    */
    static func loadPlistFromProject(filename: String) -> Dictionary<String, AnyObject>? {

        if let path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist") {
            return NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject>
        }
        println("Could not find file: \(filename)")
        return nil
    }
}

Et vous pouvez l'utiliser pour le chargement

/**
  Example function for load Files Plist

  :param: Name File Plist
*/
func loadPlist(filename: String) -> ExampleClass? {
    if let dictionary = Dictionary<String, AnyObject>.loadPlistFromProject(filename) {
        let stringValue = (dictionary["name"] as NSString)
        let intergerValue = (dictionary["score"] as NSString).integerValue
        let doubleValue = (dictionary["transition"] as NSString).doubleValue

        return ExampleClass(stringValue: stringValue, intergerValue: intergerValue, doubleValue: doubleValue)
    }
    return nil
}
2
YannickSteph

J'ai créé un initialiseur Dictionary simple qui remplace NSDictionary(contentsOfFile: path). Supprimez simplement la NS.

extension Dictionary where Key == String, Value == Any {

    public init?(contentsOfFile path: String) {
        let url = URL(fileURLWithPath: path)

        self.init(contentsOfURL: url)
    }

    public init?(contentsOfURL url: URL) {
        guard let data = try? Data(contentsOf: url),
            let dictionary = (try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any]) ?? nil
            else { return nil }

        self = dictionary
    }

}

Vous pouvez l'utiliser comme ceci:

let filePath = Bundle.main.path(forResource: "Preferences", ofType: "plist")!
let preferences = Dictionary(contentsOfFile: filePath)!
UserDefaults.standard.register(defaults: preferences)
2
Jordan H

Étape 1 : Méthode simple et rapide pour analyser le plist dans Swift 3+

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

Étape 2: Comment utiliser:

Bundle().parsePlist(ofName: "Your-Plist-Name")
1
Bhuvan Bhatt

Swift 4.0 iOS 11.2.6 liste analysé et le code à analyser, basé sur https://stackoverflow.com/users/3647770/ashok-r réponse ci-dessus.

<?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>identity</key>
    <string>blah-1</string>
    <key>major</key>
    <string>1</string>
    <key>minor</key>
    <string>1</string>
    <key>uuid</key>
    <string>f45321</string>
    <key>web</key>
    <string>http://web</string>
</dict>
<dict>
    <key>identity</key>
    <string></string>
    <key>major</key>
    <string></string>
    <key>minor</key>
    <string></string>
    <key>uuid</key>
    <string></string>
    <key>web</key>
    <string></string>
  </dict>
</array>
</plist>

do {
   let plistXML = try Data(contentsOf: url)
    var plistData: [[String: AnyObject]] = [[:]]
    var propertyListForamt =  PropertyListSerialization.PropertyListFormat.xml
        do {
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListForamt) as! [[String:AnyObject]]

        } catch {
            print("Error reading plist: \(error), format: \(propertyListForamt)")
        }
    } catch {
        print("error no upload")
    }
0
user3069232

Etant donné que cette réponse n’est pas encore disponible, je voulais simplement indiquer que vous pouvez également utiliser la propriété infoDictionary pour obtenir le répertoire d’information sous forme de dictionnaire, Bundle.main.infoDictionary.

Bien que quelque chose comme Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) puisse soit plus rapide si vous ne vous intéressez qu'à un élément spécifique du plist info.

// Swift 4

// Getting info plist as a dictionary
let dictionary = Bundle.main.infoDictionary

// Getting the app display name from the info plist
Bundle.main.infoDictionary?[kCFBundleNameKey as String]

// Getting the app display name from the info plist (another way)
Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String)
0
Scott Marchant

J'utilise les dictionnaires Swift, mais je les convertis depuis et vers NSDictionaries dans ma classe de gestionnaire de fichiers comme suit:

    func writePlist(fileName:String, myDict:Dictionary<String, AnyObject>){
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = myDict as NSDictionary
        if(thisDict.writeToFile(docPath, atomically: true)){
            NSLog("success")
        } else {
            NSLog("failure")
        }

    }
    func getPlist(fileName:String)->Dictionary<String, AnyObject>{
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = NSDictionary(contentsOfFile: docPath)
        return thisDict! as! Dictionary<String, AnyObject>
    }

Cela semble la façon la moins dérangeante de lire et d’écrire, mais le reste de mon code reste aussi rapide que possible.

0
e.w. parris

Voici la solution que j'ai trouvée:

let levelBlocks = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("LevelBlocks", ofType: "plist"))
let test: AnyObject = levelBlocks.objectForKey("Level1")
println(test) // Prints the value of test

J'ai défini le type de test sur AnyObject pour faire taire un avertissement concernant une inférence inattendue pouvant se produire.

En outre, cela doit être fait dans une méthode de classe.

Pour accéder et sauvegarder une valeur spécifique d'un type connu:

let value = levelBlocks.objectForKey("Level1").objectForKey("amount") as Int
println(toString(value)) // Converts value to String and prints it
0
TheAppleMan

Plist est un simple enum Swift que j'ai créé pour travailler avec des listes de propriétés.

// load an applications info.plist data

let info = Plist(NSBundle.mainBundle().infoDictionary)
let identifier = info["CFBundleIndentifier"].string!

Plus d'exemples:

import Plist

// initialize using an NSDictionary
// and retrieve keyed values

let info = Plist(dict)
let name = info["name"].string ?? ""
let age = info["age"].int ?? 0


// initialize using an NSArray
// and retrieve indexed values

let info = Plist(array)
let itemAtIndex0 = info[0].value


// utility initiaizer to load a plist file at specified path
let info = Plist(path: "path_to_plist_file")

// we support index chaining - you can get to a dictionary from an array via
// a dictionary and so on
// don't worry, the following will not fail with errors in case
// the index path is invalid
if let complicatedAccessOfSomeStringValueOfInterest = info["dictKey"][10]["anotherKey"].string {
  // do something
}
else {
  // data cannot be indexed
}

// you can also re-use parts of a plist data structure

let info = Plist(...)
let firstSection = info["Sections"][0]["SectionData"]
let sectionKey = firstSection["key"].string!
let sectionSecret = firstSection["secret"].int!

Plist.Swift

Plist lui-même est assez simple, voici sa liste au cas où vous vous y référeriez directement.

//
//  Plist.Swift
//


import Foundation


public enum Plist {

    case dictionary(NSDictionary)
    case Array(NSArray)
    case Value(Any)
    case none

    public init(_ dict: NSDictionary) {
        self = .dictionary(dict)
    }

    public init(_ array: NSArray) {
        self = .Array(array)
    }

    public init(_ value: Any?) {
        self = Plist.wrap(value)
    }

}


// MARK:- initialize from a path

extension Plist {

    public init(path: String) {
        if let dict = NSDictionary(contentsOfFile: path) {
            self = .dictionary(dict)
        }
        else if let array = NSArray(contentsOfFile: path) {
            self = .Array(array)
        }
        else {
            self = .none
        }
    }

}


// MARK:- private helpers

extension Plist {

    /// wraps a given object to a Plist
    fileprivate static func wrap(_ object: Any?) -> Plist {

        if let dict = object as? NSDictionary {
            return .dictionary(dict)
        }
        if let array = object as? NSArray {
            return .Array(array)
        }
        if let value = object {
            return .Value(value)
        }
        return .none
    }

    /// tries to cast to an optional T
    fileprivate func cast<T>() -> T? {
        switch self {
        case let .Value(value):
            return value as? T
        default:
            return nil
        }
    }
}

// MARK:- subscripting

extension Plist {

    /// index a dictionary
    public subscript(key: String) -> Plist {
        switch self {

        case let .dictionary(dict):
            let v = dict.object(forKey: key)
            return Plist.wrap(v)

        default:
            return .none
        }
    }

    /// index an array
    public subscript(index: Int) -> Plist {
        switch self {
        case let .Array(array):
            if index >= 0 && index < array.count {
                return Plist.wrap(array[index])
            }
            return .none

        default:
            return .none
        }
    }

}


// MARK:- Value extraction

extension Plist {

    public var string: String?       { return cast() }
    public var int: Int?             { return cast() }
    public var double: Double?       { return cast() }
    public var float: Float?         { return cast() }
    public var date: Date?         { return cast() }
    public var data: Data?         { return cast() }
    public var number: NSNumber?     { return cast() }
    public var bool: Bool?           { return cast() }


    // unwraps and returns the underlying value
    public var value: Any? {
        switch self {
        case let .Value(value):
            return value
        case let .dictionary(dict):
            return dict
        case let .Array(array):
            return array
        case .none:
            return nil
        }
    }

    // returns the underlying array
    public var array: NSArray? {
        switch self {
        case let .Array(array):
            return array
        default:
            return nil
        }
    }

    // returns the underlying dictionary
    public var dict: NSDictionary? {
        switch self {
        case let .dictionary(dict):
            return dict
        default:
            return nil
        }
    }

}


// MARK:- CustomStringConvertible

extension Plist : CustomStringConvertible {
    public var description:String {
        switch self {
        case let .Array(array): return "(array \(array))"
        case let .dictionary(dict): return "(dict \(dict))"
        case let .Value(value): return "(value \(value))"
        case .none: return "(none)"
        }
    }
}
0
Benzi

Swift 3.0

si vous voulez lire un "tableau à 2 dimensions" depuis .plist, vous pouvez l'essayer comme ceci:

if let path = Bundle.main.path(forResource: "Info", ofType: "plist") {
    if let dimension1 = NSDictionary(contentsOfFile: path) {
        if let dimension2 = dimension1["key"] as? [String] {
            destination_array = dimension2
        }
    }
}
0
Sandu