Save Data to .plist File in Swift

前端 未结 7 1301
一整个雨季
一整个雨季 2020-11-27 18:10

I am trying to save data to a plist file in swift, but the data isn\'t showing up as it was saved when the plist is read. This is the code I was using.

var          


        
相关标签:
7条回答
  • 2020-11-27 18:30
    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
        }
    }
    }
    

    Now, implement below in your view controller.

            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")
            }
    
    0 讨论(0)
  • 2020-11-27 18:36

    From your Information Property List

    Key

      Privacy - Photo Library Additions Usage Description
    

    Type

      String
    

    Value

      "Your App Name" would like to access the photo gallery to manage your profile picture
    
    0 讨论(0)
  • 2020-11-27 18:38

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

    Read and Write plist file in swift

    0 讨论(0)
  • 2020-11-27 18:41

    Apparently the file is not in a writable location, so I created it in the documents directory.

    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)
    

    Then, it has to be read from the documents directory.

    var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
    var path = paths.stringByAppendingPathComponent("data.plist")
    let save = NSDictionary(contentsOfFile: path)
    
    0 讨论(0)
  • 2020-11-27 18:48

    Check in Xcode 10 swift 4.1

    //TODO: for wtite in .plist file
            let docsBaseURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let customPlistURL = docsBaseURL.appendingPathComponent("custom.plist")
            print(customPlistURL.absoluteString)
            let dic:[String:Any] = ["key":"val"]
            // Swift Dictionary To Data.
            do  {
            let data = try PropertyListSerialization.data(fromPropertyList: dic, format: PropertyListSerialization.PropertyListFormat.binary, options: 0)
                do {
                    try data.write(to: customPlistURL, options: .atomic)
                    print("Successfully write")
                }catch (let err){
                    print(err.localizedDescription)
                }
            }catch (let err){
                print(err.localizedDescription)
            }
    
    0 讨论(0)
  • 2020-11-27 18:48

    updated swift code of 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
    
    0 讨论(0)
提交回复
热议问题