在 Swift 3 中将数据保存到 .plist 文件

0 arrays xcode ios swift swift3

我已成功将数据从 plist 文件读取到表视图中。现在,我只想知道如何添加另一个带有字符串“名称”和“位置”的“项目”。

我正在寻找的是一种发送字符串以保存为新“项目”的“名称”或“位置”的方法。例如,如果我单击一个按钮,输入的信息将存储在新“项目”下的 plist 文件中。

有人能帮助我朝正确的方向前进吗?如果是你,你会怎么做?

我正在使用 Swift 3 和 Xcode 8.2.1

这是我的 .plist 文件: 在此处输入图像描述

这是我用来获取“项目”的“名称”和“位置”的代码,以便我可以将其插入表视图中:

struct SavedTracks {

    let name: String
    let location: String
}

extension SavedTracks {
    enum ErrorType: Error {
        case noPlistFile
        case cannotReadFile
    }

    /// Load all the elements from the plist file
    static func loadFromPlist() throws -> [SavedTracks] {
        // First we need to find the plist
        guard let file = Bundle.main.path(forResource: "SkiTracks", ofType: "plist") else {
            throw ErrorType.noPlistFile
        }

        // Then we read it as an array of dict
        guard let array = NSArray(contentsOfFile: file) as? [[String: AnyObject]] else {
            throw ErrorType.cannotReadFile
        }

        // Initialize the array
        var elements: [SavedTracks] = []

        // For each dictionary
        for dict in array {
            // We implement the element
            let element = SavedTracks.from(dict: dict)
            // And add it to the array
            elements.append(element)
        }

        // Return all elements
        return elements
    }

    /// Create an element corresponding to the given dict
    static func from(dict: [String: AnyObject]) -> SavedTracks {
        let name = dict["name"] as! String
        let location = dict["location"] as! String


        return SavedTracks(name: name,
                           location: location)
    }
}
Run Code Online (Sandbox Code Playgroud)

Cry*_*ppo 5

这是读取和写入 plist 的辅助结构:

用法 :

//Reading :
let rootArray = PlistFile(named: "PlistFilename")?.array
let rootDictionary = PlistFile(named: "PlistFilename")?.dictionary

//Writing :

if let plistFile = PlistFile(named : "UserData") {
  plistFile.array = yourArray
}

//or :

try? PlistFile(named : "UserData")?.write(yourArray)
Run Code Online (Sandbox Code Playgroud)

代码 :

struct PlistFile {

    enum PlistError: Error {
        case failedToWrite
        case fileDoesNotExist
    }

    let name:String

    var sourcePath:String? {
        return Bundle.main.path(forResource: name, ofType: "plist")
    }

    var destPath:String? {
        if let _ = sourcePath {
            let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            return (dir as NSString).appendingPathComponent("\(name).plist")
        } else {
            return nil
        }
    }

    var dictionary : [String:Any]? {
        get{
            return getDictionary()
        }
        set{
            if let newDict = newValue {
                try? write(dictionary: newDict)
            }
        }
    }

    var array : [Any]? {
        get{
            return getArray()
        }
        set{
            if let newArray = newValue {
                try? write(array: newArray)
            }
        }
    }

    private let fileManager = FileManager.default

    init?(named :String) {
        self.name = named

        guard let source = sourcePath, let destination = destPath, fileManager.fileExists(atPath: source)  else {
            return nil
        }

        if !fileManager.fileExists(atPath: destination) {
            do {
                try fileManager.copyItem(atPath: source, toPath: destination)
            } catch let error {
                print("Unable to copy file. ERROR: \(error.localizedDescription)")
                return nil
            }
        }
    }


    private func getDictionary() -> [String:Any]? {
        guard let destPath = self.destPath, fileManager.fileExists(atPath: destPath) else {
            return nil
        }
        return NSDictionary(contentsOfFile: destPath) as? [String:Any]
    }

    private func getArray() -> [Any]? {
        guard let destPath = self.destPath, fileManager.fileExists(atPath: destPath) else {
            return nil
        }
        return NSArray(contentsOfFile: destPath) as? [Any]
    }

    func write(dictionary : [String:Any]) throws{
        guard let destPath = self.destPath, fileManager.fileExists(atPath: destPath) else {
            throw PlistError.fileDoesNotExist
        }

        if !NSDictionary(dictionary: dictionary).write(toFile: destPath, atomically: false) {
            print("Failed to write the file")
            throw PlistError.failedToWrite
        }
    }

    func write(array : [Any] ) throws {
        guard let destPath = self.destPath, fileManager.fileExists(atPath: destPath) else {
            throw PlistError.fileDoesNotExist
        }

        if !NSArray(array: array).write(toFile: destPath, atomically: false) {
            print("Failed to write the file")
            throw PlistError.failedToWrite
        }
    }


}
Run Code Online (Sandbox Code Playgroud)