質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.34%

SwiftのCoreDataについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,363

score 28

いろいろな参考サイトをみて、CoreDataを使ってデータの保存、検索などができるようになりました。
ただ、使い方やイメージがあっているかがわかりません。

現在、下記のようなソースでテストしているのですが、数点アドバイスをいただけないでしょうか。
Objective-Cで書いていたため、Swiftの形式にあまりなれていません。

・検索部分での表示について
検索に関してはfetchRequestをして、NSManagedObject型のデータを格納するイメージでいます。

printなどでテスト表示する際に
print(object.value(forKey: "id") as! NSString)
のような方法で取得しております。

こちら別の形で書いたり、短くする方法はないでしょうか。
今の方法だとobject.value(forKey: "id") as! NSStringと毎回指定しなければなりません。
object.idみたいな形でデータを参照したいです。

・削除について
いくつかの参考ソースでは

context.delete(task)
fetchedArray.remove(at: index)

のように2回削除しておりました。

これは元データを検索用配列に格納後、元データのcontextとfetchedArray配列の
2箇所を削除して整合性を取っている認識であっておりますでしょうか。

fetchedArray配列などを使わずに、contextに入れている場合はcontext.delete(task)だけでOKの認識で大丈夫でしょうか。

ソースについては下記となります。

        // 検索
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Task")
        do {
            fetchedArray = try context.fetch(fetchRequest)
            if(!fetchedArray.isEmpty){
                  for i in 0..<fetchedArray.count{
                    let object = fetchedArray[i]
                    print(object.value(forKey: "id") as! NSString)
                    print(object.value(forKey: "name") as! NSString)
                    //NSManagedObject *object = [fetchedArray objectAtIndex:i];
                    //NSString *key   = [object valueForKey:@"id"];
                    //NSString *value = [object valueForKey:@"name"];
                    //NSLog(@"key=%@, value=%@", key, value);                    //print("¥(fetchedArray[i].name!)の国は¥(fetchedArray[i].country!)です")

                    //print((fetchedArray[i].id!) + " " + ¥(fetchedArray[i].name!))
                  }
            }

            //print(fetchedArray.count)
        } catch let error as NSError {
            print("Could not fetch. \(error), \(error.userInfo)")
        }

        /*
        // 書き込み
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "Task",
                                                in: context)!
        let task = NSManagedObject(entity: entity,
                                     insertInto: context)

        task.setValue("1", forKeyPath: "id")
        task.setValue("user", forKeyPath: "name")

        do {
          try context.save()
          fetchedArray.append(task)
          print("保存しました")
        } catch let error as NSError {
          print("Could not save. \(error), \(error.userInfo)")
        }
        */

        // 削除
        /*
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Task")
        do {
            fetchedArray = try context.fetch(fetchRequest)
        } catch let error as NSError {
            print("Could not fetch. \(error), \(error.userInfo)")
        }

        var index:Int = 1
        let task = fetchedArray[index]//ローカルに保存したNSManagedObjectの配列のindexをまず指定

        context.delete(task)
        fetchedArray.remove(at: index)
        (UIApplication.shared.delegate as! AppDelegate).saveContext()
        */
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Task")

↑ここが間違いです。

エンティティのクラス名が分からないのでTaskというクラス名だと仮定します。
この仮定の場合、NSFetchRequestの型パラメータをTaskに変更します。

let fetchRequest = NSFetchRequest<Task>(entityName: "Task")

すると自動的にcontext.fetch(fetchRequest)の戻り値は[NSManagedObject]ではなく[Task]に変わります。
Taskの配列になりますので、object.idのようなプロパティアクセスが可能です。
(fetchedArrayの宣言部分はそのように変更しておいてください)


削除について
fetchedArrayは表示などのために一時的にcontextから取り出したものです。これはcontext内からのコピーと思ってください。
表示などを更新するためにfetchedArrayから削除する必要がありますが、これを行ってもcontext内にはオリジナルが残っています。
ですのでオリジナルを削除するためにcontext.delete(task)が必要です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

めちゃくちゃわかりやすい回答ありがとうございます!
入門書だと使い方など乗ってないので助かりました。

そのような便利な機能があるのですね!エンティティ名についても失礼しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る