0

I'm trying to write a simple Dictionary to a .plist file in swift. I have written the code in an extension of the Dictionary class, for convenience. Here's what it looks like.

extension Dictionary {
    func writeToPath (path: String) {
        do {
            // archive data
            let data = try NSKeyedArchiver.archivedData(withRootObject: self,
                                                    requiringSecureCoding: true)
            // write data
            do {
                let url = URL(string: path)
                try data.write(to: url!)
            }
            catch {
                print("Failed to write dictionary data to disk.")
            }
        }
        catch {
            print("Failed to archive dictionary.")
        }
    }
}

Every time I run this I see "Failed to write dictionary data to disk." The path is valid. I'm using "/var/mobile/Containers/Data/Application/(Numbers and Letters)/Documents/favDict.plist".

The dictionary is type Dictionary<Int, Int>, and contains only [0:0] (for simplicity/troubleshooting purposes).

Why doesn't this work? Do you have a better solution for writing the dictionary to disk?

Build
  • 80
  • 8
  • Can you show how you are creating the path url? You can't just use a hard-coded path since your app's sandbox has an unpredictable path. You need to use `NSFileManager` to get your app's documents directory – Paulw11 Jan 08 '22 at 21:46

1 Answers1

1

URL(string is the wrong API. It requires that the string starts with a scheme like https://.

In the file system where paths starts with a slash you must use

let url = URL(fileURLWithPath: path)

as WithPath implies.

A swiftier way is PropertyListEncoder

extension Dictionary where Key: Encodable, Value: Encodable {
    func writeToURL(_ url: URL) throws {
        // archive data
        let data = try PropertyListEncoder().encode(self)
        try data.write(to: url)
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • tbf the distinction between path/url/string is not particularly clear. Given that part of the URL is called a path, I can see why people that are new to the platform get confused – Alexander Jan 08 '22 at 21:50
  • That was indeed the problem yes. Stumped by path vs url again. Thanks! – Build Jan 08 '22 at 21:56
  • Just to add to the post if your path starts with `file://` it is ok to use the string initializer – Leo Dabus Jan 08 '22 at 22:54