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

Dettagliata spiegazione di CRUD di CoreData su iOS

Recentemente sto studiando CoreData, perché è necessario per lo sviluppo del progetto, ho studiato e organizzato specificamente, organizzato per l'uso futuro e come riferimento per i colleghi. Al momento, sto sviluppando progetti in Swift. Quindi, quello che ho organizzato è la versione Swift, ho abbandonato OC. Anche se c'è Swift3, la versione che ho organizzato è Swift2. Swift3 ha alcune nuove caratteristiche. Devono essere regolati in modo diverso, organizzerò ulteriormente in seguito. 

Ci sono due modi per ereditare CoreData: 

Integrare durante la creazione del progetto

 

Questo metodo eredita automaticamente all'interno di AppDelegate, per chiamarlo è necessario ottenere Context tramite il modo di UIApplication. Non mi piace questo metodo, non mi piace che AppDelegate abbia troppo codice accumulato insieme, ho riorganizzato questo metodo

Il codice derivato da CoreData viene isolato e fatto diventare una classe singleton 

Diagramma della struttura del progetto

 

Spiegazione del file progetto 
Il file fondamentale di CoreData è 
1.XPStoreManager (classe singleton per la gestione di CoreData) 
2.CoredataDemo.xcdatamodeld (file modello CoreData)
 3.Student+CoreDataProperites.swift e Student.swift (oggetto Student) 
4.ViewController.swift e Main.storyboard sono esempi di codice

Codice dettagliato 

1. XPStoreManager.swift
Classe singleton di gestione dati CoreData

//
// XPStoreManager.swift
// CoreDataDemo
//
// Creato da xiaopin il 16/9/16.
// Copyright © 2016 year xiaopin.cnblogs.com. All rights reserved.
//
import CoreData
// Classe di gestione del database locale: di default è scritta nell'AppDelegate, può essere separata in questo modo
class XPStoreManager {
 // Scrittura singleton
 static let shareInstance = XPStoreManager()
 private init() {
 }
 // MARK: - Stack Core Data
 lazy var applicationDocumentsDirectory: NSURL = {
  // La directory che l'applicazione utilizza per memorizzare il file di store Core Data. Questo codice utilizza una directory chiamata "com.pinguo.CoreDataDemo" nella directory di supporto Application Documenti dell'applicazione.
  let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
  print("\(urls[urls.count-1])")
  return urls[urls.count-1]
 }()
 lazy var managedObjectModel: NSManagedObjectModel = {
  // Il modello oggetto gestito dell'applicazione. Questa proprietà non è opzionale. È un errore fatale se l'applicazione non riesce a trovare e caricare il suo modello.
  let modelURL = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")!
  return NSManagedObjectModel(contentsOfURL: modelURL)!
 }()
 lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
  // Il coordinatore di store persistente per l'applicazione. Questa implementazione crea e restituisce un coordinatore, avendo aggiunto lo store per l'applicazione a esso. Questa proprietà è opzionale poiché ci sono condizioni di errore legittime che potrebbero causare il fallimento della creazione dello store.
  // Creare il coordinatore e lo store
  let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
  let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
  var failureReason = "C'è stato un errore nella creazione o nel caricamento dei dati salvati dell'applicazione."
  do {
   try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
  }
   // Segnalare qualsiasi errore riceviamo.
   var dict = [String: AnyObject]()
   dict[NSLocalizedDescriptionKey] = "Impossibile inizializzare i dati salvati dell'applicazione"
   dict[NSLocalizedFailureReasonErrorKey] = failureReason
   dict[NSUnderlyingErrorKey] = error as NSError
   let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
   // Sostituisci questo con il codice per gestire l'errore in modo appropriato.
   // 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("Errore non risolto \(wrappedError), \(wrappedError.userInfo)")
   abort()
  }
  return coordinator
 }()
 lazy var managedObjectContext: NSManagedObjectContext = {
  // Restituisce il contesto oggetto gestito dell'applicazione (che è già associato al coordinatore di archiviazione persistente dell'applicazione.) Questa proprietà è opzionale poiché ci sono condizioni di errore legittime che potrebbero causare il fallimento della creazione del contesto.
  let coordinator = self.persistentStoreCoordinator
  var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
 }()
 // MARK: - Core Data Saving support
 func saveContext () {
  if managedObjectContext.hasChanges {
   do {
    try managedObjectContext.save()
   }
    // 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()
   }
  }
 }
}

2.AppDelegate.swift 

Add a line of code in this line, execute save after exiting

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.
  XPStoreManager.shareInstance.saveContext()
 }

3.Student.swift 

Wrote the CRUD operations for this student object 

//
// Student.swift
// CoreDataDemo
//
// Created by cdmac on 16/9/12.
// Copyright © 2016 year xiaopin.cnblogs.com. All rights reserved.
//
import Foundation
import CoreData
class Student: NSManagedObject {
 //Insert code here to add functionality to your managed object subclass
 /*
  Normal situations involved include: increase, deletion, modification, single object query, pagination query (all, conditional query, sorting), object existence, batch increase, batch modification
  */
 /// Determines if an object exists, the obj parameter is the dictionary of the current attribute
 class func exsitsObject(obj:[String:String]) -> Bool {
  //Get the context of the managed data object
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Declare a data request
  let fetchRequest = NSFetchRequest(entityName: "Student")
  //Combine filter parameters
  let stuId = obj["stuId"]
  let name = obj["name"]
  //First method
  let predicate1 = NSPredicate(format: "stuId = %@", stuId!)
  let predicate2 = NSPredicate(format: "name = %@", name!)
  //Composite filter condition
  //or, and, not, significa: o e non, coloro che conoscono il database dovrebbero capirlo facilmente
  let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2])
  //let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2])
  fetchRequest.predicate = predicate
  //Second method
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ or name = %@", stuId!, name!)
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ and name = %@", stuId!, name!)
  do{
   let fetchObjects:[AnyObject]? = try context.executeFetchRequest(fetchRequest)
   return fetchObjects?.count > 0 ? true : false
  }
   fatalError("exsitsObject \(error)")
  }
  return false
 }
 /// Aggiungere l'oggetto, il parametro obj è un dizionario delle proprietà correnti
 class func insertObject(obj: [String:String]) -> Bool {
  //Se esiste già l'oggetto, restituire
  if exsitsObject(obj) {
   return false
  }
  //获取管理的数据上下文 对象
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Creare l'oggetto studente
  let stu = NSEntityDescription.insertNewObjectForEntityForName("Student",
                  inManagedObjectContext: context) as! Student
  //Assegnazione dell'oggetto
  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"]!)
  //Salvataggio
  do {
   try context.save()
   print("Salvataggio riuscito!")
   return true
  }
   fatalError("不能保存:\(error)")
  }
  return false
 }
 /// Eliminare l'oggetto
 class func deleteObject(obj:Student) -> Bool{
  //获取管理的数据上下文 对象
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Metodo uno: ad esempio, la lista è già un oggetto ottenuto dal database, chiamare direttamente il metodo di eliminazione predefinito di CoreData
  context.deleteObject(obj)
  XPStoreManager.shareInstance.saveContext()
  //Metodo due: tramite il parametro obj come ad esempio: id, name, utilizzare tali condizioni per cercare un oggetto singolo e rimuoverlo dal database
  //代码:略
  return true
 }
 /// 更新对象
 class func updateObject(obj:[String: String]) -> Bool {
  //obj参数说明:当前对象的要更新的字段信息,唯一标志是必须的,其他的是可选属性
  let context = XPStoreManager.shareInstance.managedObjectContext
  let oid = obj["stuId"]
  let student:Student = self.fetchObjectById(Int(oid!)!)! as! Student
  //遍历参数,然后替换相应的参数
  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("如果有其他参数需要修改,类似")
   }
  }
  //执行更新操作
  do {
   try context.save()
   print("更新成功!")
   return true
  }
   fatalError("不能保存:\(error)")
  }
  return false
 }
  /// 查询对象
 class func fetchObjects(pageIndex:Int, pageSize:Int) -> [AnyObject]? {
  //获取管理的数据上下文 对象
  let context = XPStoreManager.shareInstance.managedObjectContext
  //声明数据的请求
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  fetchRequest.fetchLimit = pageSize //每页大小
  fetchRequest.fetchOffset = pageIndex * pageSize //第几页
  //设置查询条件:参考exsitsObject
  //let predicate = NSPredicate(format: "id= '1' ", "")
  //fetchRequest.predicate = predicate
  //设置排序
  //按学生ID降序
  let stuIdSort = NSSortDescriptor(key: "stuId", ascending: false)
  //按照姓名升序
  let nameSort = NSSortDescriptor(key: "name", ascending: true)
  let sortDescriptors:[NSSortDescriptor] = [stuIdSort,nameSort]
  fetchRequest.sortDescriptors = sortDescriptors
  //查询操作
  do {
   let fetchedObjects:[AnyObject]? = try context.executeFetchRequest(fetchRequest)
   //遍历查询的结果
   /*
   for info:Student in fetchedObjects as! [Student]{
    print("id=\(info.stuId)")
    print("name=\(info.name)")
    print("sex=\(info.sex)")
    print("classId=\(info.classId)")
    print("createTime=\(info.createtime)")
    print("-------------------")
   }
    */
   return fetchedObjects
  }
  catch {
   fatalError("不能保存:\(error)")
  }
  return nil
 }
  /// 根据ID查询当个对象
 class func fetchObjectById(oid:Int) -> AnyObject?{
  //获取上下文对象
  let context = XPStoreManager.shareInstance.managedObjectContext
  //创建查询对象
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  //构造参数
  fetchRequest.predicate = NSPredicate(format: "stuId = %@", String(oid))
  //执行代码并返回结果
  do{
   let results:[AnyObject]? = try context.executeFetchRequest(fetchRequest)
   if results?.count > 0 {
    return results![0]
   }
  }
   fatalError("Errore fatale nella query dell'oggetto: \(error)\
  }
  return nil
 }
}

4.ViewController.swift 

Utilizzo specifico: 

//
// ViewController.swift
// CoreDataDemo
//
// Creato da cdmac il 11/9/16.
// Copyright © 2016 pinguo. Tutti i diritti riservati.
//
import UIKit
let cellIdentifiler = \"ReuseCell\"
class ViewController: UIViewController {
 @IBOutlet weak var txtNo: UITextField!
 @IBOutlet weak var txtName: UITextField!
 @IBOutlet weak var txtSex: UITextField!
 @IBOutlet weak var txtClassId: UITextField!
 @IBOutlet weak var tableView: UITableView!
 var dataArray:[AnyObject]?
 override func viewDidLoad() {
  super.viewDidLoad()
  // Eseguire ulteriori configurazioni dopo il caricamento della vista, tipicamente da un nib.
  self.dataArray = Student.fetchObjects(0, pageSize: 20)
  self.tableView.reloadData()
 }
 override func didReceiveMemoryWarning() {
  super.didReceiveMemoryWarning()
  // Gestire tutte le risorse che possono essere ricreate.
 }
 @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("添加成功")
   self.dataArray = Student.fetchObjects(0,pageSize: 20)
   self.tableView.reloadData()
  }
   print("添加失败")
  }
 }
 @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("更新成功")
   self.dataArray = Student.fetchObjects(0,pageSize: 20)
   self.tableView.reloadData()
  }
   print("更新失败")
  }
 }
}
extension ViewController:UITableViewDelegate,UITableViewDataSource{
 //表格有多少组
 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
  return 1
 }
 //每组多少行
 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  if self.dataArray != nil && self.dataArray?.count > 0 {
   return self.dataArray!.count
  }
  return 0
 }
 //高度
 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
  return 50
 }
 //单元格加载
 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 = "Uomo"
  if stu.sex?.intValue != 1 {
   sexStr = "Femmina"
  }
  label1.text = "\(stu.stuId!) \(stu.name!) \(sexStr) \(stu.classId!)"
  label2.text = "http://xiaopin.cnblogs.com"
  return cell!
 }
 //Seleziona
 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 {
   //Ottieni l'oggetto corrente
   let student:Student = self.dataArray![indexPath.row] as! Student
   //Elimina la memorizzazione locale
   Student.deleteObject(student)
   //Aggiorna la sorgente dei dati
   self.dataArray?.removeAtIndex(indexPath.row)
   //self.dataArray = Student.fetchObjects(0, pageSize: 20)
   //Elimina la cellula
   tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  }
 }
 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  return .Delete
 }
 func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
  return "Elimina"
 }
}

Immagine di esecuzione

 

Scarica il codice sorgente:CoreDataDemo.zip

Questo è tutto il contenuto dell'articolo, spero che sia utile per la tua apprendimento, e spero che tu sostenga fortemente il tutorial di urlania.

Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, il copyright spetta agli autori originali, il contenuto è stato caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato elaborato manualmente e non assume alcuna responsabilità legale. Se trovi contenuti sospetti di violazione del copyright, invia un'e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito cancellerà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare