Swift和CoreData /数据存储
我只是在学习Objective-C / Cocoa Touch和Core Data。 那么,在用纯Swift编写的iOS App Projects中实现数据存储的新可能性有哪些? 我非常喜欢这种语言,但据我所知,所有核心数据方法都是用Objective-C编写的。 那么核心数据类/方法会自动转换为Swift-Code还是我们必须将Core数据的Objective-C代码与其他所有内容的Swift-Code混合使用?
这就是我实现核心数据的方式。
一些非常重要的注意事项:
-
您必须将此添加到NSManagedObject类:
@objc(为MyObject)
-
您必须将实体名称添加到.xcdatamodel中的默认配置类(包含图片)
-
你不能简单地制作一个NSManagedObject。
var myObject : MyObject = MyObject()
你必须这样做:
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate let context: NSManagedObjectContext = appDelegate.managedObjectContext let entityName: String = "MyObject" let myEntityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context) var myObject = MyObject(entity: myEntityDescription, insertIntoManagedObjectContext: context)
这是我的NSManagedObject。 我包括两个fetch方法以及一个用于对象构造的类方法。 您可能会注意到我正在利用新的枚举系统,以便我可以轻松访问我的实体名称和实体属性
import UIKit import CoreData enum MyObjectPropertyList { case name func description() -> String { switch self { case .name: return "name" } } } @objc(MyObject) class MyObject: NSManagedObject { @NSManaged var name: String // //// CREATE CLASS OBJECT // class func createMyObject (propertyName:MyObjectPropertyList, value:String, context: NSManagedObjectContext) -> MyObject? { if !value.isEmpty { let propertyType = propertyName.description() let entityName = "MyObject" let request : NSFetchRequest = NSFetchRequest(entityName: entityName) request.returnsObjectsAsFaults = false request.predicate = NSPredicate(format: "\(propertyType) = %@", value) var error: NSError? = nil var matches: NSArray = context.executeFetchRequest(request, error: &error) if (matches.count > 1) { // handle error return matches[0] as? MyObject } else if matches.count == 0 { let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context) var myObject : MyObject = MyObject(entity: entityDescription, insertIntoManagedObjectContext: context) myObject.name = value return myObject } else { println(matches[0]) return matches[0] as? MyObject } } return nil } } // //// FETCH REQUESTS // func myGeneralFetchRequest (entity : CoreDataEntities, property : MyObjectPropertyList, context : NSManagedObjectContext) -> AnyObject[]?{ let entityName = entity.description() let propertyName = property.description() let request :NSFetchRequest = NSFetchRequest(entityName: entityName) request.returnsObjectsAsFaults = false let sortDescriptor : NSSortDescriptor = NSSortDescriptor(key: propertyName, ascending: true) request.sortDescriptors = [sortDescriptor] var error: NSError? = nil var matches: NSArray = context.executeFetchRequest(request, error: &error) if matches.count > 0 { return matches } else { return nil } } func myNameFetchRequest (entity : CoreDataEntities, property : MyObjectPropertyList, value : String, context : NSManagedObjectContext) -> AnyObject[]? { let entityName = entity.description() let propertyName = property.description() let request :NSFetchRequest = NSFetchRequest(entityName: entityName) request.returnsObjectsAsFaults = false request.predicate = NSPredicate(format: "\(propertyName) = %@", value) let sortDescriptor :NSSortDescriptor = NSSortDescriptor(key: propertyName, ascending: true) request.sortDescriptors = [sortDescriptor] var error: NSError? = nil var matches: NSArray = context.executeFetchRequest(request, error: &error) if matches.count > 0 { return matches } else { return nil } } // //// PRINT FETCH REQUEST // func printFetchedArrayList (myarray:AnyObject[]) { if myarray.count > 0 { println("Has \(myarray.count) object") for myobject : AnyObject in myarray { var anObject = myobject as MyObject var thename = anObject.name println(thename) } } else { println("empty fetch") } }
这是我的视图控制器
import UIKit import CoreData enum CoreDataEntities { case MyObject func description() -> String { switch self { case .MyObject: return "MyObject" } } } class ViewController: UIViewController { // //// MOC // var managedObjectContext : NSManagedObjectContext = NSManagedObjectContext() // //// Text Field // @IBOutlet var myTextField : UITextField // //// BUTTONS // @IBAction func saveButtonPress(sender : UIButton) { makeEntityAction() } @IBAction func fetchButtonPress(sender : UIButton) { fetchObjectAction() } // //// ACTIONS // func makeEntityAction () { println("-- Make action --") let value:String = self.myTextField.text var myObject : MyObject = MyObject.createMyObject(MyObjectPropertyList.name, value : value, context: self.managedObjectContext)! saveContext(self.managedObjectContext) } func fetchObjectAction () { println("-- Fetch action --") if let myTotalarray = myGeneralFetchRequest(CoreDataEntities.MyObject, MyObjectPropertyList.name, self.managedObjectContext) { printFetchedArrayList(myTotalarray) } if let mySinglearray: AnyObject[] = myNameFetchRequest(CoreDataEntities.MyObject, MyObjectPropertyList.name, "Bill", self.managedObjectContext) { println("(-- --)") printFetchedArrayList(mySinglearray) } } // //// LOAD & SAVE // func loadContext () { let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate let context: NSManagedObjectContext = appDelegate.managedObjectContext self.managedObjectContext = context } func saveContext (context: NSManagedObjectContext) { var error: NSError? = nil context.save(&error) } // //// LOAD // func myLoad () { loadContext () println("Loaded Context") } // //// Life Cycle // override func viewDidLoad() { super.viewDidLoad() myLoad () } }
所有Objective-C框架都可以快速准备好。 Swift友好的标题是自动生成的(按需显示),您可以从ObjC访问Swift中的任何内容。
我测试过使用swift访问coredata,请访问演示代码: https : //github.com/iascchen/SwiftCoreDataSimpleDemo 。
如果你想玩Swift和CoreData,我已经编写了一个框架,它是CoreData的Active Record风格助手。
SuperRecord Swift框架
(注意:不是一个无耻的插件:)我实际上认为这对用户有用)。
当您从数据模型生成NSManagedObject子类时,XCode 6 Beta 4现在允许您选择Objective C或Swift。
这是将CoreData添加到Swift应用程序的另一种方法。 此方法隐藏了应用程序其余部分的CoreData实现详细信息。 在应用程序中,您使用以下查询/更新:
Query("Order").sort("date").fetch()
要么:
let newClient = Query("Client").create() as? Client
见要点: https : //gist.github.com/gk11/438c3f2883c5d7c0b0d8