Giusto per spiegare tutti i passaggi che è effettivamente necessario eseguire per aggiungere i dati di base a un progetto che in precedenza non li aveva:
Passaggio 1: aggiungere il framework
Fai clic sul target della tua app (nel riquadro di sinistra è l'icona in alto con il nome della tua app), quindi vai alla scheda "Crea fasi", quindi su "Collega binario con librerie", fai clic sul piccolo "+" in basso, quindi trova 'CoreData.framework' e aggiungilo al tuo progetto
Quindi importa coredata su tutti gli oggetti che ti servono (in modo non sexy) usando:
veloce
import CoreData
Obiettivo C
#import <CoreData/CoreData.h>
o aggiungi l'importazione sotto le importazioni comuni nel tuo file .pch (molto più sexy) in questo modo:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#endif
Passaggio 2: aggiungere il modello dati
Per aggiungere il file .xcdatamodel fare clic con il pulsante destro del mouse / controllo-clic sui file nel riquadro a destra (come in una cartella Risorse per la conservazione sicura) e selezionare Aggiungi un nuovo file, fare clic sulla scheda Dati principali quando si seleziona il tipo di file, quindi fare clic su " Modello dati ", assegnagli un nome e fai clic su Avanti e Fine e lo aggiungerà al tuo progetto. Quando fai clic su questo oggetto Modello, vedrai l'interfaccia per aggiungere le Entità al tuo progetto con tutte le relazioni che desideri.
Passaggio 3: aggiornare il delegato dell'app
In Swift su AppDelegate.swift
//replace the previous version of applicationWillTerminate with this
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
func saveContext () {
var error: NSError? = nil
let managedObjectContext = self.managedObjectContext
if managedObjectContext != nil {
if managedObjectContext.hasChanges && !managedObjectContext.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
}
}
// #pragma mark - Core Data stack
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
var managedObjectContext: NSManagedObjectContext {
if !_managedObjectContext {
let coordinator = self.persistentStoreCoordinator
if coordinator != nil {
_managedObjectContext = NSManagedObjectContext()
_managedObjectContext!.persistentStoreCoordinator = coordinator
}
}
return _managedObjectContext!
}
var _managedObjectContext: NSManagedObjectContext? = nil
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
var managedObjectModel: NSManagedObjectModel {
if !_managedObjectModel {
let modelURL = NSBundle.mainBundle().URLForResource("iOSSwiftOpenGLCamera", withExtension: "momd")
_managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
}
return _managedObjectModel!
}
var _managedObjectModel: NSManagedObjectModel? = nil
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
var persistentStoreCoordinator: NSPersistentStoreCoordinator {
if !_persistentStoreCoordinator {
let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("iOSSwiftOpenGLCamera.sqlite")
var error: NSError? = nil
_persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
Typical reasons for an error here include:
* The persistent store is not accessible;
* The schema for the persistent store is incompatible with current managed object model.
Check the error message to determine what the actual problem was.
If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
If you encounter schema incompatibility errors during development, you can reduce their frequency by:
* Simply deleting the existing store:
NSFileManager.defaultManager().removeItemAtURL(storeURL, error: nil)
* Performing automatic lightweight migration by passing the following dictionary as the options parameter:
[NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true}
Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
*/
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
}
return _persistentStoreCoordinator!
}
var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil
// #pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
var applicationDocumentsDirectory: NSURL {
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.endIndex-1] as NSURL
}
In Obiettivo C assicurarsi di aggiungere questi oggetti a AppDelegate.h
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory; // nice to have to reference files for core data
Sintetizza gli oggetti precedenti in AppDelegate.m in questo modo:
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
Quindi aggiungi questi metodi ad AppDelegate.m (assicurati di inserire il nome del modello che hai aggiunto negli spot mostrati):
- (void)saveContext{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
- (NSManagedObjectContext *)managedObjectContext{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAMEOFYOURMODELHERE" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"NAMEOFYOURMODELHERE.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
Passaggio 4: portare gli oggetti dati nei ViewController dove sono necessari i dati
Opzione 1. Utilizzare ManagedObjectContext del delegato dell'app da VC (preferito e più semplice)
Come suggerito da @ brass-kazoo - Recupera un riferimento ad AppDelegate e il suo managedObjectContext tramite:
veloce
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.managedObjectContext
Obiettivo C
[[[UIApplication sharedApplication] delegate] managedObjectContext];
nel tuo ViewController
Opzione 2. Creare ManagedObjectContext nel VC e farlo corrispondere a AppDelegate da AppDelegate (Original)
Mostra solo la vecchia versione per Objective C poiché è molto più semplice utilizzare il metodo preferito
in ViewController.h
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
In ViewController.m
@synthesize managedObjectContext = _managedObjectContext;
In AppDelegate, o classe in cui viene creato ViewController, impostare managedObjectContext in modo che sia uguale a AppDelegate
ViewController.managedObjectContext = self.managedObjectContext;
Se si desidera che il viewcontroller che utilizza Core Data sia un FetchedResultsController, è necessario assicurarsi che questa roba sia nel ViewController.h
@interface ViewController : UIViewController <NSFetchedResultsControllerDelegate> {
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
E questo è in ViewController.m
@synthesize fetchedResultsController, managedObjectContext;
Dopo tutto ciò ora puoi usare managedObjectContext per eseguire tutti i soliti fetchRequests necessari per la bontà di CoreData! Godere