どらちゃんのポッケ

R・統計・技術メモなど勉強ログ置き場

xcode5でcore dataのチュートリアルを動かしてみる

core dataを使う

core dataとは

  • モデルオブジェクトを永続化するためのフレームワーク
  • Core Dataはデータの永続化に SQLiteを使用している
  • O/Rマッパー

サンプル

プロジェクトを生成する

  • empty projectにする
  • 「use core data」にチエックを入れておく
  • f:id:sleeping_micchi:20140201185719p:plain

  • プロジェクト作成が終了すると、coreData.xcdatamodeld が生成されている

    • f:id:sleeping_micchi:20140201185751p:plain

    • このcoreData.xcdatamodeldがcore dataを使う上でエンティティが格納されるファイル

entity editorでエンティティを作っていく

  • データのモデルを定義していく
  • f:id:sleeping_micchi:20140201185809p:plain

ストーリーボードの追加と設定

  • New > File > iosの中からストーリーボードを選択して追加
    • XIBは使用しない
  • ターゲットのgeneralのところから、mainのストーリーボードを設定する

    • f:id:sleeping_micchi:20140201185843p:plain

  • ストーリーボードを使用するようにしたので、Windowは使わないためAppDelegate.mを修正する

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
          // Override point for customization after application launch.
          self.window.backgroundColor = [UIColor whiteColor];
          [self.window makeKeyAndVisible];
          return YES;
      }
    

    から

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          return YES;
      }
    

    へ変更する

ViewControllerの追加(ファイルの追加)

  • プロジェクトを右クリック

ViewControllerの追加(ストーリーボードへの追加)

  • ストーリーボードで、ViewControllerをドラッグ&ドロップ
  • f:id:sleeping_micchi:20140201185922p:plain

    • アイデンティティインスペクタで上で作成したViewControllerのClassを指定
    • ストーリーボードのViewControllerとソースのViewControllerのマッピング記述
      • この指定を行わないと、UI部品とコードの接続ができない
    • f:id:sleeping_micchi:20140201190009p:plain

ラベルやボタンの配置

  • テキストフィールドとか、ボタンとかを接続する

saveボタンを押したときに保存するようにする

    - (IBAction)save:(id)sender {
        AppDelegate *appDelegate =
        [[UIApplication sharedApplication] delegate];

        NSManagedObjectContext *context =
        [appDelegate managedObjectContext];
        NSManagedObject *newContact;
        newContact = [NSEntityDescription
                      insertNewObjectForEntityForName:@"Contact" //Entityの名前を指定
                      inManagedObjectContext:context];
        [newContact setValue: _nameField.text forKey:@"name"]; //Atributeの各項目を指定
        [newContact setValue: _addressField.text forKey:@"address"];
        [newContact setValue: _phoneField.text forKey:@"phone"];

        //テキストフィールドの初期化
        _nameField.text = @"";
        _addressField.text = @"";
        _phoneField.text = @"";
        NSError *error;
        [context save:&error];
        _statusLabel.text = @"Contact saved";
    }
  • 下記のようなエンティティの設定にしているので、これにあわせている
    • f:id:sleeping_micchi:20140201190155p:plain

Findを押したときに検索して、該当カウントを調べる

- (IBAction)find:(id)sender {
    AppDelegate *appDelegate =
    [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *context =
    [appDelegate managedObjectContext];

    //Entityの設定
    NSEntityDescription *entityDesc =
    [NSEntityDescription entityForName:@"Contact" //Entityの名前を指定
                inManagedObjectContext:context];

    //NSFetchRequest検索条件オブジェクトの生成
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDesc];

    //NSPredicate は、NSArray で要素をフィルターするための条件を表したり、
    //Core Data で取ってくるデータの条件を表すためのクラス
    NSPredicate *pred =
    [NSPredicate predicateWithFormat:@"(name = %@)",
     _nameField.text];
    [request setPredicate:pred];
    NSManagedObject *matches = nil;

    NSError *error;
    //DBから取得
    NSArray *objects = [context executeFetchRequest:request
                                              error:&error];

    if ([objects count] == 0) {
        _statusLabel.text = @"No matches";
    } else {
        matches = objects[0];
        _addressField.text = [matches valueForKey:@"address"];
        _phoneField.text = [matches valueForKey:@"phone"];
        _statusLabel.text = [NSString stringWithFormat:
                        @"%lu matches found", (unsigned long)[objects count]];
    }
}
  • NSEntityDescription
    • 対象のエンティティを指定する
  • NSFetchRequest
    • 検索条件を指定するオブジェクト
    • setFetchBatchSize:50などで取得する上限を指定
  • NSManagedObjectContext
    • CoreDataのテンプレートを生成した際に、AppDelegateに記述されている − NSManagedObjectContextを通じてCRUD操作を行う
  • NSPredicate
    • NSArray で要素をフィルターするための条件を表すためのクラス
    • Core Data で取ってくるデータの条件を表すためのクラス

動かしてみる

  • 動くはず
  • f:id:sleeping_micchi:20140201190217p:plain

シュミレータで動かした時のsqliteの場所

  • 深い位置にある

    • (隠しファイル)ライブラリ > ApplicationSupport > iphoneSimulator > 7.0.3 > Application >(ランダム)> Documents > sqlファイル
  • f:id:sleeping_micchi:20140201190234p:plain

  • f:id:sleeping_micchi:20140201190253p:plain

見てみる

  • f:id:sleeping_micchi:20140201190324p:plain

  • CoreDataで生成されたものはZプレフィックスがつくようだ

まだまだ、これから・・・

  • テーブルの結合とか本格的な使い方をするには勉強が必要そう・・・。
  • この本とか?ちょっと古いかもだけど