2014-11-29 24 views
11

Esistono limitazioni nella scrittura di NSDictionaries nei file in swift. Sulla base di ciò che ho imparato da api docs e this stackoverflow answer, i tipi di chiave dovrebbero essere NSString, e anche i tipi di valore dovrebbero essere di tipo NSx, e Int, String e altri tipi di swift potrebbero non funzionare. La domanda è che se ho un dizionario come: Dictionary<Int, Dictionary<Int, MyOwnType>>, come posso scriverlo/leggerlo in/da un file plist in swift?Scrittura del dizionario swift su file

risposta

21

In ogni caso, quando si desidera memorizzare MyOwnType su file, MyOwnType deve essere una sottoclasse di NSObject ed è conforme alle NSCoding protocollo. in questo modo:

class MyOwnType: NSObject, NSCoding { 

    var name: String 

    init(name: String) { 
     self.name = name 
    } 

    required init(coder aDecoder: NSCoder) { 
     name = aDecoder.decodeObjectForKey("name") as? String ?? "" 
    } 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(name, forKey: "name") 
    } 
} 

Poi, ecco il Dictionary:

var dict = [Int : [Int : MyOwnType]]() 
dict[1] = [ 
    1: MyOwnType(name: "foobar"), 
    2: MyOwnType(name: "bazqux") 
] 

Così, ecco che arriva la tua domanda:

Scrivendo dizionario veloce su file

Puoi utilizzare NSKeyedArchiver per scrivere e NSKeyedUnarchiver per leggere:

func getFileURL(fileName: String) -> NSURL { 
    let manager = NSFileManager.defaultManager() 
    let dirURL = manager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false, error: nil) 
    return dirURL!.URLByAppendingPathComponent(fileName) 
} 

let filePath = getFileURL("data.dat").path! 

// write to file 
NSKeyedArchiver.archiveRootObject(dict, toFile: filePath) 

// read from file 
let dict2 = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as [Int : [Int : MyOwnType]] 

// here `dict2` is a copy of `dict` 

Ma nel corpo della tua domanda:

come posso scrivere/leggere a/da un plist file in rapida?

Infatti, NSKeyedArchiverformat is binary plist. Ma se si vuole che il dizionario come valore di plist, è possibile serializzare Dictionary-NSData con NSKeyedArchiver:

// archive to data 
let dat:NSData = NSKeyedArchiver.archivedDataWithRootObject(dict) 

// unarchive from data 
let dict2 = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [Int : [Int : MyOwnType]] 
+0

Grazie mille per la tua risposta dettagliata e grande. Sono nuovo di swift e iOS dev e mi ha aiutato a capire anche le cose correlate :) – AKH

+0

questo scrive un sacco di entità al plist –