Guardar datos en .plist archivo en Swift

Estoy tratando de guardar datos en un archivo plist en swift, pero los datos no se muestran ya que se guardaron cuando se lee el plist. Este es el código que estaba usando.

var documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString var path : NSString = documentsDirectory.stringByAppendingPathComponent("data.plist") var data : NSMutableDictionary = NSMutableDictionary(contentsOfFile: path) data.setObject(self.object, forKey: "key") data.writeToFile(path, atomically: true) 

Editar: He oído que la mejor manera de hacerlo es escribir en el directorio de documentos, por lo que mi pregunta sería ¿cómo debo escribir en un archivo en ese directorio?

Aparentemente, el archivo no está en una ubicación de escritura, así que lo creé en el directorio de documentos.

 var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String var path = paths.stringByAppendingPathComponent("data.plist") var fileManager = NSFileManager.defaultManager() if (!(fileManager.fileExistsAtPath(path))) { var bundle : NSString = NSBundle.mainBundle().pathForResource("data", ofType: "plist") fileManager.copyItemAtPath(bundle, toPath: path, error:nil) } data.setObject(object, forKey: "object") data.writeToFile(path, atomically: true) 

Luego, debe leerse en el directorio de documentos.

 var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String var path = paths.stringByAppendingPathComponent("data.plist") let save = NSDictionary(contentsOfFile: path) 

Swift 3:

 func loadData() { let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray let documentDirectory = paths[0] as! String let path = documentDirectory.appending("myData.plist") let fileManager = FileManager.default if(!fileManager.fileExists(atPath: path)){ if let bundlePath = Bundle.main.path(forResource: "myData", ofType: "plist"){ let result = NSMutableDictionary(contentsOfFile: bundlePath) print("Bundle file myData.plist is -> \(result?.description)") do{ try fileManager.copyItem(atPath: bundlePath, toPath: path) }catch{ print("copy failure.") } }else{ print("file myData.plist not found.") } }else{ print("file myData.plist already exits at path.") } let resultDictionary = NSMutableDictionary(contentsOfFile: path) print("load myData.plist is ->\(resultDictionary?.description)") let myDict = NSDictionary(contentsOfFile: path) if let dict = myDict{ myItemValue = dict.object(forKey: myItemKey) as! String? txtValue.text = myItemValue }else{ print("load failure.") } } 

Leer y escribir archivo plist en swift

Use writeToFile: options: error: y vea lo que dice el error:

 var error: NSError? var bytes = NSKeyedArchiver.archivedDataWithRootObject(data) if !bytes.writeToFile(path, options: nil, error: &error) { if let actualError = error { println(actualError) } } 

código swift actualizado de Rebeloper:

 let BedroomFloorKey = "BedroomFloor" let BedroomWallKey = "BedroomWall" var bedroomFloorID: AnyObject = 101 var bedroomWallID: AnyObject = 101 func saveGameData() { let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray let documentsDirectory = paths.objectAtIndex(0) as! NSString let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist") let dict: NSMutableDictionary = ["XInitializerItem": "DoNotEverChangeMe"] //saving values dict.setObject(bedroomFloorID, forKey: BedroomFloorKey) dict.setObject(bedroomWallID, forKey: BedroomWallKey) //... //writing to GameData.plist dict.writeToFile(path, atomically: false) let resultDictionary = NSMutableDictionary(contentsOfFile: path) print("Saved GameData.plist file is --> \(resultDictionary?.description)") self.loadGameData() }//eom func loadGameData() { // getting path to GameData.plist let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray let documentsDirectory = paths[0] as! NSString let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist") // let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist") let fileManager = NSFileManager.defaultManager() //check if file exists if(!fileManager.fileExistsAtPath(path)) { // If it doesn't, copy it from the default file in the Bundle if let bundlePath = NSBundle.mainBundle().pathForResource("GameData", ofType: "plist") { let resultDictionary = NSMutableDictionary(contentsOfFile: bundlePath) print("Bundle GameData.plist file is --> \(resultDictionary?.description)") do { try fileManager.copyItemAtPath(bundlePath, toPath: path) print("copy") } catch _ { print("error failed loading data") } } else { print("GameData.plist not found. Please, make sure it is part of the bundle.") } } else { print("GameData.plist already exits at path.") // use this to delete file from documents directory //fileManager.removeItemAtPath(path, error: nil) } let resultDictionary = NSMutableDictionary(contentsOfFile: path) print("Loaded GameData.plist file is --> \(resultDictionary?.description)") let myDict = NSDictionary(contentsOfFile: path) if let dict = myDict { //loading values bedroomFloorID = dict.objectForKey(BedroomFloorKey)! bedroomWallID = dict.objectForKey(BedroomWallKey)! //... } else { print("WARNING: Couldn't create dictionary from GameData.plist! Default values will be used!") } }//eom 
 struct Plist { enum PlistError: ErrorType { case FileNotWritten case FileDoesNotExist } let name:String var sourcePath:String? { guard let path = NSBundle.mainBundle().pathForResource(name, ofType: "plist") else { return .None } return path } var destPath:String? { guard sourcePath != .None else { return .None } let dir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] return (dir as NSString).stringByAppendingPathComponent("\(name).plist") } init?(name:String) { self.name = name let fileManager = NSFileManager.defaultManager() guard let source = sourcePath else { return nil } guard let destination = destPath else { return nil } guard fileManager.fileExistsAtPath(source) else { return nil } if !fileManager.fileExistsAtPath(destination) { do { try fileManager.copyItemAtPath(source, toPath: destination) } catch let error as NSError { print("Unable to copy file. ERROR: \(error.localizedDescription)") return nil } } } func getValuesInPlistFile() -> NSDictionary?{ let fileManager = NSFileManager.defaultManager() if fileManager.fileExistsAtPath(destPath!) { guard let dict = NSDictionary(contentsOfFile: destPath!) else { return .None } return dict } else { return .None } } func getMutablePlistFile() -> NSMutableDictionary?{ let fileManager = NSFileManager.defaultManager() if fileManager.fileExistsAtPath(destPath!) { guard let dict = NSMutableDictionary(contentsOfFile: destPath!) else { return .None } return dict } else { return .None } } func addValuesToPlistFile(dictionary:NSDictionary) throws { let fileManager = NSFileManager.defaultManager() if fileManager.fileExistsAtPath(destPath!) { if !dictionary.writeToFile(destPath!, atomically: false) { print("File not written successfully") throw PlistError.FileNotWritten } } else { throw PlistError.FileDoesNotExist } } } 

Ahora, implemente a continuación en su controlador de vista.

  if let plist = Plist(name: "plist file name") { let dict = plist.getMutablePlistFile()! dict["key"] = value do { try plist.addValuesToPlistFile(dict) } catch { print(error) } print(plist.getValuesInPlistFile()) } else { print("Unable to get Plist") }