Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 1001 - 新たに再出発の誓い... Core Dataに取り組む

長い中断があり、50親父のアプリ開発計画も中断しそうになっていました。プログラミング勉強に割ける時間も僅かで、集中して勉強できないので仕方ないかもしれませんね。理解力もかなり落ちていて他人のコードが読めない(理解できない)ことも多々あります。

Swift言語の変化についていくのも大変です。勉強をはじめた頃はバージョン1だったのに、3年で4.2まで変化を遂げました。Swift言語はダイナミックに変化しているけど、未だにiOSの深層ではobjective-cも脈々と動き続けており、その理解も必要な時があります(T_T)

まあ、愚痴を言っていても仕方ないのでCore Dataの勉強に取りかかります。

Swift 3で導入されたNSPersistentContainerクラスは、データーベースであるSQLiteを利用すためのAPIを統括するような立場です。

データーベースで扱うデータは、一つ一つentity(エンティティー)と呼ばれます。これはNSManagedObjectクラスのインスタンスとして扱われるんです。複数のNSMangaedObjectクラスをまとめるのがNSManagedObjectModelで、それをコントロールするのがNSPersistentContainerと考えればいいでしょう。

プロジェクトを作成するときに「Use Core Data」チェックマークを入れておくと、Core Dataに関する初期ファイルが色々導入され初心者には便利です。しかし、このチェックマークは万能ではありません。色々と手入れしないと使えないんです。

まず、「プロジェクト名.xcdatamodeld」というファイルが作られています。これがデータ・モデル(NSManagedObjectMode)です。ビジュアルにentityを設定することができるのでデーターベース設計をするのが楽しくなるでしょう。

Swiftで遊ぼう! - 612 - CoreDataMyDemo - Swiftで遊ぼう! on Hatena で扱っているCoreDataMyDemo.xcdatamodeldをみると、entityは「Users」です。このentityは「NSManagedObject」クラスです。

ここでUtilitiesエリアからData Model Inspectorを選択すると以下のイメージ*1のように、「Codgen」という項目があり、デフォルトでは「Class Definition」が選択されています。クラスとして扱えるけど、コードでカスタマイズできません。

f:id:yataiblue:20180614132403j:plain

コードでカスタマイズできないということは、コードで扱うとき、必ず「NSManagedObject」クラスとして取り扱う必要があり少し面倒くさいです。カスタムクラスで扱うために、「Manual/None」を選択して、Moduleに「Current Product Module」を選んで、メニューの「Editor」→「Create NSManagedObject Subclass...」を選ぶと、NSManagedOnjectのサブクラスである「Users」クラスが生成されます。

let entity = 
  NSEntityDescription.entity(forEntityName: "Users", in: context)
        
let user = Users.init(entity: entity!, insertInto: context)
user.username = "Yuji"
user.password = "1234"
        
do {
    try context.save()
            
} catch let error as NSError {
    print("Error: \(error)")
}
        
let request = 
  NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
        
do {
    let result = try context.fetch(request)
    for data in result as! [Users] {
        print(data.username!)
        print(data.password!)
    }
            
} catch let error as NSError {
     print("Error: \(error)")
}

上記のように書き換えるとUsersクラスを扱えるようになり、そのプロパティである「username」や「password」を簡単に変更できるようになります。こうした方が便利ですよね。

*1:このイメージはXcode9.4です。Xcode10.0はβ版のためイメージが使えません