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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

0回答

873閲覧

Color型変数を含むカスタムクラス配列のCodableを使ったUserDefault保存、及びそのプロパティの監視について

NuruNull

総合スコア0

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/05/22 02:34

編集2021/05/24 14:01

前提・実現したいこと

colorPickerで選択した色とTextFieldに入力した色をリストに保管し、それをUserDefaultに入れて永続化させる、リストを選択するとtextに保存した文字色でテキストを表示させる機能を実装させたいと考えています。
またその両方の値を監視し変更をすると再描画したいです。

発生している問題

実装できず最終的に何がエラー原因となっているかも分からなくなってしまったので今回質問させていただきます。
似たような質問がいくつかありましたが、そのどれを実行してもエラーを解消できませんでした。

該当のソースコード

SwiftUI

1import SwiftUI 2 3struct ContentView: View { 4 5 // 実行している動作 6 @State private var select = "Select from list" 7 // テキストフィールドへの入力値 8 @State var inputPlan = "" 9 // リストの初期値 10 @State private var works = [ 11 DataStruct(name: "banana", color: .purple), 12 DataStruct(name: "apple", color: .blue), 13 DataStruct(name: "Cat", color: .pink) 14 ] 15 16 // 選択した色 17 @State var colorSelect = Color.blue 18 // 表示色 19 @State var setColor = Color.black 20 21 // UI部分 22 var body: some View { 23 VStack { 24 Text(select) 25 .font(.largeTitle) 26 .fontWeight(.heavy) 27 .foregroundColor(setColor) 28 ZStack{ 29 // 追加用のテキフィー 30 // onCommit: 改行で動作する 31 TextField("Add Place", text: $inputPlan, onCommit: { 32 works.append(DataStruct(name: inputPlan, color: colorSelect)) 33 // 追加後の配列を保存 34 UserDefaults.standard.set(works, forKey: "working") 35 inputPlan = "" 36 }) 37 .frame(height: 40) 38 // カラーピッカーで色指定 39 ColorPicker("", selection: $colorSelect) 40 } 41 42 List { 43 ForEach(works) { name in 44 Button(action: { 45 // リスト選択で実行動作更新&動作保存 46 select = name.name 47 setColor = name.color 48 }, label: { 49 Text(name.name) 50 .foregroundColor(name.color) 51 }) 52 } 53 } 54 } // VStack終了 55 56 // 画面起動時の動作 57 .onAppear { 58 // worksリストの読み込み 59 self.works = [ 60 DataStruct(name: "banana", color: .purple), 61 DataStruct(name: "apple", color: .blue), 62 DataStruct(name: "Cat", color: .pink) 63 ] 64 guard let userdefaultArray = UserDefaults.standard.array(forKey: "working") as? Array<DataStruct> else { return } 65 self.works = userdefaultArray 66 } 67 } 68} 69 70struct DataStruct: Identifiable { 71 var id = UUID() 72 let name: String 73 let color: Color 74} 75 76struct ContentView_Previews: PreviewProvider { 77 static var previews: some View { 78 ContentView() 79 } 80}

試したこと

上記のコードを実行すると描画は出来るのですが、リストに値を追加する動作を行うと
Thread 1: "Attempt to insert non-property list object ~
といったエラーが出ます。

原因を調べたところ、カスタムクラス配列をuserDefaultに保存するにはカスタムクラスをCodableにしてUserDefaultから呼び出し、保存の際にエンコード、デコードをすれば良い事がわかりました。

なので、
リンク内容
の質問を参考に改変しましたが、
Type 'DataStruct' does not conform to protocol 'Decodable' & 'Encodable'
とエラーが出ました。

これは原因がSwiftUIのColorがCodableに対応していないと判明したので、
リンク内容
このサイトのコードを使用し、extensionを作成する事でエラーは解消しました。

ですが、Codableを実装しても22行目("struct ContentView: View {" の部分)に
Failed to produce diagnostic for expression; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project
とエラーが出て上手く行きません。

エラーコードから検索を掛けたり色々してみたのですが問題箇所が分かりませんでした。

このエラーは何処から来ているものなのか、どこを修正すれば想定通りに動作するのか教えて欲しいです。
原因がextensionや、Codableの実装方法にあるかもと思い過程を載せさせて頂きました。

よろしくお願いします。

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

Xcode Version 12.5
SwiftUI
を使用しています

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

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

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

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

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

tomato879241

2021/05/24 05:12

あなたが「22行目に」と言っても、他の人にはそれがどの行を指しているのかわからないのでは?
NuruNull

2021/05/24 14:02

エラー部分の情報を追記しました。ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問