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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

Q&A

解決済

1回答

575閲覧

リレーションでの保存

pon3428

総合スコア14

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

0グッド

0クリップ

投稿2023/04/12 08:54

編集2023/04/12 08:59

実現したいこと

1:多の保存をしたい

前提

Listにtext1(String)を表示して、タップするとそれぞれに遷移して、編集可能となります。
その際、Bool値が2つあり、それぞれのtext1の値に対してリレーションで保存したいと思っています。
そのため、EntityはItem1とItem2を用意しています。

発生している問題・エラーメッセージ

EntityでItem1とItem2を設定しているのに Use of local variable 'item2' before its declaration と出る。

該当のソースコード

SwiftUI

1 2func registSampleData(context: NSManagedObjectContext) { 3 4 /// Item1テーブル初期値 5 let studentList = [ 6 ["item1"] 7 ] 8 9 /// Item2テーブル初期値 10 let clubList = [ 11 ["item2"] 12 ] 13 14 /// Task1テーブル全消去 15 let fetchRequestStudent = NSFetchRequest<NSFetchRequestResult>() 16 fetchRequestStudent.entity = Student.entity() 17 let students = try? context.fetch(fetchRequestStudent) as? [Student] 18 for student in students! { 19 context.delete(student) 20 } 21 22 /// Task2テーブル全消去 23 let fetchRequestClub = NSFetchRequest<NSFetchRequestResult>() 24 fetchRequestClub.entity = Club.entity() 25 let clubs = try? context.fetch(fetchRequestClub) as? [Club] 26 for club in clubs! { 27 context.delete(club) 28 } 29 30 for club in clubList { 31 let newClub = Item1(context: context) 32 newClub.id = item1[0] 33 newClub.text1 = item1[1] 34 35newClub.text2 = item1[2] 36 37newClub.text3 = item1[3] 38 39 } 40 41 let dateFormatter = DateFormatter() 42 dateFormatter.dateFormat = "yyyy/M/d" 43 44 for student in studentList { 45 let newStudent = Item2(context: context) 46 newStudent.id = item2[0] 47 newStudent.bool1 = Item2[1] 48 newStudent.bool2 = Item2[2] 49 50 /// リレーションの設定 51 fetchRequestClub.predicate = NSPredicate(format: "id = %@", student[5]) 52 let result = try? context.fetch(fetchRequestClub) as? [Item1] 53 if result!.count > 0 { 54 newStudent.club = result![0] 55 } 56 } 57 58 /// コミット 59 try? context.save() 60} 61

試したこと

再起動、プロジェクトをつくり直しました。

補足情報(FW/ツールのバージョンなど)

Xcode14.1

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/04/12 11:22

前提のところでは 「EntityはItem1とItem2を用意しています。」 と記載されていますが、 該当のソースコードの中では Studentのエンティティ、Clubのエンティティなども登場しているように見えました。 該当のソースコードをコピペして再現確認してみたところ 「Use of local variable 'item2' before its declaration」 のビルドエラーにはならず、 「Connot find 'item1' in scope」のようなビルドエラーになりました。 実際のコードと「該当のソースコード」が違うのかなと思います。 コードが違うと回答できないと思いますので、 「Use of local variable 'item2' before its declaration」 のビルドエラーになるコードに修正してもらえると助かります。
pon3428

2023/04/13 04:56 編集

ありがとうございます やっていて思ったのですが 1:多とはいいますが、1であるtext1はStringで、Item.text1となります。 一方、多であるBool値ふたつはそのそれぞれに保存することになります。 その際、Item.text1のそれぞれは、どのように記述すればいいと思いますか? Item1.text1[0]やItem1.text1[index]でしょうか。
guest

回答1

0

ベストアンサー

コメントありがとうございます。
コードを記述したかったため、回答欄に記載しますね。

その際、Item.text1のそれぞれは、どのように記述すればいいと思いますか?

CoreDataのRelationshipはNSSet型になるみたいです。
この型は[0]のように参照することができないみたいです。
ですので、次のように配列にしてあげると扱いやすいみたいです。
(Item1とItem2はRelationshipの関係を設定していますよね?)

swift

1let zero = Date.init(timeIntervalSince1970: 0) 2// newItem1はItem1のインスタンスです。 3let setItem2 = newItem1.relationshipItem2 as? Set<Item2> ?? [] 4let arrayItem2 = setItem2.sorted(by: { $0.attributeTimestamp ?? zero < $1.attributeTimestamp ?? zero }) 5print(newItem1.attributeText1 ?? "") 6if !arrayItem2.isEmpty { 7 print(arrayItem2[0].attributeBool1) 8 print(arrayItem2[0].attributeBool2) 9}

Item1のエンティティには次のアトリビュートを設定しています。

  • attributeTimestamp: Date
  • attributeText1: String

Item2のエンティティには次のアトリビュートを設定しています。

  • attributeTimestamp: Date (配列にする際に日時の昇順にソートするために使用しています)
  • attributeBool1: Boolean
  • attributeBool1: Boolean

Item1からItem2へのRelationshipは「Item1.relationshipItem2」を設定しています。

*CoreDataのEntity(クラス)は大文字で始まり、
変数名(インスタンス)は小文字で始めるのが一般的かなと思います。

投稿2023/04/13 07:17

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pon3428

2023/04/17 02:52

ありがとうございます text1(配列として用いています)に対する二つのBool値はNSSet型として扱えばいいのですね リレーションをやめようかと思いましたが、 続けてみようとおもいます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問