Sponsor Link
環境&対象
- macOS Big Sur 11.4
- Xcode 12.5
- iOS 14.5
@AppStorage
@AppStorage は、iOS14/macOS11 から導入されました。
UserDefaults からの読み込みや UserDefaults への書き込みを簡単に行うための Property Wrapper です。
Apple のドキュメントは、こちら。
UserDefaults
UserDefaults は、SwiftUI 以前から存在して アプリのちょっとしたデータを保存するための領域として使うことができます。
Apple のドキュメントは、こちら。
保存されたデータは、アプリのライフサイクルを超えて読み書きすることができます。
@State 変数
@State は、SwiftUI と同時に導入された Property Wrapper の1つで、宣言された変数は、その変数を保持するビューのライフサイクルと合わせて管理してくれます。
@AppStorage の使い道
@AppStorage の使い方の一例として、ビューのライフサイクルを超えてデータを保持させることがあります。
ビューのライフサイクルでのみ保存されるケース
以下は、カウンターのサンプルです。
見てもらうとわかりますが、カウンターの値を ビュー内の @State 変数で定義しているため、カウンターのビューが非表示になると、カウンターのデータ自体も失われます。
使用したコードは、以下です。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/06/16
// © 2021 SmallDeskSoftware
//
import SwiftUI
struct ContentView: View {
@State private var showCounter = false
var body: some View {
VStack {
if showCounter {
CounterView()
.padding()
} else {
Text("counter will appear here")
.padding()
}
Button(action: {
showCounter.toggle()
}, label: {
Text(showCounter ? "Hide Counter" : "Show counter")
})
}
}
}
struct CounterView: View {
@State private var counter = 0
var body: some View {
VStack {
Text("\(counter)")
.font(.largeTitle)
HStack {
Button(action: {
counter += 1
}, label: {
Image(systemName: "plus")
})
Button(action: {
counter -= 1
}, label: {
Image(systemName: "minus")
})
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
このような時に、@AppStorage を使用すると ビューのライフサイクルを超えて データを保持することができます。
@AppStorage を使用した データの保持
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/06/16
// © 2021 SmallDeskSoftware
//
import SwiftUI
struct ContentView: View {
@State private var showCounter = false
var body: some View {
VStack {
if showCounter {
CounterView()
.padding()
} else {
Text("counter will appear here")
.padding()
}
Button(action: {
showCounter.toggle()
}, label: {
Text(showCounter ? "Hide Counter" : "Show counter")
})
}
}
}
struct CounterView: View {
@AppStorage("counter") private var counter:Int = 0
var body: some View {
VStack {
Text("\(counter)")
.font(.largeTitle)
HStack {
Button(action: {
counter += 1
}, label: {
Image(systemName: "plus")
})
Button(action: {
counter -= 1
}, label: {
Image(systemName: "minus")
})
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
@AppStorage で指定している “counter” は、アプリケーション内でユニークな値が設定される必要があります。実際に、この値は UserDefaults のキーとして使用されます。つまり、同じキーを使用して他のビューからもアクセスすることが可能であるため、注意が必要です。
まとめ:@AppStorage を使って、ビューのライフサイクルを超えて値を保持する
- @State を @AppStorage に置き換えるだけで、ビューのライフサイクルを超えて値を保持できる
- @AppStorage は、UserDefaults を使用してデータを保持する
- @AppStorage 指定する時には、UserDefaults でのキー値が必要
- 同じキー値を指定すると別のビューからも操作できてしまうので注意
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link