15
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-04-16

どーも。寺坂です

最近、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
    }
    
}

15
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?