1

I'm trying to save my struct array. And I read all posts I could find for this topic. Finally I used one example and stripped it a little bit, but it doesn't work. It does not save, so it could not read back:

    func path() -> String {
        return URL(fileURLWithPath: "/Volumes/MacOS/fasttemp/Test.TXT").absoluteString
    }

    struct Movie {
        let name: String
        let releaseYear: Int
    }

    protocol Dictionariable {
        func dictionaryRepresentation() -> NSDictionary
        init?(dictionaryRepresentation: NSDictionary?)
    }

    extension Movie: Dictionariable {
        func dictionaryRepresentation() -> NSDictionary {
            let representation: [String: AnyObject] = [
                "name": name as AnyObject,
                "releaseYear": releaseYear as AnyObject
            ]
            return representation as NSDictionary
        }

        init?(dictionaryRepresentation: NSDictionary?) {
            guard let values = dictionaryRepresentation else {return nil}
            if let name = values["name"] as? String,
                let releaseYear = values["releaseYear"] as? Int {
                self.name = name
                self.releaseYear = releaseYear
            } else {
                return nil
            }
        }
    }

    func extractStructureFromArchive<T: Dictionariable>() -> T? {
        guard let encodedDict = NSKeyedUnarchiver.unarchiveObject(withFile: path()) as? NSDictionary else {return nil}
        return T(dictionaryRepresentation: encodedDict)
    }

    func archiveStructure<T: Dictionariable>(structure: T) {
        let encodedValue = structure.dictionaryRepresentation()
        NSKeyedArchiver.archiveRootObject(encodedValue, toFile: path())
    }

    func extractStructuresFromArchive<T: Dictionariable>() -> [T] {
        guard let encodedArray = NSKeyedUnarchiver.unarchiveObject(withFile: path()) as? [AnyObject] else {return []}
        return encodedArray.map{$0 as? NSDictionary}.flatMap{T(dictionaryRepresentation: $0)}
    }

    func archiveStructureInstances<T: Dictionariable>(structures: [T]) {
        let encodedValues = structures.map{$0.dictionaryRepresentation()}
        NSKeyedArchiver.archiveRootObject(encodedValues, toFile: path())
    }

    let movies = [
        Movie(name: "Avatar", releaseYear: 2009),
        Movie(name: "The Dark Knight", releaseYear: 2008)
    ]

    // this fails!
    archiveStructureInstances(structures: movies)

    let someArray: [Movie] = extractStructuresFromArchive()

    print("\(someArray[0].name)")

No file is created. The folder exist. What's wrong with it? I'm using XCode 8.2.1 with Swift 3.

Added: I took this example from another question/answer. I also reduced it from 3 to 2 struct members. And I updated it for Swift 3. But it still doesn't work! That's the reason I'm asking.

shallowThought
  • 19,212
  • 9
  • 65
  • 112
Peter Silie
  • 825
  • 1
  • 11
  • 16
  • Possible duplicate of [archive array of optional structs with NSCoding in Swift?](http://stackoverflow.com/questions/25311098/archive-array-of-optional-structs-with-nscoding-in-swift) – shallowThought Jan 25 '17 at 14:42
  • (see above): I took this example from that question/answer. I also reduced it from 3 to 2 struct members. And I updated it for Swift 3. But it still doesn't work! That's the reason I'm asking. – Peter Silie Jan 25 '17 at 17:20

1 Answers1

1

Your path is wrong. You do not archive to a file. You have to use a directory.

Changing the path() methode to this (from this answer):

func path() -> String {
    let documentsPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
    let path = documentsPath! + "/Movie"
    return path
}

your code prints Avatar as expected.

Community
  • 1
  • 1
shallowThought
  • 19,212
  • 9
  • 65
  • 112