Swift y CoreData / Almacenamiento de datos

Solo estoy aprendiendo Objective-C / Cocoa Touch y Core Data. Entonces, ¿cuáles son las nuevas posibilidades para implementar el almacenamiento de datos en los proyectos de la aplicación iOS que están escritos en Swift puro? Me gusta mucho el idioma, pero por lo que sé todos los methods de datos centrales están escritos en Objective-C. Entonces, ¿las classs / methods de datos centrales se convertirán a Swift-Code automáticamente o tendremos que mezclar el Código de Objective-C para los datos de Núcleo y el Código de Swift para todo lo demás?

Así es como implementé los datos centrales.

Un par de notas realmente importantes:

  • Tienes que agregar esto a tu class NSManagedObject:

    @objc (MyObject)

  • Debe agregar el nombre de la entidad a su class de configuration pnetworkingeterminada en .xcdatamodel (image incluida)

xcdatamodel

  • No puedes simplemente hacer un NSManagedObject.

    var myObject : MyObject = MyObject() 

Tienes que hacer esto:

 let appDelegate: AppDelegate = UIApplication.shanetworkingApplication().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) 

Aquí está mi NSManagedObject. Incluí dos methods de obtención así como un método de class para la construcción de objects. Puede notar que aprovecho el nuevo sistema de enumeración para poder acceder fácilmente a los attributes de mi entidad y nombres

 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.pnetworkingicate = NSPnetworkingicate(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.pnetworkingicate = NSPnetworkingicate(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") } } 

Aquí está mi controller de vista

 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.shanetworkingApplication().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 () } } 

Todos los frameworks Objective-C están listos para usar. Los encabezados fáciles de usar se generan automáticamente (a pedido, parece), y puedes acceder a cualquier cosa desde Swift que puedas desde ObjC.

Había probado el uso rápido para acceder a la conetworkingata, visite el código de demostración: https://github.com/iascchen/SwiftCoreDataSimpleDemo .

Si quieres jugar con Swift y CoreData, he escrito un marco que es un asistente de estilo Active Record para CoreData.

SuperRecord Swift Framework

(nota: no un plug descarado 🙂 realmente pensé que esto sería útil para el usuario).

XCode 6 Beta 4 ahora le permite elegir Objective C o Swift cuando genera subclasss NSManagedObject desde su model de datos.

Aquí hay otro enfoque para agregar CoreData a su aplicación Swift. Este enfoque oculta los detalles de implementación CoreData del rest de la aplicación. En la aplicación, utiliza consultas / actualizaciones como estas:

 Query("Order").sort("date").fetch() 

o:

 let newClient = Query("Client").create() as? Client 

Ver Gist: https://gist.github.com/gk11/438c3f2883c5d7c0b0d8