将 Core Data 相关代码迁移到 Swift 2

Posted

技术标签:

【中文标题】将 Core Data 相关代码迁移到 Swift 2【英文标题】:Migrating Core Data related code to Swift 2 【发布时间】:2015-09-17 06:55:59 【问题描述】:

我有一些这样的功能:

func getAllEntities() -> [MyEntity]? 

    let fetchRequest = NSFetchRequest(entityName:"MyEntity")

    var error: NSError?
    let fetchedResults = context.executeFetchRequest(fetchRequest) as! [MyEntity]?

    if let results = fetchedResults 
        return results
    
    else 
            print("Could not fetch \(error), \(error!.userInfo)")
        
    

    return nil

现在升级到Swift 2Xcode 7,我收到如下错误:

无法从“[AnyObject]”向下转换为更可选的类型“[MyEntity]?”

调用可以抛出,但是没有标记'try'并且错误没有处理

这是在执行自动Swift 代码迁移之后,当您第一次启动Xcode 7 时会要求您执行此操作。在新的Swift 版本中重写我的函数的正确方法是什么?

谢谢

编辑:我需要保持与ios 7iOS 8 的向后兼容性。

【问题讨论】:

【参考方案1】:

有两个错误:

在 Swift 2 中,executeFetchRequest() 返回一个非可选值。所以你不能将返回值转换为[MyEntity]?。您可以(强制或可选)将其转换为 [MyEntity]executeFetchRequest() 在错误情况下抛出错误,所以它必须 在 do-catch 语句中使用 try 调用。

例子:

func getAllEntities() -> [MyEntity]? 

    let fetchRequest = NSFetchRequest(entityName: "MyEntity")
    do 
        let results = try context.executeFetchRequest(fetchRequest) as! [MyEntity]
        return results
     catch let error as NSError 
        print("Could not fetch \(error), \(error.userInfo)")
        return nil
    

强制转换 as! [MyEntity] 在这里是可以接受的(如您的 原始代码)因为你知道实体的类,它是 在 Core Data 模型检查器中设置。

【讨论】:

谢谢。我忘了提到我需要让我的应用程序与 iOS 7 和 8 兼容,而且似乎 Swift 2 仅适用于 iOS 8 及更高版本......我编辑了我的问题。我该怎么办? @AppsDev:据我所知,Swift 2 部署回 iOS 7,所以这应该不是问题。 – 不可能编写同时使用 Swift 1.2 和 Swift 2 编译的代码,这两个版本差别太大了。 Xcode 帮助显示新的executeFetchRequest 适用于 iOS 8.1 及更高版本 @AppsDev:executeFetchRequest 从 iOS 3 开始可用(参见 developer.apple.com/library/ios/documentation/Cocoa/Reference/…)。没有“新的”executeFetchRequest,Swift 1.2 和 Swift 2 之间只有映射到 Swift 的不同。上面的代码在我的 Xcode 7GM 中与 iOS 7 部署目标一起编译没有问题。我会在下载后立即仔细检查最终版本。 @AppsDev:上面的代码是用Xcode 7编译的,部署目标设置为iOS 7。Xcode帮助检查器中的可用性通知是错误的。【参考方案2】:

对于第一个错误,我通常会从 Xcode 获得建议,通常要求我丢失 ?或将其更改为!,我无法为您提供具体的解决方案。

这是解决第二个错误的代码:

func getAllEntities() -> [MyEntity]? 

let fetchRequest = NSFetchRequest(entityName:"MyEntity")

var error: NSError?
let fetchedResults = try context.executeFetchRequest(fetchRequest) as! [MyEntity]?

do 
return results


catch error 
print("Could not fetch \(error), \(error!.userInfo)")


return nil

【讨论】:

以上是关于将 Core Data 相关代码迁移到 Swift 2的主要内容,如果未能解决你的问题,请参考以下文章

(Swift) 如何对 Core Data 进行模糊搜索?

如何将字符串保存到Core Data Swift

将 Core Data 应用程序迁移到 iCloud

如何将一个 Core Data 模型迁移到一个全新的模型?

CoreData学习:Core Data Stack(Swift)

Swift 3 Core Data Migration with Progress Indicator 或 Activity Spinner