[English]
iOSではCore DataというO/Rマッピングツールを使用してSqliteにデータを保存します。
環境: Xcode 8.3, Swift 3
1.準備
まずプロジェクト作成時に「Use Core Data」にチェックを入れます。

これによりAppDelegateにCore Dataのオブジェクトが生成されます。
次に[プロジェクト名.xcdatamodeld]でDBのテーブルレイアウトを定義します。

テーブルにImageを保存したい場合は、データ型を「Binary Data」とし、「Allows External Storage」にチェックを入れます。

Allows External Storageを指定すると、大きなサイズのImageの場合は、ImageのURLが保存される様になります。
これを指定せずにCore Dateで大きさなサイズのImageを保存すると、保存に時間がかかったり、悪い時にはメモリ使用量が一気に増えてアプリケーションがクラッシュする時があります。
テーブルレイアウトの定義が完了したら、XCodeの[Editor]-[Create NSManagedObject Subclass]を実行します。
この操作で定義したテーブルのクラス(NSManagedObject)が生成されます。
これにて準備は完了です。
あとはCore Dataを使用するクラスの先頭で「import Core Data」を宣言します。
2.データの新規追加(INSERT)
まずAppDelegateのNSManagedObjectContextを生成します。
次にNSMangedObjectContextから1で生成したテーブルのNSManagedObjectを生成します。
このNSMnagedObjectに値を設定して、saveメソッドを呼び出します。
説明よりもコードを見た方が早いと思いますので、コードをどうぞ。
import UIKit
import CoreData
class ViewController: UIViewController {
private var imageView:Array<UIImageView!> = Array<UIImageView!>()
func saveImageData(){
//UIImageViewの画像をSqliteに保存
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.データの検索(SELECT)
次にデータを検索する場合のコードです。
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()
}
検索条件を指定する時はNSPredicateを使用します。
ソート条件を指定する時はNSSortDescriptorを使用します。
(昇順の場合はascendingをtrueにし、降順の場合はascendingをfalseにします。)
尚、imageをロードした時、保存時にimageの向きが下向きであれば、imageの上下を反転しておきます。
3.データの上書き(UPDATE)
データを上書きする時は、対象のデータを一度検索して、その値を新しい値に上書きます。
コードは以下の様になります。
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
//検索した値を取得
index = fetchResult.valueForKey("index") as! Int
//検索した値をUPDATE
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.データの削除(DELETE)
削除を行う場合も、まず一度削除対象のデータを検索してから、そのデータに削除のマークをつける手順で行います。
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
//削除のマークをつける
managedContext.deleteObject(object)
}
//削除のマークをつけたデータを保存することで削除が実行される
try managedContext.save()
}catch let error{
NSLog("\(error)")
}
managedContext.reset()
}
Write a comment