Swift - 核心数据和 NSCoding:无法调用指定的初始化程序
Swift - Core Data & NSCoding : Failed to call designated initializer
我在 Swift 中遇到以下情况:
我有一个名为 Event 的 NSManaged class:
import UIKit
import Foundation
import CoreData
class Event: NSManagedObject, NSCoding {
@NSManaged var eventArchived: Bool
@NSManaged var eventCCRecipientAddress: String?
@NSManaged var eventCCRecipientName: String?
@NSManaged var eventEndDate: String?
@NSManaged var eventEndRSVPDateTime: String?
@NSManaged var eventHappeningId: String?
@NSManaged var eventName: String?
@NSManaged var eventResourcesFolderName: String?
@NSManaged var eventStartDate: String?
@NSManaged var eventId: String?
@NSManaged var eventHappening: Happening
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
// MARK: NSCoding protocol conformance
required init(coder aDecoder: NSCoder) {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: context)!
// Note: pass `nil` to `insertIntoManagedObjectContext`
super.init(entity: entity, insertIntoManagedObjectContext: nil)
if let eventArchived = aDecoder.decodeObjectForKey("eventArchived") as? Bool {
self.eventArchived = eventArchived
}
if let eventCCRecipientAddress = aDecoder.decodeObjectForKey("eventCCRecipientAddress") as? String {
self.eventCCRecipientAddress = eventCCRecipientAddress
}
if let eventCCRecipientName = aDecoder.decodeObjectForKey("eventCCRecipientName") as? String {
self.eventCCRecipientName = eventCCRecipientName
}
if let eventEndDate = aDecoder.decodeObjectForKey("eventEndDate") as? String {
self.eventEndDate = eventEndDate
}
if let eventEndRSVPDateTime = aDecoder.decodeObjectForKey("eventEndRSVPDateTime") as? String {
self.eventEndRSVPDateTime = eventEndRSVPDateTime
}
if let eventHappeningId = aDecoder.decodeObjectForKey("eventHappeningId") as? String {
self.eventHappeningId = eventHappeningId
}
if let eventName = aDecoder.decodeObjectForKey("eventName") as? String {
self.eventName = eventName
}
if let eventResourcesFolderName = aDecoder.decodeObjectForKey("eventResourcesFolderName") as? String {
self.eventResourcesFolderName = eventResourcesFolderName
}
if let eventStartDate = aDecoder.decodeObjectForKey("eventStartDate") as? String {
self.eventStartDate = eventStartDate
}
if let eventId = aDecoder.decodeObjectForKey("eventId") as? String {
self.eventId = eventId
}
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(eventArchived, forKey: "eventArchived")
if let eventCCRecipientAddress = self.eventCCRecipientAddress {
aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
}
if let eventCCRecipientName = self.eventCCRecipientName {
aCoder.encodeObject(eventCCRecipientName, forKey: "eventCCRecipientName")
}
if let eventEndDate = self.eventEndDate {
aCoder.encodeObject(eventEndDate, forKey: "eventEndDate")
}
if let eventEndRSVPDateTime = self.eventEndRSVPDateTime {
aCoder.encodeObject(eventEndRSVPDateTime, forKey: "eventEndRSVPDateTime")
}
if let eventCCRecipientAddress = self.eventCCRecipientAddress {
aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
}
if let eventHappeningId = self.eventHappeningId {
aCoder.encodeObject(eventHappeningId, forKey: "eventHappeningId")
}
if let eventName = self.eventName {
aCoder.encodeObject(eventName, forKey: "eventName")
}
if let eventResourcesFolderName = self.eventResourcesFolderName {
aCoder.encodeObject(eventResourcesFolderName, forKey: "eventResourcesFolderName")
}
if let eventStartDate = self.eventStartDate {
aCoder.encodeObject(eventStartDate, forKey: "eventStartDate")
}
if let eventId = self.eventId {
aCoder.encodeObject(eventId, forKey: "eventId")
}
aCoder.encodeObject(eventHappening, forKey: "eventHappening")
}
}
class 曾经是 "simple" 只有 NSManaged 变量,直到我被要求实现 NSCoding 协议。我使用 NSCoding 是因为我需要在我的应用程序的任何地方了解当前事件,包括离线模式。
当我尝试使用我的事件 Class 时,我一直出现以下错误:
CoreData: error: Failed to call designated initializer on NSManagedObject class 'AccueilInviteVIP.Event'
这就是我尝试访问我的 class 的方式:
var currentEvent = Event()
然后在viewDidLoad方法中:
// currentEvent
currentEvent = NSEntityDescription.insertNewObjectForEntityForName("Event", inManagedObjectContext: self.managedObjectContext!) as! Event
它在这条线上崩溃了。
错误应该很清楚,似乎我的 init 方法不正确但我无法让它工作,因为我是 Swift 的新手并且找不到任何接近此的示例。
任何帮助都会很棒!
谢谢,
雨果
对我来说,这看起来像是过度工程化和太多的代码。
为什么不只存储 eventId 并从核心数据中检索对象?还要归档它看起来真的很乱和多余。
// store
NSUserDefaults.standardUserDefaults().setObject(event.eventId forKey:"mainEventID")
// retrieve
let eventId = NSUserDefaults.standardUserDefaults().stringForKey("mainEventId")!
let request = NSFetchRequest(entityName: "Event")
request.predicate = NSPredicate(format: "eventId = %@", eventId)
let event = (context.executeFetchRequest(request, error:nil) as [Event]).first!
您将不得不做更多的错误并 nil
检查,但您明白了。
我在 Swift 中遇到以下情况:
我有一个名为 Event 的 NSManaged class:
import UIKit
import Foundation
import CoreData
class Event: NSManagedObject, NSCoding {
@NSManaged var eventArchived: Bool
@NSManaged var eventCCRecipientAddress: String?
@NSManaged var eventCCRecipientName: String?
@NSManaged var eventEndDate: String?
@NSManaged var eventEndRSVPDateTime: String?
@NSManaged var eventHappeningId: String?
@NSManaged var eventName: String?
@NSManaged var eventResourcesFolderName: String?
@NSManaged var eventStartDate: String?
@NSManaged var eventId: String?
@NSManaged var eventHappening: Happening
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
// MARK: NSCoding protocol conformance
required init(coder aDecoder: NSCoder) {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: context)!
// Note: pass `nil` to `insertIntoManagedObjectContext`
super.init(entity: entity, insertIntoManagedObjectContext: nil)
if let eventArchived = aDecoder.decodeObjectForKey("eventArchived") as? Bool {
self.eventArchived = eventArchived
}
if let eventCCRecipientAddress = aDecoder.decodeObjectForKey("eventCCRecipientAddress") as? String {
self.eventCCRecipientAddress = eventCCRecipientAddress
}
if let eventCCRecipientName = aDecoder.decodeObjectForKey("eventCCRecipientName") as? String {
self.eventCCRecipientName = eventCCRecipientName
}
if let eventEndDate = aDecoder.decodeObjectForKey("eventEndDate") as? String {
self.eventEndDate = eventEndDate
}
if let eventEndRSVPDateTime = aDecoder.decodeObjectForKey("eventEndRSVPDateTime") as? String {
self.eventEndRSVPDateTime = eventEndRSVPDateTime
}
if let eventHappeningId = aDecoder.decodeObjectForKey("eventHappeningId") as? String {
self.eventHappeningId = eventHappeningId
}
if let eventName = aDecoder.decodeObjectForKey("eventName") as? String {
self.eventName = eventName
}
if let eventResourcesFolderName = aDecoder.decodeObjectForKey("eventResourcesFolderName") as? String {
self.eventResourcesFolderName = eventResourcesFolderName
}
if let eventStartDate = aDecoder.decodeObjectForKey("eventStartDate") as? String {
self.eventStartDate = eventStartDate
}
if let eventId = aDecoder.decodeObjectForKey("eventId") as? String {
self.eventId = eventId
}
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(eventArchived, forKey: "eventArchived")
if let eventCCRecipientAddress = self.eventCCRecipientAddress {
aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
}
if let eventCCRecipientName = self.eventCCRecipientName {
aCoder.encodeObject(eventCCRecipientName, forKey: "eventCCRecipientName")
}
if let eventEndDate = self.eventEndDate {
aCoder.encodeObject(eventEndDate, forKey: "eventEndDate")
}
if let eventEndRSVPDateTime = self.eventEndRSVPDateTime {
aCoder.encodeObject(eventEndRSVPDateTime, forKey: "eventEndRSVPDateTime")
}
if let eventCCRecipientAddress = self.eventCCRecipientAddress {
aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
}
if let eventHappeningId = self.eventHappeningId {
aCoder.encodeObject(eventHappeningId, forKey: "eventHappeningId")
}
if let eventName = self.eventName {
aCoder.encodeObject(eventName, forKey: "eventName")
}
if let eventResourcesFolderName = self.eventResourcesFolderName {
aCoder.encodeObject(eventResourcesFolderName, forKey: "eventResourcesFolderName")
}
if let eventStartDate = self.eventStartDate {
aCoder.encodeObject(eventStartDate, forKey: "eventStartDate")
}
if let eventId = self.eventId {
aCoder.encodeObject(eventId, forKey: "eventId")
}
aCoder.encodeObject(eventHappening, forKey: "eventHappening")
}
}
class 曾经是 "simple" 只有 NSManaged 变量,直到我被要求实现 NSCoding 协议。我使用 NSCoding 是因为我需要在我的应用程序的任何地方了解当前事件,包括离线模式。
当我尝试使用我的事件 Class 时,我一直出现以下错误:
CoreData: error: Failed to call designated initializer on NSManagedObject class 'AccueilInviteVIP.Event'
这就是我尝试访问我的 class 的方式:
var currentEvent = Event()
然后在viewDidLoad方法中:
// currentEvent
currentEvent = NSEntityDescription.insertNewObjectForEntityForName("Event", inManagedObjectContext: self.managedObjectContext!) as! Event
它在这条线上崩溃了。
错误应该很清楚,似乎我的 init 方法不正确但我无法让它工作,因为我是 Swift 的新手并且找不到任何接近此的示例。
任何帮助都会很棒!
谢谢,
雨果
对我来说,这看起来像是过度工程化和太多的代码。
为什么不只存储 eventId 并从核心数据中检索对象?还要归档它看起来真的很乱和多余。
// store
NSUserDefaults.standardUserDefaults().setObject(event.eventId forKey:"mainEventID")
// retrieve
let eventId = NSUserDefaults.standardUserDefaults().stringForKey("mainEventId")!
let request = NSFetchRequest(entityName: "Event")
request.predicate = NSPredicate(format: "eventId = %@", eventId)
let event = (context.executeFetchRequest(request, error:nil) as [Event]).first!
您将不得不做更多的错误并 nil
检查,但您明白了。