Xcode NSInvalidUnarchiveOperationException when trying to unpack a file

This is the error with xcode:

Application terminated due to uncaught exception "NSInvalidUnarchiveOperationException", reason: "*** - [NSKeyedUnarchiver decodeInt64ForKey:]: value for key (rating) is not an integer"

This is part of the class for creating the Meal object:

// MARK: Properties

var rating: Int
var name: String
var photo: UIImage?

      

// MARK: Path

static let DocumentDirectory = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains:.UserDomainMask).first!

static let ArchivelUrl = DocumentDirectory.URLByAppendingPathComponent("meals")

      

// MARK: NSCoding

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(name, forKey: propertyKey.nameKey)
    aCoder.encodeObject(photo, forKey: propertyKey.photoKey)
    aCoder.encodeInteger(rating, forKey: propertyKey.ratingKey)

}
required convenience init?(coder aDecoder: NSCoder) {
    let name = aDecoder.decodeObjectForKey(propertyKey.nameKey) as! String
    let photo = aDecoder.decodeObjectForKey(propertyKey.photoKey) as? UIImage
    let rating = aDecoder.decodeIntegerForKey(propertyKey.ratingKey)
    //must call to designate initiallizer 
    self.init(name: name,photo: photo,rating: rating)
}

      

and this is an archiver and an unarchiver:

// MARK: NSCoding

func saveMeal(){
    let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile:Meal.ArchivelUrl.path!)

    if !isSuccessfulSave {
        print("Failed to save")
    }
    else{
        print("saved")
    }
}

 func loadMeal() -> [Meal]? {
  return NSKeyedUnarchiver.unarchiveObjectWithFile(Meal.ArchivelUrl.path!) as [Meal] }

      

I followed this tutorial on apple site: [ https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson10.html

The sample project worked. I tried to copy the code into my project files and it worked too. So I think there is a difference here!

+3


source to share


3 answers


The problem I solved by replacing the following code:

let rating = aDecoder.decodeIntegerForKey(propertyKey.ratingKey)
to
let rating = aDecoder.decodeObjectForKey(propertyKey.ratingKey) as! Int

      



I think you have already compiled and stored the rating as an object instead of Integer, so when you decode the object as Integer it will tell you that the object is not Integer (the reason why the compiler doesn't know what the type of the object is)

Or you can print Meal.ArchivelUrl.path!

and delete the existing meal.text

and delete the application in your simulator and then Compile your code that you posted here again. I think it will be good (at least great for me).

+15


source


Ok So I finally solved the problem. When a value optional

was obtained, encoding was obtained while storing the value. And since the fast encoding function does not raise any warning, even if odd values ​​are passed to a function that is only meant to accept an integer.

The solution is to encode the value Int

with !

.



Check out my class for more details. Note that Permission

both Office

are classes.

class User : NSObject, NSCoding {
    var bio : String! = ""
    var careerLevel : Int! = 0

    var office : Office!
    var permissions : Array<Permission>!

    init (userDetail:Dictionary<String, Any>) {
        super.init()

        //set values
        self.setValues(detail: userDetail)
    }

    func setValues(detail:Dictionary<String, Any>)  {
        if let value = detail["hash_token"] as? String {self.accessToken = value}

        //now get user detail
        if var information = detail["user_details"] as? Dictionary<String, Any> {
            if let value = information["bio"] {self.bio = String(describing: value)}
            if let value = information["career_level"]  {self.careerLevel = Int(String.init(describing: value))!}

            //set office information
            if let officeDictionary = information["office_detail"] as? Dictionary<String, Any> {
                let office_ = Office.init(detail: officeDictionary, id: officeId)
                self.office = office_
            }

            //now set permission information
            if self.permissions != nil {self.permissions.removeAll(); self.permissions = nil}
            self.permissions = Array<Permission>()
            if  let permissionArray = information["permissions"] as? Array<Any>{
                for permissionDictionary in permissionArray {
                    let permission : Permission = Permission.init(detail: permissionDictionary as! Dictionary<String, Any>)
                    self.permissions.append(permission)
                }
            }
        }
    }

    required init(coder decoder: NSCoder) {
        //Error here "missing argument for parameter name in call
        self.bio = decoder.decodeObject(forKey: "bio") as! String
        self.careerLevel = decoder.decodeInteger(forKey: "careerLevel")

        //
        self.office = decoder.decodeObject(forKey: "office") as! Office
        self.permissions = decoder.decodeObject(forKey: "permissions") as! Array<Permission>

        super.init()
    }

    func encode(with aCoder: NSCoder) {
        //
        aCoder.encode(self.bio!, forKey: "bio")
        aCoder.encode(self.careerLevel!, forKey:"careerLevel")

        //
        aCoder.encode(self.office!, forKey: "office")
        aCoder.encode(self.permissions!, forKey: "permissions")
    }
}

      

+6


source


This GitHub issue suggests it can be fixed Hardware > Erase all Content and Settings

from within the Simulator app

0


source







All Articles