SwiftUI入門-勉強メモ014-【プロパティ共有その4 UserDefaults Part.1】

SwiftUI

環境は,

  • macOS Catalina 10.15.7
  • Xcode 12.1
  • Swift 5.3
  • iOS 14.1

です.

目次

UserDefaultsとは

UserDefaultsはkeyと呼ばれる文字列と値のペアでデータを管理するものです. アプリを終了しても値の保存はされたままですが, 大容量のデータ保存には向きません.

UserDefaultsオブジェクトであるuserDefaults.standardから値の保存や削除を行っていきます.

メソッド説明
set(, forKey: キー)データを保存します
object(, forKey: キー)データを読み出します
removeObject(, forKey: キー)データを消去します

簡単な例

タップした回数を保存する

以下のサイトを参考にしました.

import SwiftUI

struct ContentView: View {
    @State private var tapCount = UserDefaults.standard.integer(forKey: "Tap")
    
    var body: some View {
        VStack(spacing: 20) {
            Button("押してください!") {
                self.tapCount += 1
                UserDefaults.standard.set(tapCount, forKey: "Tap")
            }
            Text(" \(tapCount)")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

アプリを終了してもボタンを押した回数は保存されます.

SwiftUI

まずは,

@State private var PushCount = UserDefaults.standard.integer(forKey: "Tap")

でボタンを押した回数をカウントする変数を設定します. 今回は整数型でKeyは”Tap”になります.

また, Buttonのaction内で,

self.PushCount += 1
UserDefaults.standard.set(PushCount, forKey: "Tap")

としています. 最初はボタンを押されるたびにtapCountの回数に+1をしています.

2行目でtapCountを保存し直しています. この作業をすることで, アプリを落としたあともボタンを押した回数は保存されます.

タップした回数をリセットする

先ほどの例にリセット機能を追加しました.

import SwiftUI

struct ContentView: View {
    @State private var tapCount = UserDefaults.standard.integer(forKey: "Tap")
    
    var body: some View {
        VStack(spacing: 20) {
            Button("押してください!") {
                self.tapCount += 1
                UserDefaults.standard.set(tapCount, forKey: "Tap")
            }
            Text(" \(tapCount)")
            Button("リセット") {
                self.tapCount = 0
                UserDefaults.standard.set(tapCount, forKey: "Tap")
            }
        }
    }
}
SwiftUI

削除部分は,

Button("リセット") {
    UserDefaults.standard.removeObject(forKey: "Tap")
    self.tapCount = 0
}

保存したボタンを押した回数を読み出す

さらに, 保存したデータを読み出す+デザインを少し変えました.

import SwiftUI

struct ContentView: View {
    @State private var tapCount = UserDefaults.standard.integer(forKey: "Tap")
    @State private var readTapCount: Int = 0
    
    var body: some View {
        VStack(spacing: 20) {
            Button("押してください!") {
                self.tapCount += 1
                UserDefaults.standard.set(tapCount, forKey: "Tap")
            }
            Text(" \(tapCount)")
                .font(.largeTitle)
                .foregroundColor(.pink)
            Button("リセット") {
                self.tapCount = 0
                UserDefaults.standard.set(tapCount, forKey: "Tap")
            }
            Divider()
                .padding()
            Button("読み出し") {
                self.readTapCount = UserDefaults.standard.object(forKey: "Tap") as! Int
            }
            HStack{Text("ボタンを押した回数は")
                Text("\(readTapCount)")
                    .font(.largeTitle)
                Text("です")
            }
        }
    }
}

今回の場合, アプリを落としてもう一度起動すると,

  • tapCountはボタンを押した回数が維持される
  • readTapCountはボタンを押した回数が維持されない

ことになります.

設定画面で使用してみる

以下のサイトを参考に作成してみました.

import SwiftUI

class UserSettings: ObservableObject {
    @Published var username: String {
        didSet {
            UserDefaults.standard.set(username, forKey: "username")
        }
    }
    @Published var password: String {
        didSet {
            UserDefaults.standard.set(password, forKey: "password")
        }
    }
    @Published var isUserLocation: Bool {
        didSet {
            UserDefaults.standard.set(isUserLocation, forKey: "isUserLocation")
        }
    }
    
    public var opponents = ["すべての人", "連絡先のみ", "誰とも共有しない"]
    
    init() {
        self.username = UserDefaults.standard.object(forKey: "username") as? String ?? ""
        self.password = UserDefaults.standard.object(forKey: "password") as? String ?? ""
        self.isUserLocation = UserDefaults.standard.object(forKey: "userLocation") as? Bool ?? true
    }
}

struct ContentView: View {
    @ObservedObject var userSettings = UserSettings()
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("ユーザー名とパスワード")) {
                    TextField("Username", text: $userSettings.username)
                    SecureField("Password", text: $userSettings.password)
                }
                Section(header: Text("位置情報")) {
                    Toggle(isOn: $userSettings.isUserLocation) {
                        Text("位置情報の共有する")
                    }
                    Picker(selection: $userSettings.opponents, label: Text("このiPhoneを検出可能な相手")) {
                        ForEach(userSettings.opponents, id: \.self) { opponent in
                            Text(opponent)
                        }
                    }
                }
            }
            .navigationBarTitle("設定")
        }
    }
}
SwiftUI

UserDefaultsに関しては, また勉強が進んだらPart.2を公開していく予定です.

よかったらシェアしてね!

コメント

コメントする

目次
閉じる