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

Detailed Explanation of CRUD in iOS CoreData

最近在学习CoreData, 因为项目开发中需要,特意学习和整理了一下,整理出来方便以后使用和同行借鉴。目前开发使用的Swift语言开发的项目。所以整理出来的是Swift版本,OC我就放弃了。 虽然Swift3 has already been there, and the version I am organizing now is Swift2 Swift 3 There are some new features. It needs to be adjusted separately, and I will organize it later when I have time. 

There are two ways to inherit CoreData: 

Integrated when creating the project

 

This method is automatically inherited in AppDelegate, and the call needs to obtain AppDelegate's Context through the UIApplication. I don't like this method, as I don't like AppDelegate to have too much code piled together. I've organized this method

The code inherited by CoreData is decoupled and made into a singleton class separately 

Project structure diagram

 

Project file description 
The core file of CoreData is 
1.XPStoreManager (singleton class for managing CoreData) 
2.CoredataDemo.xcdatamodeld (CoreData data model file)
 3.Student+CoreDataProperites.swift and Student.swift (student object) 
4.ViewController.swift and Main.storyboard are sample code

Detail code 

1. XPStoreManager.swift
Singleton class for CoreData data management

//
// XPStoreManager.swift
// CoreDataDemo
//
// Created by xiaopin on 16/9/16.
// Copyright © 2016Year xiaopin.cnblogs.com. All rights reserved.
//
import CoreData
/// Local database management class: it is usually written in AppDelegate, but it can be separated in this way
class XPStoreManager {
 //Singleton writing style
 static let shareInstance = XPStoreManager()
 private init() {
 }
 // MARK: - Core Data stack
 lazy var applicationDocumentsDirectory: NSURL = {
  // The directory that the application uses to store the Core Data store file. This code uses a directory named "com.pinguo.CoreDataDemo" in the application's documents Application Support directory.
  let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
  print("\(urls[urls.count - 1])")-1
  return urls[urls.count - 1])-1}
 }()
 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 = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")!
  return NSManagedObjectModel(contentsOfURL: modelURL)!
 }()
 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.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
  var failureReason = "There was an error creating or loading the application's saved data."
  do {
   try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
  }
   // Report any error we got.
   var dict = [String: AnyObject]()
   dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
   dict[NSLocalizedFailureReasonErrorKey] = failureReason
   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 = {
  // 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
  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 here to execute a 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 

Written for the addition, deletion, modification, and query of this student object 

//
// Student.swift
// CoreDataDemo
//
// Created by cdmac on 16/9/12.
// Copyright © 2016Year xiaopin.cnblogs.com. All rights reserved.
//
import Foundation
import CoreData
class Student: NSManagedObject {
 // Insert code here to add functionality to your managed object subclass
 /*
  Commonly involved situations include: addition, deletion, modification, single object query, pagination query (all, conditional query, sorting), whether the object exists, batch addition, batch modification
  */
 /// Determine if the object exists, where obj parameter is the dictionary of the current property
 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 filtering parameters
  let stuId = obj["stuId"]
  let name = obj["name"]
  //Method one
  let predicate1 = NSPredicate(format: "stuId = %@", stuId!)
  let predicate2 = NSPredicate(format: "name = %@", name!)
  //Composite filtering conditions
  //or, and, not, means: or and not, those who understand databases should easily understand
  let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2])
  //let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2])
  fetchRequest.predicate = predicate
  //Method two
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ or name = %@", stuId!, name!)
  //fetchRequest.predicate = NSPredicate(format: "stuId = %@ and name = %@", stuId!, name!)
  do{
   let fetchObjects: [AnyObject]&63; = try context.executeFetchRequest(fetchRequest)
   return fetchObjects&63;.count > 0 &63; true : false
  }
   fatalError("existsObject \(error)")
  }
  return false
 }
 /// Add object, the obj parameter is the dictionary of current properties
 class func insertObject(obj: [String: String]) -> Bool {
  //If an object exists, return
  if existsObject(obj) {
   return false
  }
  //Get the data context object manager
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Create student object
  let stu = NSEntityDescription.insertNewObjectForEntityForName("Student",
                  inManagedObjectContext: context) as! Student
  //Object assignment
  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"]!)
  //Save
  do {
   try context.save()
   print("Save successful!")
   return true
  }
   fatalError("Cannot save: \(error)")
  }
  return false
 }
 /// Delete object
 class func deleteObject(obj:Student) -> Bool{
  //Get the data context object manager
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Method one: For example, the list has already been obtained from the database, directly call the default deletion method of CoreData
  context.deleteObject(obj)
  XPStoreManager.shareInstance.saveContext()
  //Method two: Through the obj parameter, for example: id, name, query an object through such conditions one by one, and delete this object from the database
  //Code: omitted
  return true
 }
 /// Update object
 class func updateObject(obj:[String: String]) -> Bool {
  //obj parameter description: The field information of the current object to be updated, the unique identifier is required, and the others are optional attributes
  let context = XPStoreManager.shareInstance.managedObjectContext
  let oid = obj["stuId"]
  let student:Student = self.fetchObjectById(Int(oid!)!)! as! Student
  //Traverse parameters and then replace the corresponding parameters
  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("If there are other parameters that need to be modified, similar")
   }
  }
  //Execute update operation
  do {
   try context.save()
   print("Update successful!")
   return true
  }
   fatalError("Cannot save: \(error)")
  }
  return false
 }
  /// Query objects
 class func fetchObjects(pageIndex:Int, pageSize:Int) -> [AnyObject]? {
  //Get the data context object manager
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Declare data request
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  fetchRequest.fetchLimit = pageSize //Page size
  fetchRequest.fetchOffset = pageIndex * pageSize //Page number
  //Set query conditions: refer to exsitsObject
  //let predicate = NSPredicate(format: "id= '1", "
  //fetchRequest.predicate = predicate
  //Set sorting
  //Sort by student ID in descending order
  let stuIdSort = NSSortDescriptor(key: "stuId", ascending: false)
  //Sort by name in ascending order
  let nameSort = NSSortDescriptor(key: "name", ascending: true)
  let sortDescriptors:[NSSortDescriptor] = [stuIdSort,nameSort]
  fetchRequest.sortDescriptors = sortDescriptors
  //Query operation
  do {
   let fetchedObjects:[AnyObject]? = try context.executeFetchRequest(fetchRequest)
   //Iterate over the query results
   /*
   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("Cannot save: \(error)")
  }
  return nil
 }
  /// Query an object by ID
 class func fetchObjectById(oid:Int) -> AnyObject63;{}}
  //Get context object
  let context = XPStoreManager.shareInstance.managedObjectContext
  //Create query object
  let fetchRequest:NSFetchRequest = NSFetchRequest(entityName: "Student")
  //Construct parameters
  fetchRequest.predicate = NSPredicate(format: "stuId = %@", String(oid))
  //Execute code and return results
  do{
   let results:[AnyObject]? = try context.executeFetchRequest(fetchRequest)
   return results![0]63.count > 0 {
    catch{
   }
  }
   fatalError("Querying individual object fatal error: \(error)")
  }
  return nil
 }
}

4.ViewController.swift 

Specific usage: 

//
// ViewController.swift
// CoreDataDemo
//
// Created by cdmac on 16/9/11.
// Copyright © 2016Year pinguo. All rights reserved.
//
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()
  // Do any additional setup after loading the view, typically from a 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: UITableViewDataSource, UITableViewDelegate {
 //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
 }
 //Cell loading
 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!
 }
 //Selected
 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 {
   //Obtain the current object
   let student:Student = self.dataArray![indexPath.row] as! Student
   //Delete Local Storage
   Student.deleteObject(student)
   //Refresh Data Source
   self.dataArray?.removeAtIndex(indexPath.row)
   //self.dataArray = Student.fetchObjects(0, pageSize: 20)
   //Delete Cell
   tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  }
 }
 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  return .Delete
 }
 func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
  return "Delete"
 }
}

Running Effect Diagram

 

Source Code Download:CoreDataDemo.zip

That's all for this article. I hope it will be helpful to everyone's learning and also hope everyone will support the Yelling Tutorial more.

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You May Also Like