简体   繁体   中英

write plist file swift

i have a plist file, this file populate a form with settings; when I finish writing each textfield or switch, value is saved correctly, refresh my table correctly and my info its correct. But when i change the screen and return, my plist file is empty, i check several options:

...

let path = NSBundle.mainBundle().pathForResource("perfilBitrubian", ofType: "plist")
descripcionCelda.writeToFile(path!, atomically: false)

or

...
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDirectory = paths.objectAtIndex(0) as! NSString
let path = documentsDirectory.stringByAppendingPathComponent("perfilBitrubian.plist")
descripcionCelda.writeToFile(path!, atomically: false)

My list has hidden options; when i hide and show my table refresh data correctly, but if i change the process and return the form; my plist file don't have info.

i see this examples and I do not know what to do.

http://rebeloper.com/read-write-plist-file-swift/

and this:

http://www.appcoda.com/expandable-table-view/

Thanks!

Several things:

First, your first code block won't work. The app bundle is read-only. Trying to write a file to the bundle will always fail.

Next, property lists can only contain a very small set of objects, all of which must be NSObjects. Do a search on "property list object" in Xcode for more info.

The function writeToFile that you are calling (on a dictionary or array?) returns a Bool. Check the result to see if it's failing.

These are my methods, you have to pass the plist name (without extension), to write also pass the key and a dictionary or an array. The plist is automatically copied to documents directory if not already done before:

public static func plistRead(plistName: String) -> [String: AnyObject]? {

    let path = documentsPath().stringByAppendingPathComponent(plistName + ".plist")

    let fileManager = NSFileManager.defaultManager()
    if !(fileManager.fileExistsAtPath(path)) {
        if let bundlePath = NSBundle.mainBundle().pathForResource(plistName, ofType: "plist") {
            do {
                try fileManager.copyItemAtPath(bundlePath, toPath: path)
            } catch let error as NSError {
                print("Can't move plist from bundle to documents directory: " + error.localizedDescription)
            }
        } else {
            print("No plist found!")
        }
    }
    return NSDictionary(contentsOfFile: path) as? [String: AnyObject]
}

public static func plistWrite(plistName: String, key: String, data: AnyObject?) -> Bool {
    let path = documentsPath().stringByAppendingPathComponent(plistName + ".plist")

    let fileManager = NSFileManager.defaultManager()
    if !(fileManager.fileExistsAtPath(path)) {
        if let bundlePath = NSBundle.mainBundle().pathForResource(plistName, ofType: "plist") {
            do {
                try fileManager.copyItemAtPath(bundlePath, toPath: path)
            } catch let error as NSError {
                print("Can't move plist from bundle to documents directory: " + error.localizedDescription)
                return false
            }
        } else {
            print("No plist found!")
            return false
        }
    }

    if let savedStock = NSMutableDictionary(contentsOfFile: path) {
        if let data = data { savedStock.setObject(data, forKey: key) }
        else { savedStock.removeObjectForKey(key) }

        if savedStock.writeToFile(path, atomically: true) { return true }
        else {
            print("Can't save file at path: \(path)")
            return false
        }
    }
    else {
        print("Can't create dictionary!")
        return false
    }
}

Update swift 3

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 switf

class MainTableViewController: UITableViewController {

//MARK:- Properties
//reading data
var tableData = [String]()
//writing data
var dicData: NSMutableDictionary = ["name" : "data"]


//MARK:- View Life Cycle
override func viewDidLoad() {

    super.viewDidLoad()
    /* converting path to document directory since plist in bundle             can't be modified */

    let documentsDirectory =    NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString

    let path : NSString = documentsDirectory.appendingPathComponent("TableDataPropertyList.plist") as NSString

     /* getting the path and paste the path in finder to see the plist in document directory */

     print(" \(path) ")
     dicData.write(toFile: path as String, atomically: false)

     //path of plist in bundle to read

     let mainPath = Bundle.main.path(forResource: "TableDataPropertyList", ofType: "plist")
     let dict = NSDictionary(contentsOfFile: (mainPath)! as String)
     tableData = dict!.object(forKey: "AppleDevice") as! [String]

}

override func didReceiveMemoryWarning() {

    super.didReceiveMemoryWarning()

}


//MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {

    return 1

}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return tableData.count

}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath as IndexPath)

    cell.textLabel!.text = tableData[indexPath.row]

    return cell

}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM