English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
最近在学习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.)