English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
最近在学习CoreData, 因为项目开发中需要,特意学习和整理了一下,整理出来方便以后使用和同行借鉴。目前开发使用的Swift语言开发的项目。所以整理出来的是Swift版本,OC我就放弃了。 虽然Swift3 이미 있습니다. 현재 정리한 버전은 Swift입니다2 의 Swift 3 다음은 새로운 기능이 있습니다. 추가로 조정이 필요하며, 나중에 정리할 예정입니다.
CoreData를 상속받는 방법은 두 가지가 있습니다:
프로젝트 생성 시 통합
이 방법은 AppDelegate에 자동으로 상속되며, 호출할 때는 UIApplication을 통해 AppDelegate를 얻어서 Context를 얻어야 합니다. 저는 이 방법을 좋아하지 않으며, AppDelegate에 너무 많은 코드가 모여 있지 않기를 원합니다. 이렇게 정리했습니다
CoreData를 상속받은 코드를 단일 인스턴스 클래스로 분리하여 만듭니다
프로젝트 구조도
프로젝트 파일 설명
CoreData의 핵심 파일은
1.XPStoreManager(CoreData를 관리하는 단일 인스턴스 클래스)
2.CoredataDemo.xcdatamodeld (CoreData 데이터 모델 파일)
3.Student+CoreDataProperites.swift 및 Student.swift (학생 객체)
4. ViewController.swift 및 Main.storyboard은 예제 코드입니다
세부 코드
1. XPStoreManager.swift
CoreData 데이터 관리 단일 인스턴스 클래스
// // XPStoreManager.swift // CoreDataDemo // // xiaopin에 의해 만들어졌습니다. 16/9/16. // 저작권 © 2016年 xiaopin.cnblogs.com. All rights reserved. // import CoreData /// 로컬 데이터베이스 관리 클래스: 기본적으로 AppDelegate에 작성되지만, 이렇게 분리할 수 있습니다 class XPStoreManager { //단일 인스턴스 작성 방법 static let shareInstance = XPStoreManager() private init() { } // MARK: - Core Data 스택 lazy var applicationDocumentsDirectory: NSURL = { // 애플리케이션이 Core Data 저장 파일을 저장하는 디렉토리입니다. 이 코드는 애플리케이션의 문서 Application Support 디렉토리에 "com.pinguo.CoreDataDemo" 이름의 디렉토리를 사용합니다. let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) print("\(urls[urls.count-1])") return urls[urls.count-1] }() lazy var managedObjectModel: NSManagedObjectModel = { // 애플리케이션의 관리된 객체 모델. 이 속성은 선택 사항이 아닙니다. 애플리케이션이 모델을 찾고 로드할 수 없다면 그것은 중요한 오류입니다. let modelURL = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")! return NSManagedObjectModel(contentsOfURL: modelURL)! }() lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { // 애플리케이션의 지속적인 저장 관리자 조정자. 이 구현은 애플리케이션의 저장소를 추가한 후 조정자를 생성하고 반환합니다. 이 속성은 선택 사항이며, 저장소 생성이 실패할 수 있는 합법적인 오류 상태가 있기 때문입니다. // 콘티너와 스토어를 생성하세요. let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") var failureReason = \ do { try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil) } // 얻은 모든 오류를 보고하세요. var dict = [String: AnyObject]() dict[NSLocalizedDescriptionKey] = \ dict[NSLocalizedFailureReasonErrorKey] = failureReason dict[NSUnderlyingErrorKey] = error as NSError let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) // 적절하게 오류를 처리하는 코드로 이를 대체하세요. // abort()는 애플리케이션에 충돌 로그를 생성하고 종료하도록 합니다. 이 함수는 개발 중에는 유용할 수 있지만 배포 애플리케이션에서는 사용하지 않는 것이 좋습니다. NSLog("해결되지 않은 오류(wrappedError), \(wrappedError.userInfo)") abort() } return coordinator }() lazy var managedObjectContext: NSManagedObjectContext = { // 애플리케이션의 관리된 객체 컨텍스트를 반환합니다(이는 이미 애플리케이션의 영구 저장소 컨텍터와 연결되어 있습니다.). 이 프로퍼티는 옵셔널입니다. 왜냐하면 오류 조건이 컨텍스트 생성을 실패시킬 수 있는 합리적인 상황이 있기 때문입니다. let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }() // MARK: - Core Data Saving 지원 func saveContext () { if managedObjectContext.hasChanges { do { try managedObjectContext.save() } // 이 구현을 적절히 오류를 처리하는 코드로 대체하세요. // abort()는 애플리케이션에 충돌 로그를 생성하고 종료하도록 합니다. 이 함수는 개발 중에는 유용할 수 있지만 배포 애플리케이션에서는 사용하지 않는 것이 좋습니다. let nserror = error as NSError NSLog("Unresolved error \(nserror), \(nserror.userInfo)") abort() } } } }
2.AppDelegate.swift
이 줄에 코드를 추가하여 종료 후 저장을 수행합니다
func applicationWillTerminate(application: UIApplication) { // 애플리케이션이 종료될 준비를 하고 있을 때 호출됩니다. 적절하다면 데이터를 저장합니다. 또한 applicationDidEnterBackground: 를 참조하세요. // 애플리케이션이 종료되기 전에 애플리케이션의 관리된 객체 컨텍스트에 변경 사항을 저장합니다. XPStoreManager.shareInstance.saveContext() }
3.Student.swift
이 학생 객체에 대한 추가删除修改查询를 작성했습니다
// // Student.swift // CoreDataDemo // // cdmac에 의해 만들어짐 on 16/9/12. // 저작권 © 2016年 xiaopin.cnblogs.com. All rights reserved. // import Foundation import CoreData class Student: NSManagedObject { // Insert code here to add functionality to your managed object subclass /* 보통涉及到的情况有:增加删除修改,单一对象查询,分页查询(所有,条件查询,排序),对象是否存在,批量增加,批量修改 */ /// 오브젝트가 존재하는지 확인합니다, obj 파라미터는 현재 속성의 딕셔너리입니다 class func exsitsObject(obj:[String:String]) -> Bool { //관리 데이터 객체의 컨텍스트를 가져옵니다 let context = XPStoreManager.shareInstance.managedObjectContext //데이터 요청을 선언합니다 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!) do{ let fetchObjects:[AnyObject]63; = try context.executeFetchRequest(fetchRequest) return fetchObjects63;.count > 063; true : false } fatalError("exsitsObject \(error)") } return false } /// 添加对象, obj参数是当前属性的字典 class func insertObject(obj: [String:String]) -> Bool { //如果存在对象了就返回 if exsitsObject(obj) { return false } //데이터 관리 객체를 가져옵니다 let context = 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"]!) //저장 do { try context.save() print("저장 성공!") return true } fatalError("저장할 수 없음: \(error)") } return false } /// 객체 삭제 class func deleteObject(obj:Student) -> Bool{ //데이터 관리 객체를 가져옵니다 let context = XPStoreManager.shareInstance.managedObjectContext //방법 하나: 예를 들어, 목록이 데이터베이스에서 가져온 객체이면, CoreData 기본 삭제 메서드를 직접 호출 context.deleteObject(obj) XPStoreManager.shareInstance.saveContext() //방법 두 번째: obj 매개변수를 통해 예를 들어: id, name, 이러한 조건으로 하나의 객체를 검색하여 이 객체를 데이터베이스에서 삭제 //코드: 생략 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) return results![0]63;.count > 0 { catch{ } } fatalError("객체를 검색하는 중 치명적인 오류: \(error)") } return nil } }
4.ViewController.swift
특정 사용 방법:
// // ViewController.swift // CoreDataDemo // // cdmac에 의해 만들어짐 on 16/9/11. // 저작권 © 2016연 pinguo. 모든 권리 보호됨. // 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() // 뷰를 로드한 후 추가 설정을 수행하십시오. 일반적으로 nib에서부터. self.dataArray = Student.fetchObjects(0, pageSize: 20) self.tableView.reloadData() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // 모든 재생 가능한 자원을 처리할 수 있는 경우 해제. } @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 = "남자" if stu.sex?.intValue != 1 { sexStr = "여자" } label1.text = "\(stu.stuId!) \(stu.name!) \(sexStr) \(stu.classId!)" label2.text = "http:"//xiaopin.cnblogs.com" return cell! } //선택 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 { //현재 객체 가져오기 let 학생:Student = self.dataArray![indexPath.row] as! Student //로컬 저장소에서 삭제 Student.deleteObject(student) //데이터 소스 새로 고침 self.dataArray?.removeAtIndex(indexPath.row) //self.dataArray = Student.fetchObjects(0, pageSize: 20) //셀 삭제 tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) } } func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { return .Delete } func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? { return "삭제" } }
실행 이미지
소스 코드 다운로드:CoreDataDemo.zip
이것이 이 문서의 전체 내용입니다. 여러분의 학습에 도움이 되길 바라며, 다양한 지원을 해 주시길 부탁드립니다.
언급: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권은 원저자에게 있으며, 인터넷 사용자가 자발적으로 기여하고 업로드한 내용입니다. 이 사이트는 소유권을 가지지 않으며, 인공 편집을 하지 않았으며, 관련 법적 책임을 부담하지 않습니다. 저작권 침해가 의심되는 내용이 있으면 이메일을 보내주시기 바랍니다: notice#oldtoolbag.com(보내는 이메일에서 #을 @으로 변경하십시오. 신고하시고 관련 증거를 제공하시면, 사실이 확인되면 이 사이트는 즉시 저작권 침해 내용을 삭제합니다。)