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?
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 .
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.
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
}
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.
In dieser Antwort werden statt NSDictionary native Objekte von Swift verwendet.
//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"] ?? ""
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.
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"])
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.
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")
}
}
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").
kann es tatsächlich in einer Zeile machen
var dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Config", ofType: "plist"))
Ü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
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>
in meinem Fall erstelle ich eine NSDictionary
mit dem NamenappSettings
und 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 {
}
}
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.
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?
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
}
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)
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")
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")
}
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)
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.
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
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)"
}
}
}
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
}
}
}