Storing ClosedRange<Float> via @AppStorage

24 views Asked by At

Following this tutorial I would like to store ClosedRange<Float> using @AppStorage. I've extended ClosedRange as follows:

extension ClosedRange where Bound == Float {
    init?(rawValue: String) {
        let components = rawValue.split(separator: ",").compactMap { Float($0) }
        guard components.count == 2 else { return nil }
        self = components[0]...components[1]
    }

    var rawValue: String {
        return "\(lowerBound),\(upperBound)"
    }
}

In my view I would like to use @AppStorage in the following manner:

@AppStorage("range_slider_position", store: .group) var sliderPosition: ClosedRange<Float> = 20...80

Presently the code returns the error:

<view_definition_file...>.swift:16:3 No exact matches in call to initializer 

Candidate requires that the types 'ClosedRange<Float>' and 'Bool' be equivalent (requirement specified as 'Value' == 'Bool') (SwiftUI.AppStorage)
Candidate requires that the types 'ClosedRange<Float>' and 'Int' be equivalent (requirement specified as 'Value' == 'Int') (SwiftUI.AppStorage)
Candidate requires that the types 'ClosedRange<Float>' and 'Double' be equivalent (requirement specified as 'Value' == 'Double') (SwiftUI.AppStorage)
Candidate requires that the types 'ClosedRange<Float>' and 'String' be equivalent (requirement specified as 'Value' == 'String') (SwiftUI.AppStorage)
Candidate requires that the types 'ClosedRange<Float>' and 'URL' be equivalent (requirement specified as 'Value' == 'URL') (SwiftUI.AppStorage)
Candidate requires that the types 'ClosedRange<Float>' and 'Data' be equivalent (requirement specified as 'Value' == 'Data') (SwiftUI.AppStorage)
1

There are 1 answers

0
vadian On BEST ANSWER

You forgot one of your tags, the extension must adopt RawRepresentable.
And the protocol methods must be declared public

extension ClosedRange : RawRepresentable where Bound == Float {
   public init?(rawValue: String) {
        let components = rawValue.split(separator: ",").compactMap { Float($0) }
        guard components.count == 2 else { return nil }
        self = components[0]...components[1]
    }

    public var rawValue: String {
        return "\(lowerBound),\(upperBound)"
    }
}