Swift 2.0 迁移错误
Swift 2.0 Migration errors
我观看了 WWDC 会议,阅读了关于 Swift 的新程序员书籍,并阅读了我能在 Stack Overflow 上找到的所有相关问题。从 Swift 1.2 迁移到 Swift 2.0.
后,我修复了应用程序中的大部分错误
不过还有一些没解决。
向下转换 AnyObject
错误:
Cannot downcast from '[AnyObject]' to a more optional type '[NSManagedObject]'
代码:
let fetchRequest = NSFetchRequest(entityName: formulaEntity)
var error: NSError?
do {
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]?
if let results = fetchedResults {
stocks = results
} else {
print("Could not fetch \(error), \(error!.userInfo)")
}
} catch {
print("ERROR: \(error)")
}
显示的错误发生在 let fetchedResults = try...
行
我遇到的另一个奇怪错误是在我的 AppDelegate 中:
错误:
'NSMutableDictionary' is not convertible to '[NSObject : AnyObject]'
代码:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("Stocks.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as [NSObject : AnyObject])
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
}
return coordinator
}()
我没有接触过上面的代码。所以我不知道为什么没有通过 Apple 的迁移工具正确迁移。
我的 AppDelegate 中的另一个错误:
Binary operator '&&' cannot be applied to two Bool operands
Call can throw, but it is not marked with 'try' and the error is not handled.
代码:
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save() {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
同样,我还没有触及 AppDelegate 的这一部分,并且不确定上面的代码究竟有什么问题。
Cannot downcast from '[AnyObject]' to a more optional type '[NSManagedObject]'
在 Swift 1.2 中,executeFetchRequest(:_)
returned [AnyObject]?
。在 Swift 2 中,它 returns [AnyObject]
因为新的 try
... 语法 returns 是非可选的。
(如果该方法会 return nil
,则该方法根本不会 return,并且控制会移至 catch
块。)
'NSMutableDictionary' is not convertible to '[NSObject : AnyObject]'
这意味着您正试图将无法转换为 Objective-C 对象的内容插入到 NSMutableDictionary
中。在你的情况下,我认为这是因为 error
是一个符合 ErrorType
的结构,而不是 NSError
对象。请尝试添加 error1
。
Call can throw, but it is not marked with 'try' and the error is not handled.
save()
可能会抛出错误,因此需要使用 try
执行它,而不是将其计算为 bool
。正如 Martin R. 在评论中指出的那样, 的答案提供了一个完整的解决方案,所以我不会在这里重复它。
AppDelegate 上的 CoreData 似乎存在严重的 Swift 2 迁移问题。我能够通过将 AppDelegate CoreData Swift 1.2 完全替换为 Swift 2.0.
来解决问题
您需要做的是删除以下内容
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
lazy var managedObjectContext: NSManagedObjectContext = {
// MARK: - Core Data Saving support
func saveContext ()
并粘贴 Swift 2.0 代码:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
}
这应该可以解决问题。
我观看了 WWDC 会议,阅读了关于 Swift 的新程序员书籍,并阅读了我能在 Stack Overflow 上找到的所有相关问题。从 Swift 1.2 迁移到 Swift 2.0.
后,我修复了应用程序中的大部分错误不过还有一些没解决。
向下转换 AnyObject
错误:
Cannot downcast from '[AnyObject]' to a more optional type '[NSManagedObject]'
代码:
let fetchRequest = NSFetchRequest(entityName: formulaEntity)
var error: NSError?
do {
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]?
if let results = fetchedResults {
stocks = results
} else {
print("Could not fetch \(error), \(error!.userInfo)")
}
} catch {
print("ERROR: \(error)")
}
显示的错误发生在 let fetchedResults = try...
行
我遇到的另一个奇怪错误是在我的 AppDelegate 中:
错误:
'NSMutableDictionary' is not convertible to '[NSObject : AnyObject]'
代码:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("Stocks.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as [NSObject : AnyObject])
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
}
return coordinator
}()
我没有接触过上面的代码。所以我不知道为什么没有通过 Apple 的迁移工具正确迁移。
我的 AppDelegate 中的另一个错误:
Binary operator '&&' cannot be applied to two Bool operands
Call can throw, but it is not marked with 'try' and the error is not handled.
代码:
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save() {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
同样,我还没有触及 AppDelegate 的这一部分,并且不确定上面的代码究竟有什么问题。
Cannot downcast from '[AnyObject]' to a more optional type '[NSManagedObject]'
在 Swift 1.2 中,executeFetchRequest(:_)
returned [AnyObject]?
。在 Swift 2 中,它 returns [AnyObject]
因为新的 try
... 语法 returns 是非可选的。
(如果该方法会 return nil
,则该方法根本不会 return,并且控制会移至 catch
块。)
'NSMutableDictionary' is not convertible to '[NSObject : AnyObject]'
这意味着您正试图将无法转换为 Objective-C 对象的内容插入到 NSMutableDictionary
中。在你的情况下,我认为这是因为 error
是一个符合 ErrorType
的结构,而不是 NSError
对象。请尝试添加 error1
。
Call can throw, but it is not marked with 'try' and the error is not handled.
save()
可能会抛出错误,因此需要使用 try
执行它,而不是将其计算为 bool
。正如 Martin R. 在评论中指出的那样,
AppDelegate 上的 CoreData 似乎存在严重的 Swift 2 迁移问题。我能够通过将 AppDelegate CoreData Swift 1.2 完全替换为 Swift 2.0.
来解决问题您需要做的是删除以下内容
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
lazy var managedObjectContext: NSManagedObjectContext = {
// MARK: - Core Data Saving support
func saveContext ()
并粘贴 Swift 2.0 代码:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
}
这应该可以解决问题。