【问题标题】:Obj-C to Swift Coredata conversionObj-C 到 Swift Coredata 的转换
【发布时间】:2015-09-03 17:33:10
【问题描述】:

好的,刚开始研究 Swift 并尝试使用现有 Obj-C 程序中的 Coredata 模型和 SQLfile

  • 创建了新的 swift Coredata 项目
  • 用现有模型替换了 coredata 模型
  • 指向 sql 数据文件的程序
  • 创建了 Swift NSMangagedObject 子类

运行程序,出现类类型不匹配的错误。

  • 删除 Swift NSMangedObject 子类并创建 Objective-C 版本

运行程序,没有问题,fetch 执行得很好。

我想最终用 swift 重写程序,但我必须处理旧的 SQL 数据文件。有没有办法让它工作而不必混合两种语言?

我没有尝试过,但是轻量级迁移会这样做吗?

-[编辑]---

错误信息在控制台中:

“致命错误:NSAarry 元素无法匹配 Swift 数组元素类型”

获取代码:

 let request = NSFetchRequest(entityName: "Account")
 var error:NSError?=nil
 var fetchResults = managedObjectContext?executeFetchRequest(request, error: &error)! as [Account]

 for aAccount in fetchResults {
 println(aAccount.name)
 }

此代码确实有效 - 如果 NSManagedObject 子类(帐户)是 Obj-C

此代码不起作用 - 如果 NSManagedObject 子类(帐户)是 Swift - 这是我收到错误的时候。

NSManagedObject Subclass 是通过 XCode 中的“Create NSManagedObject Subclass”生成的。

CoreData 模型和 SQL 数据文件来自以前的、正常运行的程序(当 100% Obj-C 时)。

-[编辑 2]-------

除非我做错了什么,否则它是大小写的……

 var fetchResults = ...(request, error: &error)! as [Account]

为了测试,我把上面的改成:

 var fetchResults = ...(request, error: &error)! as [NSManagedObject] 

通过此更改,以下工作 - 正如您所期望的那样:

 for aAccount in fetchResults {

        println(aAccount.valueForKey("name")!)     
 }

以下内容不起作用(将其添加到 for-in 循环中):

 if let account = aAccount as? Account {
            println(account.name)
 }

所以,它不会让我转换为 Swift Account 类。我使用 Xcode 的“创建 ManagedObject 子类”来创建 Swift 子类。

-[编辑 3]-----

XCode 版本:6.1

Account.swift 文件:

 import Foundation
 import Coredata

 class Account: NSManagedObject {

 @NSManaged var name: String
 @NSManaged var number: String
 @NSManaged var type: String
 @NSManaged var status: String

 }

如果我创建一个 Obj-C 版本的 Account(Account.h 和 Account.m),将它们添加到 Bridging-Header,删除 .swift 版本,一切正常。

【问题讨论】:

  • 请提供更多信息。代码。编译器错误消息。等等……
  • 我立即注意到你的类名是Accout,但你的实体名是Account(注意缺少的'n')
  • 将其放入 SO 时的错字在两台不同的计算机上,所以我无法剪切-n-粘贴 - 程序中的拼写是正确的。

标签: objective-c swift core-data


【解决方案1】:

您需要将fetchedResults 中的NSManagedObject 强制转换为您的Swift 类,以便直接访问Swift 类的属性。

for aAccount in fetchResults {
 println(aAccount.name)   // NOT GOING TO WORK
 } 

aAccount 将是 NSManagedObject,因此您必须将其转换为您的 Swift 类才能通过 Swift 类 (aAccount.name) 访问它的属性。否则你必须像这样访问该属性

aAccount.getValueForKey("Name")

或者试试这个

for managedObject in fetchResults {
 if let account = managedObject as? Account {
     println(account.name)   
  }
 } 

这是我的 Swift 模型类之一,尝试添加 @objc()

import Foundation
import CoreData

@objc(AssetX)
class AssetX: BaseNode {

    @NSManaged var childCostTotal: NSNumber
    @NSManaged var dateOfManufacture: NSDate
    @NSManaged var dateOfPurchase: NSDate
    @NSManaged var dateOfValuation: NSDate
    @NSManaged var invoice: NSAttributedString
    @NSManaged var make: String
    @NSManaged var model: String
    @NSManaged var photo: NSAttributedString
    @NSManaged var purchaseCost: NSNumber
    @NSManaged var serialNo: String
    @NSManaged var valuationCost: NSNumber
    @NSManaged var category: AssetCategory
}

基类是:

import Foundation
import CoreData

@objc(BaseNode)
class BaseNode: NSManagedObject {

    @NSManaged var canCollapse: NSNumber
    @NSManaged var canExpand: NSNumber
    @NSManaged var details: NSAttributedString
    @NSManaged var displayName: String
    @NSManaged var isExpanded: NSNumber
    @NSManaged var isLeaf: NSNumber
    @NSManaged var isSelectable: NSNumber
    @NSManaged var isSpecialGroup: NSNumber
    @NSManaged var reminderDate: NSDate
    @NSManaged var reminderPeriod: String
    @NSManaged var sortIndex: NSNumber
    @NSManaged var status: NSNumber
    @NSManaged var children: NSSet
    @NSManaged var linkedTo: People
    @NSManaged var parent: BaseNode

    var found:Bool = false

}

【讨论】:

  • 感谢您的建议,请参阅补充编辑。它不会将类型转换为类的 Swift 版本。
  • 贴出生成的 Swift Account 类的代码,可能是 XCode 错误
  • 抱歉,我没有看到您实际上已经在代码中投射到 Account。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
相关资源
最近更新 更多