[iOS]Core Data Programming

[日本語]

 

You can do database programming by Core Data, O/R mapping tool for Sqlite, on iOS.

 

Environment: Xcode 8.3, Swift 3

 

1.Preparation

At first, Check "Use Core Data" when project is created.

And code of Core Data Objects are created in AppDelegate.

 

Next, select "[project name].xcdatamodeld" and define table layout.

 

To save UIImage, select "Binary Data" in Type and check "Allow External Storage". 

When the size of UIImage is big, URL of UIImage is saved in Core Data.

When you don't check "Allow External Storage", the time of saving core data will take and memory utilization will be increase instantly, and an application will crash.

 

After table layout definition, execute [Editor]-[Create NSManagedObject Subclass] on Xcode.

And class of table layout definition, NSManagedObject is created.

 

At last, declare "import Core Data" at the top of class using Core Data.

 

2.How to INSERT

At first, Make NSManagedObjectContext in AppDelegate.

Next, Make NSManagedObject from NSManagedObjectContext.

Let's see code for inserting new data by Core Data.

import UIKit

import CoreData

 

class ViewController: UIViewController {  

 

 private var imageView:Array<UIImageView!> = Array<UIImageView!>() 

 

 func saveImageData(){

  

  //Save UIImageView's image  

  let imageData:NSData! = UIImageJPEGRepresentation(imageView[0].image,1.0)!

  

  var imageOrientation:Int = 0   

  if (imageView[0].image.imageOrientation == UIImageOrientation.Down){    

   imageOrientation = 2   

  }else{    

   imageOrientation = 1   

  }   

 

  let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate   

  let managedContext: NSManagedObjectContext = appDelegate.managedObjectContext   

  let objectEntity:NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Object", inManagedObjectContext: managedContext) as NSManagedObject

  

  objectEntity.setValue(imageData, forKey: "dataValue")   

  objectEntity.setValue(imageOrientation, forKey: "imageOrientation")   

 

  do {    

   try managedContext.save()   

  }catch let error{    

   NSLog("\(error)")   

  }   

  managedContext.reset()  

 }

}

 

2.How to SELECT

Let's see code for selecting data by Core Data.

func LoadData(id:String){

 var minX:CGFloat = 0

 var minY:CGFloat = 0

 var widthValue:CGFloat = 0

 var heightValue:CGFloat = 0

 var imageOrientation:Int = 0

  

 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate   

 let managedContext: NSManagedObjectContext = appDelegate.managedObjectContext

  

 let fetchRequest = NSFetchRequest(entityName: "Object")   

 fetchRequest.returnsObjectsAsFaults = false   

 

 let predicate = NSPredicate(format: "id == %@", id)   

 fetchRequest.predicate = predicate   

 

 let descriptor_1 = NSSortDescriptor(key: "objectType", ascending: true)   

 let descriptor_2 = NSSortDescriptor(key: "createDateTime", ascending: false)   

 fetchRequest.sortDescriptors = [descriptor_1,descriptor_2]

 

 do {     

  let fetchResults: Array = try managedContext.executeFetchRequest(fetchRequest)      

 

  for fetchResult in fetchResults {       

   let object = fetchResult as! NSManagedObject

      

   width = fetchResult.valueForKey("width") as! CGFloat       

   height = fetchResult.valueForKey("height") as! CGFloat       

   minX = fetchResult.valueForKey("minX") as! CGFloat       

   minY = fetchResult.valueForKey("minY") as! CGFloat       

   data = fetchResult.valueForKey("data") as! NSData

      

   image = UIImage(data: data)       

   imageOrientation = fetchResult.valueForKey("imageOrientation") as! Int       

   if (imageOrientation == 2) {         

    image = UIImage(CGImage: image!.CGImage!, scale: image!.scale, orientation: UIImageOrientation.Down)       

   }

 

   imageView.append(UIImageView())             

   imageView[imageView.count - 1].frame = CGRect(x:minX,y:minY,width:widthValue,height:heightValue)       

   imageView[imageView.count - 1].image = image       

   self.view.addSubView(imageView[imageView.count-1])      

  }   

 }catch let error{       

  NSLog("\(error)")   

 }   

 managedContext.reset()  

}

Use NSPredicate for designating searching options.

Use NSSortDescriptor and ascending option for designation sort options.

 

If you road UIImage, check UIImageOrientation.

If UIImageOrientation is down, you must invert UIImage.

 

3.How to UPDATE

Update value of data which is read.

Let's see code for updating data by Core Data.

func UpdateData(id:String, objectType:Int){

    var index:Int = 0

  

 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate   

 let managedContext: NSManagedObjectContext = appDelegate.managedObjectContext   

 

 let fetchRequest = NSFetchRequest(entityName: "Object")   

 fetchRequest.returnsObjectsAsFaults = false   

 

 let predicate = NSPredicate(format: "id == %@ And objectType == %d", id, objectType)   

 fetchRequest.predicate = predicate   

 

 do {    

  let fetchResults: Array = try managedContext.executeFetchRequest(fetchRequest)     

 

  for fetchResult in fetchResults {      

   let object = fetchResult as! NSManagedObject

 

   //Get value

   index = fetchResult.valueForKey("index") as! Int      

 

   //Update value     

   object.setValue(imageView[index].frame.width, forKey: "width")      

   object.setValue(imageView[index].frame.height, forKey: "height")      

   object.setValue(imageView[index].frame.minX, forKey: "minX")      

   object.setValue(imageView[index].frame.minY, forKey: "minY")      

 

   let imageData:NSData! = UIImageJPEGRepresentation(imageView[index].image,1.0)!      

   object.setValue(imgeData, forKey: "data")

 

   var imageOrientation:Int = 0   

   if (imageView[index].image.imageOrientation == UIImageOrientation.Down){    

    imageOrientation = 2   

   }else{    

    imageOrientation = 1   

   }

   object.setValue(imageOrientation, forKey:"imageOrientation")  

  }     

  try managedContext.save()   

 }catch let error{    

  NSLog("\(error)")   

 }  

 managedContext.reset()  

}

 

4.How to DELETE

Delete data which is read.

func DeleteData(id:String,objectType:Int){   

 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate   

 let managedContext: NSManagedObjectContext! = appDelegate.managedObjectContext

  

 let fetchRequest = NSFetchRequest(entityName: "Object")   

 fetchRequest.returnsObjectsAsFaults = false   

 

 let predicate = NSPredicate(format: "id == %@ and objectNo == %d", id,objectType)   

 fetchRequest.predicate = predicate  

 

 do {   

  var fetchResults: Array! = try managedContext.executeFetchRequest(fetchRequest)   

  for fetchResult in fetchResults {    

   let object = fetchResult as! NSManagedObject    

 

   //Making a mark as deleted   

   managedContext.deleteObject(object)   

  }

        //Exec saving -> Delete data

  try managedContext.save()  

 }catch let error{    

  NSLog("\(error)")   

 }   

 managedContext.reset()  

}