Search code examples
swift3ios10nskeyedunarchiver

NSKeyedArchiver.unarchiveObject Swift 3 iOS 10


I've been searching for an answer for this question but I couldn't find any, the similar ones don't have an answer at all. Basically, I want to save data with NSKeyedUnarchiver.archiveRootObject() and load it with .unarchiveObject(withFile). It was working fine with Swift 2.3, now it crashes saying that the unarchive part always gets back nil. I also check for the file if it exists and it does. I really have no idea what's going on. This is the loading procedure:

func loadnotifs(_ username:String)->[AFNotificationData]{
    let ArchiveURL = Constants.DocumentsDirectory.appendingPathComponent(username)
        print("loading " + ArchiveURL.path)
    if FileManager.default.fileExists(atPath: ArchiveURL.path) {
        let unarchived = NSKeyedUnarchiver.unarchiveObject(withFile: ArchiveURL.path) as? [AFNotificationData]
        if unarchived != nil {
            return  NSKeyedUnarchiver.unarchiveObject(withFile: ArchiveURL.path) as! [AFNotificationData]
        } else {
            return []
        }
    }
    else {
        return []
    }

}

and this is the saving:

func savenotifs(_ username:String){
    if username != "" {
        let ArchiveURL = Constants.DocumentsDirectory.appendingPathComponent(username)
        print("saving " + ArchiveURL.path)
       }

        let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(AFDatabase.sharedDatabase.notificationList, toFile: ArchiveURL.path)
        if !isSuccessfulSave {
            print("Failed to save notifs")
        }

    }
}

but in the end I always get "fatal error: unexpectedly found nil while unwrapping an Optional value"


Solution

  • I was looking in the wrong place. Actually the saving and loading procedures are fine, the problem is the required init needed to comply the NSCoding protocol: I was using

    aDecoder.decodeObject(forKey:xxx) as! Bool
    

    instead of the new

    aDecoder.decodeBool(forKey:xxx)
    

    Giving the fact that it was changed automatically by the swift 2.3->3 converter using the wrong command, watch out for this!

    Moreover, watch out because this command is not compatible with booleans/integers from swift 2.3.