Help us understand the problem. What is going on with this article?

[Swift]ローカルファイルを使用せずにCoreDataをオンメモリ化する方法

More than 5 years have passed since last update.

どーも。寺坂です

最近、CoreDataのテストを書いている時に、

ローカルのファイルを汚したくないなー
と思ったので、 メモリ上でデータ管理を行う方法 を紹介します。

前提:CoreDataとは

CoreDataは、データを永続化するためのフレームワークの一つです。

多くの場合、SQLiteを利用して使用され、
端末内に.sqliteファイルを作成して、そこにデータを保存します。

このままだと、ファイルが汚れてゴミが残ったり、
読み書きが発生して遅くなりったりするので、

今回は、このCoreDataの保存先を
メモリ上に変更する方法を紹介したいと思います。

※ 使用するコードは、Xcodeでデフォルト生成されるものを元にします。

実装1.NSManagedObjectModel

NSManagedObjectModelは、CoreDataのEntityを定義したものです。

これは .momdで保存されるファイルに書かれているので、
まずはそのファイルパスを取得します。

class CoreDataInMemory {

  let myModuleName = "モジュール名を記述"

  lazy var managedObjectModel: NSManagedObjectModel = {
     let modelURL = NSBundle(forClass: CoreDataInMemory.self).URLForResource(myModuleName, withExtension: "momd")!
     return NSManagedObjectModel(contentsOfURL: self.modelURL)!
     }()

}

実装2.NSPersistentStoreCoordinator

managedObjectModelを呼んで、
NSPersistentStoreCoordinatorを生成します。

ここでNSInMemoryStoreType を指定することによって、
メモリ上で動作するようになります。

参考:CoreData Framework Reference NSPersistentStoreCoordinator Class Reference - Store Types

class CoreDataInMemory {...

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
        var coordinator:NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        if coordinator?.addPersistentStoreWithType( NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil) == nil {
            coordinator = nil
        }
        return coordinator
        }()

...
}

実装3.NSManagedObjectContext

NSManagedObjectContextの生成。

ここで先ほどのcoordinatorを使用します。

let coordinator = self.persistentStoreCoordinator
managedObjectContext.persistentStoreCoordinator = coordinator
を忘れると動かないので、ご注意を。

class CoreDataInMemory {...

    lazy var managedObjectContext: NSManagedObjectContext? = {
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext()
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
        }()

...
}

実装4.saveContext()

データ保存はそのままです。

class CoreDataInMemory {...

    func saveContext() {
        var error:NSError? = nil
        managedObjectContext?.save(&error)
        if let e = error {
            log.error( CoreDataError(cause: e).description )
        }
    }

...
}

実装5.解放

nilを入れましょう。

class CoreDataInMemory {...

    func releaseMemory(){
        persistentStoreCoordinator = nil
        managedObjectContext = nil
    }

...
}

まとめ

以下のようなクラスができました。

テストの時はこちらを使うようにすると、
ストレスレステストができますね。

class CoreDataInMemory {

    let myModuleName = "モジュール名を記述"

    lazy var managedObjecar: NSManagedObjectModel = {
        let modelURL = NSBundle(forClass: CoreDataInMemory.self).URLForResource(myModuleName, withExtension: "momd")!
        return NSManagedObjectModel(contentsOfURL: self.modelURL)!
        }()

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
        var coordinator:NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        if coordinator?.addPersistentStoreWithType( NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil) == nil {
            coordinator = nil
        }
        return coordinator
        }()


    lazy var managedObjectContext: NSManagedObjectContext? = {
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext()
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
        }()


    func saveContext() {
        var error:NSError? = nil
        managedObjectContext?.save(&error)
        if let e = error {
            log.error( CoreDataError(cause: e).description )
        }
    }

    func releaseMemory(){
        persistentStoreCoordinator = nil
        managedObjectContext = nil
    }

}

i_terasaka
エンジニア一年目のぺーぺーです。 ScalaとかSwiftとかAngularとか、いろいろ。
septeni-original
技術を磨き続けることでネットサービスを軸とした新たな体験を世界に提供します。
http://www.septeni-original.co.jp/index.html
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away