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

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

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

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

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2791閲覧

[SwiftUI]UserDefaultsによってデータの永続化をしたい

Hyperbolic4183

総合スコア17

Xcode

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

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2020/05/28 07:12

編集2020/05/28 11:21

##今の状態・困っていること
SwiftUIを使ってアプリを作っています。
画像のように選択した色を保存するとRGBの3つの値がObservableObjectクラスのプロパティである配列@Published var rgbArray = [[Int]]()に保存され、別のビューでリスト表示されるようになっています。
困っていることはアプリの履歴を消したり、本体を再起動すると配列に格納されていた要素が消えてしまうことです。
##試みている解決方法
UserDefaultsによって永続化を試みています。

UserDefaults.standard.set(self.favoriteArray.rgbArray,forKey: "stored") self.favoriteArray.rgbArray.append([self.r,self.g,self.b])

によってrgbArrayにUseDefaultsを用いています。
リストを表示するビューでは

let userdefaultRgbArray: [[Int]] = UserDefaults.standard.array(forKey: "stored") as! [[Int]] var body: some View { List { ForEach(0..<self.userdefaultRgbArray.count) { item in ListRow(rValue: self.userdefaultRgbArray[item][0], gValue: self.userdefaultRgbArray[item][1], bValue: self.userdefaultRgbArray[item][2]) } }

のようにして配列の要素の数だけリストが増えるようになっています。
##起きているエラー
Can't preview in this fileと表示され
| Error Domain=com.apple.dt.ultraviolet.service Code=12 "Rendering service was interrupted" UserInfo={NSLocalizedDescription=Rendering service was interrupted}
と出ています。
このエラーはこちらにある通り、@Environmentなどの状態を保存する属性を用いたときに発生するエラーです。

##ソースコード

保存するビュー

ColorDetail

1import SwiftUI 2 3 4struct ColorDetail: View { 5 var r:Int 6 var g:Int 7 var b:Int 8 @EnvironmentObject var favoriteArray: ObservedRGB 9 10 var userDefaults = UserDefaults.standard 11 12 var body: some View { 13 14 GeometryReader{ bodyView in 15 VStack { 16 Text("") 17 .frame(width: bodyView.size.width, height: bodyView.size.width) 18 .background(Color.init(UIColor(self.r,self.g,self.b))) 19 Text("R値は(self.r)G値は(self.g)B値は(self.b)") 20 Button(action: { 21 print("tapped") 22 UserDefaults.standard.set(self.favoriteArray.rgbArray,forKey: "stored") //rgbArray永続的に保存する 23 self.favoriteArray.rgbArray.append([self.r,self.g,self.b]) 24 }){ 25 Text("保存する") 26 } 27 } 28 } 29 } 30} 31 32 33extension UIColor { 34 35 convenience init(_ red: Int, _ green: Int, _ blue: Int, _ alpha: Int = 255) { 36 let rgba = [red, green, blue, alpha].map { i -> CGFloat in 37 switch i { 38 case let i where i < 0: 39 return 0 40 case let i where i > 255: 41 return 1 42 default: 43 return CGFloat(i) / 255 44 } 45 } 46 self.init(red: rgba[0], green: rgba[1], blue: rgba[2], alpha: rgba[3]) 47 } 48} 49 50struct ColorDetail_Previews: PreviewProvider { 51 static let favoriteArray = ObservedRGB() 52 static var previews: some View { 53 ColorDetail(r: 3,g:12,b:21).environmentObject(favoriteArray) 54 } 55}

リストに並べられるビュー

ListRow

1 2import SwiftUI 3 4struct ListRow: View { 5 6 var rValue: Int 7 var gValue: Int 8 var bValue: Int 9 10 11 12 var body: some View { 13 14 Text("(String(rValue, radix: 16))(String(gValue, radix: 16))(String(bValue, radix: 16))") 15 .frame(width: 300, height: 50) 16 .background(Color.init(UIColor(rValue,gValue,bValue))) 17 18 } 19} 20 21struct ListRow_Previews: PreviewProvider { 22 static let favoriteArray = ObservedRGB() 23 static var previews: some View { 24 ListRow(rValue: 1, gValue: 0, bValue: 0) 25 } 26}

リストのビュー

MainList

1import SwiftUI 2 3struct MainList: View { 4 @EnvironmentObject var favoriteArray: ObservedRGB 5 let userdefaultRgbArray: [[Int]] = UserDefaults.standard.array(forKey: "stored") as! [[Int]] 6 var body: some View { 7 8 List { 9 ForEach(0..<self.userdefaultRgbArray.count) { item in 10 11 ListRow(rValue: self.userdefaultRgbArray[item][0], gValue: self.userdefaultRgbArray[item][1], bValue: self.userdefaultRgbArray[item][2]) 12 } 13 } 14 15 16 17 18 19 } 20} 21 22struct MainList_Previews: PreviewProvider { 23 static let favoriteArray = ObservedRGB() 24 static var previews: some View { 25 MainList().environmentObject(favoriteArray) 26 } 27}

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

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

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

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

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

guest

回答1

0

自己解決

解決いたしました。以下の動画が参考になりました。
https://www.youtube.com/watch?v=pFEemgQvJzg

詳細を記し、得られた知見を共有できればと思います。
SwiftUIではUIKitでのViewdidLoad()などにあたるものとして.onAppear()モディファイアがあります。
UserDefaultsを利用して保存されたものをキーを通してゲットする操作をアプリを開いた時に開くビュー、つまりrootViewControllerやcontentViewに設定したビューに.onAppear()を設定することで期待する結果となりました。

投稿2020/05/29 00:34

Hyperbolic4183

総合スコア17

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問