tutorial programar instalar español developer desde curso cero apple ios xcode swift core-data swift3

ios - programar - xcode 6



¿Cómo crear managedObjectContext usando Swift 3 en Xcode 8? (5)

Problema de enfrentamiento "El valor del tipo ''AppDelegate'' no tiene ningún miembro ''managedObjectContext'' en el nuevo Xcode 8 (usando Swift 3, iOS 10) al intentar crear un nuevo contexto en View Controller

let context = (UIApplication.shared().delegate as! AppDelegate).managedObjectContext

En Xcode 8 no hay código para managedObjectContext dentro del archivo AppDelegate.swift. El código de la pila de datos centrales dentro de AppDelegate.swift se presenta solo con: lazy var persistentContainer: propiedad NSPersistentContainer y func saveContext (). No existe la propiedad managedObjectContext.

¿Cómo crear managedObjectContext usando Swift 3 en Xcode 8) o tal vez no hay necesidad de hacerlo usando Swift 3?


En Swift3, puede acceder al managedObjectContext a través de viewContext como

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

Esta opción está disponible si los datos principales se habilitaron al crear el proyecto. Sin embargo, para el proyecto existente en el que desea incluir datos centrales, realice el proceso normal de agregar los datos centrales y agregue el siguiente código que le permitirá obtener el

lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "you_model_file_name") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error { fatalError("Unresolved error /(error), /(error.userInfo)") } }) return container }()

Deberá importar CoreData.

Nota: Para Swift3, la subclase ManagedObject se genera automáticamente. Ver más de developer.apple.com/videos/play/wwdc2016/242


La solución de lleva a la mayor parte del camino para iOS 10.0, pero no aborda iOS 9.0 o inferior, que no puede acceder a ese método y necesita construir manualmente el NSManagedObjectModel . Aquí está la solución que funcionó para mí:

var context: NSManagedObjectContext? if #available(iOS 10.0, *) { context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext } else { // iOS 9.0 and below - however you were previously handling it guard let modelURL = Bundle.main.url(forResource: "Model", withExtension:"momd") else { fatalError("Error loading model from bundle") } guard let mom = NSManagedObjectModel(contentsOf: modelURL) else { fatalError("Error initializing mom from: /(modelURL)") } let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let docURL = urls[urls.endIndex-1] let storeURL = docURL.appendingPathComponent("Model.sqlite") do { try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil) } catch { fatalError("Error migrating store: /(error)") } }

Está claro que el cambio a 10.0 hace que CoreData sea significativamente más simple, pero es lamentable que sea tan doloroso para los desarrolladores existentes dar el salto ...

Para implementar lo anterior, solo asegúrese de lanzar el Contenedor persistentContainer en su AppDelegate.swift, definido en la respuesta de .


Movió todo el código de la pila de datos principales a un solo archivo y agregó iOS 10 e inferior a iOS10. a continuación es mi intento (no estoy seguro de que sea totalmente a la altura)

import Foundation import CoreData class CoreDataManager { // MARK: - Core Data stack static let sharedInstance = CoreDataManager() private lazy var applicationDocumentsDirectory: URL = { // The directory the application uses to store the Core Data store file. This code uses a directory named in the application''s documents Application Support directory. let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return urls[urls.count-1] }() private lazy var managedObjectModel: NSManagedObjectModel = { // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model. let modelURL = Bundle.main.url(forResource: "CoreDataSwift", withExtension: "momd")! return NSManagedObjectModel(contentsOf: modelURL)! }() private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. // Create the coordinator and store let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.appendingPathComponent("CoreDataSwift.sqlite") var failureReason = "There was an error creating or loading the application''s saved data." do { // Configure automatic migration. let options = [ NSMigratePersistentStoresAutomaticallyOption : true, NSInferMappingModelAutomaticallyOption : true ] try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options) } catch { // Report any error we got. var dict = [String: AnyObject]() dict[NSLocalizedDescriptionKey] = "Failed to initialize the application''s saved data" as AnyObject? dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject? dict[NSUnderlyingErrorKey] = error as NSError let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) // Replace this 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. NSLog("Unresolved error /(wrappedError), /(wrappedError.userInfo)") abort() } return coordinator }() lazy var managedObjectContext: NSManagedObjectContext = { var managedObjectContext: NSManagedObjectContext? if #available(iOS 10.0, *){ managedObjectContext = self.persistentContainer.viewContext } else{ // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail. let coordinator = self.persistentStoreCoordinator managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) managedObjectContext?.persistentStoreCoordinator = coordinator } return managedObjectContext! }() // iOS-10 @available(iOS 10.0, *) lazy var persistentContainer: NSPersistentContainer = { /* The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. */ let container = NSPersistentContainer(name: "CoreDataSwift") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() 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 parent directory does not exist, cannot be created, or disallows writing. * The persistent store is not accessible, due to permissions or data protection when the device is locked. * The device is out of space. * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ fatalError("Unresolved error /(error), /(error.userInfo)") } }) print("/(self.applicationDocumentsDirectory)") return container }() // MARK: - Core Data Saving support func saveContext () { if managedObjectContext.hasChanges { do { try managedObjectContext.save() } catch { // 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. let nserror = error as NSError NSLog("Unresolved error /(nserror), /(nserror.userInfo)") abort() } } } }


Primero, obtenga el objeto AppDelegate: -

let appDelegateObject = UIApplication.shared.delegate as! AppDelegate

Y ahora, podemos obtener objetos gestionados como:

let managedObject = appDelegateObject.persistentContainer.viewContext


NSPersistentContainer tiene una propiedad viewContext que es un tipo NSManagedObjectContext .

Como nota al margen, si crea una aplicación Master-Detail en Xcode 8, el código de muestra de Apple coloca la propiedad managedObjectContext en el archivo MasterViewController.swift y la establece utilizando dicha propiedad viewContext en AppDelegate.