@App Storage and MKCoordinateRegion Function

233 views Asked by At

Is it possible to save an MKCoordinateRegion Value in @App Storage? I tried this. But it doesn't work. I got the error 'No exact matches in call to initializer' .

    @AppStorage("region_key") var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
        span: MKCoordinateSpan(latitudeDelta: 100, longitudeDelta: 100)
    )
1

There are 1 answers

0
jnpdx On BEST ANSWER

Types that get stored in AppStorage have to conform to RawRepresentable. MKCoordinateRegion doesn't do this out-of-the-box, but you can add an extension to add conformance:

extension MKCoordinateRegion : RawRepresentable {
    struct RepresentableForm : Codable {
        var centerLat : Double
        var centerLong : Double
        var latDelta: Double
        var longDelta : Double
    }
    
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8), let result = try? JSONDecoder().decode(RepresentableForm.self, from: data)
        else {
            return nil
        }
        self = MKCoordinateRegion(
            center: CLLocationCoordinate2D(latitude: result.centerLat, longitude: result.centerLong),
            span: MKCoordinateSpan(latitudeDelta: result.latDelta, longitudeDelta: result.longDelta)
        )
    }
    
    public var rawValue: String {
        do {
            let data = try JSONEncoder().encode(RepresentableForm(centerLat: self.center.latitude, centerLong: self.center.longitude, latDelta: self.span.latitudeDelta, longDelta: self.span.longitudeDelta))
            return String(data: data, encoding: .utf8) ?? ""
        } catch {
            fatalError()
        }
    }
}