English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

iOS详解CoreData增删改查

Recientemente he estado aprendiendo CoreData, ya que es necesario para el desarrollo del proyecto, he aprendido y organizado específicamente, organizado para facilitar su uso futuro y que los colegas puedan referirse a él. Actualmente estoy desarrollando proyectos en lenguaje Swift. Por lo tanto, he organizado la versión Swift, y he descartado OC. Aunque Swift3 ya tiene, la versión que estoy organizando ahora es Swift2 de. Swift 3 si tiene algunas nuevas características. Necesita ajustar aparte, organizaré más tarde. 

Hay dos maneras de heredar CoreData: 

Integrar al crear el proyecto

 

Esta manera es automática en AppDelegate, se necesita obtener AppDelegate a través de la forma de llamada de UIApplication para obtener el contexto. No me gusta esta manera, no me gusta que AppDelegate tenga demasiado código juntos, he organizado esta manera

Separar el código que hereda de datos centrales y hacer una clase singleton 

Diagrama de estructura del proyecto

 

Descripción del archivo del proyecto 
El archivo central de datos centrales es 
1.XPStoreManager (clase singleton de gestión de datos centrales) 
2.CoredataDemo.xcdatamodeld (archivo de modelo de datos centrales)
 3.Student+CoreDataProperites.swift y Student.swift (objeto estudiante) 
4.ViewController.swift y Main.storyboard son códigos de ejemplo

Código de detalles 

1. XPStoreManager.swift
Clase singleton de gestión de datos centrales

//
// XPStoreManager.swift
// CoreDataDemo
//
// Creado por xiaopin el 16/9/16.
// Copyright © 2016xiaopin.cnblogs.com. Todos los derechos reservados.
//
import CoreData
/// Clase de gestión de base de datos local: por defecto está escrita en AppDelegate, se puede separar de esta manera
class XPStoreManager {
 //Escriba un solo ejemplo
 static let shareInstance = XPStoreManager()
 private init() {
 }
 // MARCA: - Pila de datos centrales
 var lazy applicationDocumentsDirectory: NSURL = {
  // El directorio que la aplicación utiliza para almacenar el archivo de almacenamiento de datos centrales. Este código utiliza un directorio llamado "com.pinguo.CoreDataDemo" en el directorio de soporte de documentos de la aplicación.
  let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
  print("\(urls[urls.count-1])")
  return urls[urls.count-1]
 }()
 var managedObjectModel: NSManagedObjectModel = {
  // El modelo de objeto gestionado de la aplicación. Esta propiedad no es opcional. Es un error fatal que la aplicación no pueda encontrar y cargar su modelo.
  let modelURL = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")!
  return NSManagedObjectModel(contentsOfURL: modelURL)!
 }()
 var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
  // El coordinador de almacenamiento persistente de la aplicación. Esta implementación crea y devuelve un coordinador, después de agregarle el almacenamiento para la aplicación. Esta propiedad es opcional ya que hay condiciones de error legítimas que podrían causar que la creación del almacenamiento falle.
  // Crear el coordinador y el almacenamiento
  let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
  let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
  var failureReason = "Se produjo un error al crear o cargar los datos guardados de la aplicación."
  do {
   try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
  } catch {}}
   // Informar de cualquier error que obtengamos.
   var dict = [String: AnyObject]()
   dict[NSLocalizedDescriptionKey] = "Falló al inicializar los datos guardados de la aplicación"
   dict[NSLocalizedFailureReasonErrorKey] = failureReason
   dict[NSUnderlyingErrorKey] = error as NSError
   let wrappedError = NSError(domain: "TU_ERROR_DOMAIN", code: 9999, userInfo: dict)
   // Reemplaza esto con el código para manejar el error adecuadamente.
   // abort() hace que la aplicación genere un registro de accidentes y finalice. No debe usar esta función en una aplicación de lanzamiento, aunque puede ser útil durante el desarrollo.
   NSLog("Error sin resolver \(wrappedError), \(wrappedError.userInfo)")
   abort()
  }
  return coordinator
 }()
 lazy var managedObjectContext: NSManagedObjectContext = {
  // Devuelve el contexto de objeto gestionado para la aplicación (que ya está vinculado al coordinador de almacenamiento persistente de la aplicación). Esta propiedad es opcional ya que hay condiciones de error legítimas que podrían causar que la creación del contexto falle.
  let coordinator = self.persistentStoreCoordinator
  var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
 }()
 // MARCA: - Soporte de guardado de Core Data
 func saveContext () {
  if managedObjectContext.hasChanges {
   do {
    try managedObjectContext.save()
   } catch {}}
    // Reemplace esta implementación con código para manejar el error adecuadamente.
    // abort() hace que la aplicación genere un registro de accidentes y finalice. No debe usar esta función en una aplicación de lanzamiento, aunque puede ser útil durante el desarrollo.
    let nserror = error as NSError
    NSLog("Error sin resolver \(nserror), \(nserror.userInfo)")
    abort()
   }
  }
 }
}

2.AppDelegate.swift 

Añada una línea de código aquí para guardar después de salir

func applicationWillTerminate(application: UIApplication) {
  // Llamado cuando la aplicación está a punto de terminar. Guarde los datos si es apropiado. Véase también applicationDidEnterBackground:.
  // Guarda los cambios en el contexto de objetos administrados de la aplicación antes de que la aplicación termine.
  XPStoreManager.shareInstance.saveContext()
 }

3.Student.swift 

Se escribió una lógica de aumento, eliminación, modificación y búsqueda para este objeto estudiante 

//
// Student.swift
// CoreDataDemo
//
// Creado por cdmac el 16/9/12.
// Copyright © 2016xiaopin.cnblogs.com. Todos los derechos reservados.
//
import Foundation
import CoreData
class Student: NSManagedObject {
 // Inserte el código aquí para agregar funcionalidad a su subclase de objeto administrado
 /*
  Los casos generales que involucran incluyen: agregar, eliminar, modificar, búsqueda de objeto único, búsqueda por paginación (todos, búsqueda condicional, ordenamiento), existencia del objeto, adición en lote, modificación en lote
  */
 /// Determinar si el objeto existe, el parámetro obj es el diccionario de la propiedad actual
 class func exsitsObject(obj:[String:String]) -> Bool {
  //Obtener el contexto de datos administrados
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  //Declarar una solicitud de datos
  let fetchRequest = NSFetchRequest(entityName: "Student")
  //组合过滤参数
  let stuId = obj["stuId"]
  let name = obj["name"]
  //方式一
  let predicate1 = NSPredicate(format: "stuId = %@", stuId!)
  let predicate2 = NSPredicate(format: "name = %@", name!)
  //合成过滤条件
  //or ,and, not , 意思是:或与非,懂数据库的同学应该就很容易明白
  let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2]
  //let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2]
  fetchRequest.predicate = predicate
  //方式二
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ or name = %@", stuId!, name!)
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ and name = %@", stuId!, name!)
  hacer{
   let fetchObjects:[AnyObject]? = try contexto.ejecutarPeticiónFetch(fetchRequest)
   return fetchObjects?.count > 0 ? true : false
  }
   fatalError("exsitsObject \(error)")
  }
  return false
 }
 /// 添加对象, obj参数是当前属性的字典
 class func insertObject(obj: [String:String]) -> Bool {
  //如果存在对象了就返回
  if exsitsObject(obj) {
   return false
  }
  //obtener el objeto contexto de datos administrativo
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  //创建学生对象
  let stu = NSEntityDescription.insertNewObjectForEntityForName("Student",
                  inManagedObjectContext: context) as! Student
  //对象赋值
  let sexStr:String
  if obj["sex"] == "男"{
   sexStr = "}}1"
  }
   sexStr = "0"
  }
  let numberFMT = NSNumberFormatter()
  numberFMT.numberStyle = .NoStyle
  stu.stuId = numberFMT.numberFromString(obj["stuId"]!)
  stu.name = obj["name"]
  stu.createtime = NSDate()
  stu.sex = numberFMT.numberFromString(sexStr)
  stu.classId = numberFMT.numberFromString(obj["classId"]!)
  //Guardar
  do {
   try context.save()
   print("¡Guardado con éxito!")
   return true
  } catch {}}
   fatalError("No se puede guardar: \(error)")
  }
  return false
 }
 /// Eliminar objeto
 class func deleteObject(obj:Student) -> Bool{
  //obtener el objeto contexto de datos administrativo
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  //Método uno: por ejemplo, la lista ya se ha obtenido de la base de datos, llame directamente al método de eliminación predeterminado de CoreData
  context.deleteObject(obj)
  XPStoreManager.shareInstance.saveContext()
  //Método dos: a través del parámetro obj, por ejemplo: id, name, buscar un objeto a la vez con tales condiciones y eliminarlo de la base de datos
  //Código: omitido
  return true
 }
 /// Actualizar objeto
 class func updateObject(obj:[String: String]) -> Bool {
  //obj参数说明:La información de campo del objeto actual a actualizar, el identificador único es obligatorio, los demás son atributos opcionales
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  let oid = obj["stuId"]
  let student:Student = self.fetchObjectById(Int(oid!)!)! as! Student
  //Recorrer los parámetros y luego reemplazar los parámetros correspondientes
  let numberFMT = NSNumberFormatter()
  numberFMT.numberStyle = .NoStyle
  for key in obj.keys {
   switch key {
   case "name":
    student.name = obj["name"]
   case "classId":
    student.classId = numberFMT.numberFromString(obj["classId"]!)
   default:
    print("Si hay otros parámetros que necesiten modificar, al estilo de")
   }
  }
  //Ejecutar la operación de actualización
  do {
   try context.save()
   print("¡Actualización exitosa!")
   return true
  } catch {}}
   fatalError("No se puede guardar: \(error)")
  }
  return false
 }
  /// buscar objetos
 class func fetchObjects(pageIndex:Int, pageSize:Int) -> [AnyObject]? {
  //obtener el objeto contexto de datos administrativo
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  //declarar solicitud de datos
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  fetchRequest.fetchLimit = pageSize //tamaño de página
  fetchRequest.fetchOffset = pageIndex * tamañoDePagina //página
  //establecer condiciones de búsqueda: referente a exsitsObject
  //let predicate = NSPredicate(format: "id= '"1", "")
  //fetchRequest.predicate = predicate
  //establecer ordenamiento
  //ordenar por ID de estudiante en orden descendente
  let stuIdSort = NSSortDescriptor(key: "stuId", ascending: false)
  //ordenar por nombre en orden ascendente
  let nameSort = NSSortDescriptor(key: "name", ascending: true)
  let sortDescriptors:[NSSortDescriptor] = [stuIdSort,nameSort]
  fetchRequest.sortDescriptors = sortDescriptors
  //operación de búsqueda
  do {
   let fetchedObjects:[AnyObject]? = try contexto.ejecutarPeticiónFetch(fetchRequest)
   //recorrer los resultados de la búsqueda
   /*
   for info:Student in fetchedObjects as! [Student]{
    print("id=\(info.stuId)")
    print("nombre=\(info.name)")
    print("sexo=\(info.sex)")
    print("classId=\(info.classId)")
    print("createTime=\(info.createtime)")
    print("-------------------")
   }
    */
   return fetchedObjects
  }
  catch {
   fatalError("No se puede guardar: \(error)")
  }
  devolver nil
 }
  /// según ID buscar un objeto
 class func fetchObjectById(oid:Int) -> AnyObject?{}}
  //obtener objeto de contexto
  let contexto = XPStoreManager.shareInstance.managedObjectContext
  //crear objeto de consulta
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  //construir parámetros
  fetchRequest.predicate = NSPredicate(format: "stuId = %@", String(oid))
  //ejecutar código y devolver resultados
  hacer{
   let resultados:[AnyObject]? = try contexto.ejecutarPeticiónFetch(fetchRequest)
   if resultados?.count > 0 {
    devolver resultados![0]
   }
  catch{
   errorFatal("Error fatal al consultar el objeto individual: \(error)")
  }
  devolver nil
 }
}

4.ViewController.swift 

Uso específico: 

//
// ViewController.swift
// CoreDataDemo
//
// Creado por cdmac el 16/9/11.
// Copyright © 2016pingüino. Todos los derechos reservados.
//
importar UIKit
let cellIdentifiler = "ReuseCell"
clase ViewController: UIViewController {
 @IBOutlet débil var txtNo: UITextField!
 @IBOutlet débil var txtName: UITextField!
 @IBOutlet débil var txtSex: UITextField!
 @IBOutlet débil var txtClassId: UITextField!
 @IBOutlet débil var tableView: UITableView!
 var dataArray:[AnyObject]?
 sobreescritura func viewDidLoad() {
  super.viewDidLoad()
  // Haga cualquier configuración adicional después de cargar la vista, generalmente desde un nib.
  self.dataArray = Student.fetchObjects(0, pageSize: 20)
  self.tableView.reloadData()
 }
 override func didReceiveMemoryWarning() {
  super.didReceiveMemoryWarning()
  // Dispose of any resources that can be recreated.
 }
 @IBAction func addAction(sender: AnyObject) {
  var dic = [String:String]()
  dic["stuId"] = txtNo.text
  dic["name"] = txtName.text
  dic["sex"] = txtSex.text
  dic["classId"] = txtClassId.text
  if Student.insertObject(dic) {
   print("Add successful")
   self.dataArray = Student.fetchObjects(0, pageSize: 20)
   self.tableView.reloadData()
  }
   print("Add failed")
  }
 }
 @IBAction func updateAction(sender: AnyObject) {
  var dic = [String:String]()
  dic["stuId"] = txtNo.text
  dic["name"] = txtName.text
  //dic["sex"] = txtSex.text
  dic["classId"] = txtClassId.text
  if Student.updateObject(dic) {
   print("Update successful")
   self.dataArray = Student.fetchObjects(0, pageSize: 20)
   self.tableView.reloadData()
  }
   print("Update failed")
  }
 }
}
extension ViewController: UITableViewDelegate, UITableViewDataSource{
 //how many groups in the table
 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
  return 1
 }
 //how many rows per group
 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  if self.dataArray != nil && self.dataArray63.count > 0 {
   return self.dataArray!.count
  }
  return 0
 }
 //height
 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {}}
  return 50
 }
 //Carga de celda
 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifiler)
  let stu:Student = self.dataArray![indexPath.row] as! Student
  let label1:UILabel = cell?.contentView.viewWithTag(10001) as! UILabel
  let label2:UILabel = cell?.contentView.viewWithTag(10002) as! UILabel
  var sexStr = "男性"
  if stu.sex?.intValue != 1 {
   sexStr = "女性"
  }
  label1.text = "\(stu.stuId!) \(stu.name!) \(sexStr) \(stu.classId!)"
  label2.text = "http:"//xiaopin.cnblogs.com"
  return cell!
 }
 //Seleccionar
 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
 }
 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
  return true
 }
 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
  if editingStyle == .Delete {
   //Obtener el objeto actual
   let student:Student = self.dataArray![indexPath.row] as! Student
   //eliminar almacenamiento local
   Student.deleteObject(student)
   //refrescar fuente de datos
   self.dataArray?.removeAtIndex(indexPath.row)
   //self.dataArray = Student.fetchObjects(0, pageSize: 20)
   //eliminar celda
   tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  }
 }
 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  return .Delete
 }
 func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
  return "eliminar"
 }
}

Imágenes de ejecución

 

Descarga de código fuente:CoreDataDemo.zip

Esto es todo el contenido de este artículo, espero que sea útil para su aprendizaje y que todos nos apoyen y alentemos el tutorial.

Declaración: el contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume la responsabilidad legal relevante. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @ para denunciar y proporcione evidencia. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción de derechos de autor.)