简体   繁体   中英

Writing swift dictionary to file

There are limitations with writing NSDictionaries into files in swift. Based on what I have learned from api docs and this stackoverflow answer , key types should be NSString, and value types also should be NSx type, and Int, String, and other swift types might not work. The question is that if I have a dictionary like: Dictionary<Int, Dictionary<Int, MyOwnType>> , how can I write/read it to/from a plist file in swift?

Anyway, when you want to store MyOwnType to file, MyOwnType must be a subclass of NSObject and conforms to NSCoding protocol. like this:

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

Then, here is the Dictionary :

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

So, here comes your question:

Writing swift dictionary to file

You can use NSKeyedArchiver to write, and NSKeyedUnarchiver to read:

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`

But in the body of your question:

how can I write/read it to/from a plist file in swift?

In fact, NSKeyedArchiver format is binary plist . But if you want that dictionary as a value of plist , you can serialize Dictionary to NSData with NSKeyedArchiver :

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

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

Response for Swift 5

private func getFileURL(fileName: String) throws -> URL {
        let manager = FileManager.default
        let dirURL = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        return dirURL.appendingPathComponent(fileName)
 }

 if let filePath = try? getFileURL(fileName: "data.dat").path {
        NSKeyedArchiver.archiveRootObject(data, toFile: filePath)
 }

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