Je viens d'apprendre Objective-C/Cocoa Touch et Core Data. Quelles sont donc les nouvelles possibilités d’implémentation du stockage de données dans les projets d’application iOS écrits en Swift pur? J'aime beaucoup le langage, mais autant que je sache, toutes les méthodes de données de base sont écrites en Objective-C. Ainsi, les classes/méthodes de données de base converties automatiquement en Swift-Code ou devrons-nous mélanger le code Objective-C pour les données de base et Swift-Code pour tout le reste?
Voici comment j'ai implémenté les données de base.
Quelques notes vraiment importantes:
Vous devez ajouter ceci à votre classe NSManagedObject:
@objc (MyObject)
Vous devez ajouter le nom de l'entité à votre classe de configuration par défaut dans le fichier .xcdatamodel (image incluse).
Vous ne pouvez pas simplement créer un NSManagedObject.
var myObject : MyObject = MyObject()
Tu dois faire ca:
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)
Voici mon NSManagedObject. J'ai inclus deux méthodes de récupération, ainsi qu'une méthode de classe pour la construction d'objet. Vous remarquerez peut-être que je profite du nouveau système Enum pour pouvoir accéder facilement à mes noms et attributs d'entité.
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")
}
}
Voici mon contrôleur de vue
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 ()
}
}
Tous les frameworks Objective-C sont prêts pour Swift. Des en-têtes conviviaux pour Swift sont automatiquement générés (à la demande, semble-t-il) et vous pouvez accéder à tout ce que vous pouvez depuis Swift depuis ObjC.
J'avais testé l'utilisation de Swift pour accéder à Coredata, veuillez visiter le code de démonstration: https://github.com/iascchen/SwiftCoreDataSimpleDemo .
Si vous voulez jouer avec Swift et CoreData, j'ai écrit un cadre qui associe un assistant de style Active Record à CoreData.
(note: pas une fiche éhontée :) j'ai en fait pensé que cela serait utile pour l'utilisateur).
XCode 6 Beta 4 vous permet maintenant de choisir Objective C ou Swift lorsque vous générez des sous-classes NSManagedObject à partir de votre modèle de données.
Voici une autre approche permettant d’ajouter CoreData à votre application Swift . Cette approche masque les détails de la mise en œuvre de CoreData dans le reste de l’application. Dans l'application, vous utilisez des requêtes/mises à jour comme celles-ci:
Query("Order").sort("date").fetch()
ou:
let newClient = Query("Client").create() as? Client
Voir Gist: https://Gist.github.com/gk11/438c3f2883c5d7c0b0d8