web-dev-qa-db-de.com

Wie bekomme ich eine Liste als Wörterbuch in Swift?

Ich spiele mit der neuen Programmiersprache Swift von Apple herum und habe einige Probleme ...

Momentan versuche ich eine plist-Datei zu lesen. In Objective-C würde ich Folgendes tun, um den Inhalt als NSDictionary zu erhalten:

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

Wie bekomme ich eine Liste als Wörterbuch in Swift?

Ich gehe davon aus, dass ich den Weg zur Plist finden kann:

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

Wenn dies funktioniert (Wenn es richtig ist): Wie bekomme ich den Inhalt als Wörterbuch?

Auch eine allgemeinere Frage:

Ist es in Ordnung, die Standardklassen NS * zu verwenden? Ich denke schon ... oder fehlt mir etwas? Soweit ich weiß, sind die Standard-Framework-Klassen NS * noch gültig und in Ordnung?

164
Sebastian

In Swift 3.0 Lesen von 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)")
        }
    }

Lesen Sie mehr WIE VERWENDEN SIE EIGENSCHAFTENLISTEN (.PLIST) IN SCHNELLER .

32
Ashok R

Sie können weiterhin NSD-Wörterbücher in Swift verwenden:

Für Swift 4

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

Für Swift 3+

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

Und ältere Versionen von 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
}

Die NSClasses sind immer noch verfügbar und können in Swift problemlos verwendet werden. Ich denke, dass sie den Fokus wahrscheinlich bald auf Swift verlagern wollen, aber momentan verfügen die Swift-APIs nicht über die gesamte Funktionalität der Kern-NSClasses.

239
Connor

So mache ich, wenn ich eine .plist in ein Swift-Wörterbuch umwandeln möchte: 

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

Für Swift 2.0 bearbeitet:

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

Für Swift 3.0 bearbeitet:

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

Schnell 4.0

Sie können jetzt das Decodable-Protokoll verwenden, um eine .plist in eine benutzerdefinierte Struktur zu decodieren. Ich werde ein grundlegendes Beispiel durchgehen. Für kompliziertere .plist-Strukturen empfehle ich Decodable/Encodable (eine gute Ressource ist hier: https://benscheirman.com/2017/06/Swift-json/ ) .

Richten Sie zuerst Ihre Struktur in das Format Ihrer .plist-Datei ein. In diesem Beispiel werde ich eine .plist mit einem Root-Level-Dictionary und 3 Einträgen betrachten: 1 Zeichenkette mit Schlüssel "name", 1 Int mit Schlüssel "age" und 1 Boolean mit Schlüssel "single". Hier ist die Struktur:

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

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

Einfach genug. Nun der coole Teil. Mit der PropertyListDecoder-Klasse können Sie die .plist-Datei problemlos in eine Instantiierung dieser Struktur einordnen:

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

Nicht viel mehr Code, über den man sich sorgen müsste, und alles in Swift. Besser noch, wir haben jetzt eine Instantiierung der Config-Struktur, die wir leicht verwenden können: 

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

Dies gibt den Wert für die Schlüssel "Name", "Alter" und "Einzelne" in der .plist aus.

29
ekreloff

In dieser Antwort werden statt NSDictionary native Objekte von Swift verwendet. 

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.

Ich habe mit Swift 3.0 gearbeitet und wollte eine Antwort auf die aktualisierte Syntax liefern. Darüber hinaus und möglicherweise noch wichtiger verwende ich das PropertyListSerialization -Objekt, um das schwere Anheben durchzuführen. Dies ist viel flexibler als die Verwendung des NSDictionary, da ein Array als Stammtyp der Plist zulässig ist.

Unten sehen Sie einen Screenshot der von mir verwendeten Liste. Es ist ein wenig kompliziert, um die verfügbare Leistung anzuzeigen, dies funktioniert jedoch für jede zulässige Kombination von Plist-Typen.

 Sample plist file Wie Sie sehen, verwende ich ein Array von String: String-Wörterbüchern, um eine Liste mit Websitenamen und der entsprechenden URL zu speichern.

Wie oben erwähnt verwende ich das PropertyListSerialization -Objekt, um das schwere Anheben für mich auszuführen. Darüber hinaus wurde Swift 3.0 "Swifty", so dass alle Objektnamen das Präfix "NS" verloren haben.

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)

Nach der Ausführung des obigen Codes wird plist vom Typ Array<AnyObject> sein, aber wir wissen, um welchen Typ es sich wirklich handelt, sodass wir ihn in den richtigen Typ umwandeln können:

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

Und jetzt können wir auf die verschiedenen Eigenschaften unseres String-Arrays zugreifen: String-Wörterbücher auf natürliche Weise. Hoffentlich in wirklich stark typisierte Strukturen oder Klassen umwandeln;)

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

Es ist am besten, native Wörterbücher und Arrays zu verwenden, da sie für die Verwendung mit Swift optimiert wurden. Davon abgesehen, können Sie in Swift NS ... -Klassen verwenden, und ich denke, dass diese Situation dies rechtfertigt. So würden Sie es umsetzen:

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

Bisher (meiner Meinung nach) ist dies der einfachste und effizienteste Weg, um auf eine plist zuzugreifen, aber in der Zukunft erwarte ich, dass Apple in native Wörterbücher mehr Funktionalität (z. B. plist) hinzufügt.

8
67cherries

Swift - Lesen/Schreiben von Plist und Textdatei ....

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: Zugriff auf Info.Plist

Ich habe ein Wörterbuch namens CoachMarksDictionary mit einem booleschen Wert in Info.Plist. Ich möchte auf den bool-Wert zugreifen und ihn wahr machen.

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

Schreiben auf die Plist:

Aus einer benutzerdefinierten Pliste: - (Aus Datei-Neue-Datei-Ressourcen-Eigenschaftsliste erstellen. Drei Zeichenfolgen mit dem Namen DashBoard_New, DashBoard_Draft, DashBoard_Completed) hinzugefügt.

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

Die Methode kann als aufgerufen werden 

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

kann es tatsächlich in einer Zeile machen 

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

Über Nick's Antwort in eine Komforterweiterung umgewandelt:

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

verwendungszweck:

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

Ich wäre bereit zu wetten, dass es auch funktionieren würde, eine ähnliche Erweiterung für Arrays zu erstellen

4
mredig

Sie können plist in Swift Language auf folgende Weise lesen:

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

Einzelwörterbuch lesen:

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

Wenn Sie ein mehrdimensionales Wörterbuch in plist erhalten möchten:

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

Hier ist die 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

in meinem Fall erstelle ich eine NSDictionary mit dem NamenappSettingsund füge alle benötigten Schlüssel hinzu. Für diesen Fall lautet die Lösung:

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
}

Der einfachste Weg dazu ist meiner Meinung nach.

2
quemeful

Hier ist eine etwas kürzere Version, basierend auf der Antwort von @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

Sie können das verwenden, ich erstelle eine einfache Erweiterung für Dictionary in 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
    }
}

Und Sie können das zum Laden verwenden

/**
  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

Ich habe einen einfachen Dictionary-Initialisierer erstellt, der NSDictionary(contentsOfFile: path) ersetzt. Entfernen Sie einfach die 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
    }

}

Sie können es wie folgt verwenden:

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

Schritt 1 : Einfache und schnellste Möglichkeit, plist in Swift 3+ zu analysieren

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

Schritt 2: Verwendung:

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

Swift 4.0 iOS 11.2.6 Liste analysiert und Code analysiert, basierend auf https://stackoverflow.com/users/3647770/ashok-r answer oben.

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

Da diese Antwort noch nicht verfügbar ist, möchten Sie nur darauf hinweisen, dass Sie die infoDictionary -Eigenschaft verwenden können, um die Info-Liste als Wörterbuch zu erhalten, Bundle.main.infoDictionary.

Obwohl etwas wie Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) kann schneller sein, wenn Sie nur an einem bestimmten Element in der Info-Liste interessiert sind.

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

Ich verwende Swift-Wörterbücher, konvertiere sie jedoch in und aus NSD-Wörterbüchern in meiner Datei-Manager-Klasse:

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

Dies scheint die am wenigsten störende Art zu lesen und zu schreiben, aber der Rest meines Codes bleibt so schnell wie möglich.

0
e.w. parris

Hier ist die Lösung, die ich gefunden habe:

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

Ich habe den Typ von test auf AnyObject gesetzt, um eine Warnung vor unerwarteten Inferenzen auszuschalten.

Es muss auch in einer Klassenmethode ausgeführt werden.

So greifen Sie auf einen bestimmten Wert eines bekannten Typs zu und speichern ihn:

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

Plist ist ein einfaches, schnelles Enum, das ich für das Arbeiten mit Eigenschaftslisten erstellt habe.

// load an applications info.plist data

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

Mehr Beispiele:

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 selbst ist ziemlich einfach, hier ist seine Auflistung, falls Sie direkt darauf verweisen möchten.

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

wenn Sie ein "2-dimensionales Array" aus .plist lesen möchten, können Sie es wie folgt versuchen:

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