'No exact matches in call to initializer' error on @AppStorage variable?

Viewed 9089

I'm getting the following error: No exact matches in call to initializer on my @AppStorage variable below:

Model.swift

class UserSettings: ObservableObject {
    @AppStorage("minAge") var minAge: Float = UserDefaults.standard.float(forKey: "minAge") 

This variable is meant to bind to a Slider value below.

Settings.swift

import SwiftUI
struct Settings: View {
    let auth: UserAuth
    init(auth: UserAuth) {
        self.auth = auth
    }
    @State var minAge = UserSettings().minAge
    let settings = UserSettings()

    var body: some View {
            VStack {
                NavigationView {
                    Form {
                        Section {
                        Text("Min age")
                        Slider(value: $minAge, in: 18...99, step: 1, label: {Text("Label")})
                            .onReceive([self.minAge].publisher.first()) { (value) in
                                UserDefaults.standard.set(self.minAge, forKey: "minAge")
                            }
                        Text(String(Int(minAge)))
                        }

Any idea what the problem is?

2 Answers

I am also seeing the same error with the following:

@AppStorage ("FavouriteBouquets") var favouriteBouquets: [String] = []()

Perhaps an array of Strings is not supported by AppStorage.

Edit Found the answer here.

You don't need intermediate state and UserDefaults, because you can bind directly to AppStorage value and it is by default uses UserDefaults.standard. Also you need to use same types with Slider which is Double.

So, here is a minimal demo solution. Tested with Xcode 12.

struct Settings: View {
    @AppStorage("minAge") var minAge: Double = 18

    var body: some View {
        VStack {
            NavigationView {
                Form {
                    Section {
                        Text("Min age")
                        Slider(value: $minAge, in: 18...99, step: 1, label: {Text("Label")})
                        Text(String(Int(minAge)))
                    }
                }
            }
        }
    }
}

Related