Core Dataのデータベースの保存場所を切り替える
保存場所を固定的に変更する方法は前回の記事を参照
今回の保存場所の切り替えというのは既に使用している A.sqlite ファイルから別の B.sqlite を使用するようにしたりまた A.sqlite に戻したりするという意味での動的な切り替え。
利用ケースの想定としては
- ローカルDBとクラウド上のデータのローカルキャッシュのDBを分けて管理する *1
- サービスのアカウント毎にローカルキャッシュのDBファイルを切り替える *2
- ローカルデータを削除せず、テストデータを読み込ませてまた後にローカルデータへ戻す *3
等々。
実装
実装はシンプル。Xcode のテンプレートに沿って AppDelegate への実装とする。
まず NSPersistentContainer
の管理クラス(ここでは AppDelegate)にDBのURLを設定出来るようにする。
#import <UIKit/UIKit.h> #import <CoreData/CoreData.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (readonly, strong) NSPersistentContainer *persistentContainer; @property (strong) NSURL *databaseURL; // <-- here - (void)saveContext; @end
databaseURL が設定されたら値を保持して、persistentContainer を nil にする。
- (void)setDatabaseURL:(NSURL *)databaseURL { _databaseURL = databaseURL; _persistentContainer = nil; }
persistentContainer の初期化コードにこの databaseURL を使って初期化するよう仕込む。
初期化処理は次に persistentContainer
メソッドが呼ばれる時に実行される。
- (NSPersistentContainer *)persistentContainer { @synchronized (self) { if (_persistentContainer == nil) { _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"AppName"]; if (self.databaseURL) { NSPersistentStoreDescription *storeDescription = _persistentContainer.persistentStoreDescriptions.firstObject; storeDescription.URL = self.databaseURL; } [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { if (error != nil) { NSLog(@"Unresolved error %@, %@", error, error.userInfo); abort(); } }]; } } return _persistentContainer; }
以下の様に databaseURL を変更した後に persistentContainer へのアクセスが発生すると指定の場所へDBが作られる事になる。
NSURL *databaseURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:@"Test.sqlite"]; appDelegate.databaseURL = databaseURL;
もしかするとテンプレートの persistentContainer
メソッドの様に _persistentContainer が nil の場合に初期化処理が走るのではなく、初期化処理をメソッドとして用意してやって、databaseURL の設定と共に初期化処理を明示的に実行させてやっても良いかも知れない。
サンプルコードの全体は以下。
(その他の AppDelegate の処理は割愛して Core Data の実装のみ記述)