2015-03-23 3 views
1

я архивировать массив моей NSCoding соответствующих требований класса «Назначение» в файл в общем (App Groups) контейнер:NSInvalidUnarchiveOperationException подняли только в расширении IOS, а не основное приложение

class private func updateSharedFiles() { 
    let path = NSFileManager().containerURLForSecurityApplicationGroupIdentifier("group.agenda-touch")!.path! + "/widgetData" 
    if let incompleteAssignmentsArray = self.incompleteAssignments { 
     NSKeyedArchiver.archiveRootObject(incompleteAssignmentsArray, toFile: path) 
    } 
} 

Теперь, когда мое расширение хочет прочитать из этого файла, который я назвал NSFileManager.fileExistsAtPath: в файле и он возвращает true. Наконец, я вызываю NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? AssignmentArray и получаю исключение NSInvalidUnarchiveOperationException. Дело в том, что, когда я отформатирую файл в своем основном приложении, я не получаю такого исключения. И чтобы быть ясным, я добавил Assignment.swift в мои компилируемые источники для виджета. Поэтому мой TodayViewController знает, что такое Assignment, но не может его декодировать по какой-то причине. В качестве дополнения, здесь реализация NSCoding для задания:

//MARK: NSCoding 
    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(self.assignmentName, forKey: "assignmentName") 
     aCoder.encodeObject(self.assignmentDueDate, forKey: "assignmentDueDate") 
     aCoder.encodeObject(self.assignmentSubject, forKey: "assignmentSubject") 
     aCoder.encodeBool(self.completed, forKey: "assignmentCompleted") 
     aCoder.encodeObject(self.creationDate, forKey: "assignmentCreationDate") 
     aCoder.encodeInteger(self.assignmentType.rawValue, forKey: "assignmentType") 
     aCoder.encodeBool(self.earmarkedForDeletion, forKey: "assignmentEarmarked") 
     aCoder.encodeObject(self.modificationDates, forKey: "assignmentModificationDates") 
    } 
    required convenience init(coder aDecoder: NSCoder) { 
     let assignmentName = aDecoder.decodeObjectForKey("assignmentName") as String 
     let assignmentDueDate = aDecoder.decodeObjectForKey("assignmentDueDate") as NSDate 
     let assignmentSubject = aDecoder.decodeObjectForKey("assignmentSubject") as String 
     let completed = aDecoder.decodeBoolForKey("assignmentCompleted") 
     self.init(name:assignmentName,dueDate:assignmentDueDate,subject:assignmentSubject,completed:completed) 
     self.creationDate = aDecoder.decodeObjectForKey("assignmentCreationDate") as NSDate 
     let assignmentTypeRaw = aDecoder.decodeIntegerForKey("assignmentType") 
     self.assignmentType = AssignmentType(rawValue: assignmentTypeRaw)! 
     self.earmarkedForDeletion = aDecoder.decodeBoolForKey("assignmentEarmarked") 
     self.modificationDates = aDecoder.decodeObjectForKey("assignmentModificationDates") as Dictionary<String,NSDate> 
    } 

ответ

2

У меня точно такая же проблема. Я попытался удалить и добавить файл в и из источников компиляции. Не работает. Вы нашли решение еще?

Единственное отличие от моей проблемы: я пытаюсь разобрать NSArray объектов xxx. Он работает при архивировании и распаковке в главном приложении или архивировании и распаковке в приложении WatchKit, но не тогда, когда я архивирую его в главном приложении и разархивирую его в приложении WatchKit (и в противном случае).

let defaults: NSUserDefaults = NSUserDefaults(suiteName: "group.name")! 

if let object: NSData = defaults.objectForKey(ArrayKey) as? NSData { 
    if let array: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(object) { 
     return array as NSArray 
    } 
} 

return NSArray() 

Обмен объектами через NSUserDefaults в моей группе приложений работает. Я испытываю эту проблему только с NSKeyedArchiver и NSKeyedUnarchiver NSArray с объектами xxx.

* Нагрузочное приложение из-за неперехваченное исключение 'NSInvalidUnarchiveOperationException', причина: «* - [NSKeyedUnarchiver decodeObjectForKey]: не может декодировать объект класса хого


EDIT: Я решил этот вопрос в что делает мой объект совместимым с NSSecureCoding. Поэтому я заменил

propertyName = aDecoder.decodeObjectForKey("propertyName")

с

propertyName = aDecoder.decodeObjectOfClass(NSString.self, forKey: "propertyName") as NSString

и добавил

class func supportsSecureCoding() -> Bool { 
    return true 
} 

Я также установить ИмяКласса из NSKeyedUnarchiver унд NSKeyedArchiver в applicationFinishLaunchingWithOptions главного приложения и в первом WKInterfaceController в WatchKitApp

NSKeyedArchiver.setClassName("Song", forClass: Song.self) 
    NSKeyedUnarchiver.setClass(Song.self, forClassName: "Song") 
+1

Ждать, я не думаю, что это ответ. – PopKernel

+0

Извините, я не мог комментировать исходный вопрос из-за низкой репутации. :) Я редактировал сообщение, поэтому он может содержать ответ на исходный вопрос. – helkarli

+0

Все, что необходимо, это вызвать 'NSKeyedArchiver.setClassname' и' NSKeyedUnarchiver.setClass'. Принятие «NSSecureCoding» не должно иметь никакого значения. Основная проблема заключается в том, что имя класса сохраняется, включая модуль, а ваше расширение и основное приложение имеют разные имена модулей. – ianthetechie

Смежные вопросы