Initialize a state variable from observed object

Viewed 1010

I have another problem with the observable objects.

In my View at the line "Position 1" I have the text view for editing the address (and save it into the state property "text", which have to be displayed in the view).
The state variable "text" has to be initialized from the class LocationObserver property "currentAddress". I just tried to set the initialization of the view Can somebody help me?

Thanks in advance!

Best

Dragan


The View 


struct PickFoto: View {
    @ObservedObject var observeLocation = LocationObserver.shared()!
    @State private var address = LocationObserver.shared()?.currentAddress ?? " "

...    

TextView(text: $text, isEditing: $isEditing) // Position 1


Text("current Address (observeLocation): \(observeLocation.currentAddress)") // Position 2
...
}

The Shared Object

class  LocationObserver: NSObject, CLLocationManagerDelegate, ObservableObject {
    // This published property value  has to be the initial value   
    // for the TextView (the property $text. how to to this??)

    @Published var currentAddress = " " 

    static var instance: LocationObserver?

    var locationManager = CLLocationManager()
    var defaultLocation = CLLocation(latitude: 52.516861, longitude:13.356796)

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let currentLocation = locations.last?.coordinate



        convertGPSToAdress(coordinates: locations.last ?? defaultLocation,
                           completion: { (retStr: String) in
                                            self.currentAddress = retStr // set the  @Published property
                                            print("currentAddress in EscapingClosure: \(self.currentAddress)")
                                            //everything is fine
                                        }
        )

    }


    func convertGPSToAdress(coordinates: CLLocation,
                        completion:  @escaping(String) -> ()) -> () {

    let address = CLGeocoder.init()
    address.reverseGeocodeLocation(coordinates) { (places, error) in
        if error == nil{
            if places != nil {
                let place = places?.first
                completion(formatAddressString(place: place!)) // returns a formatted string address 
            }
        }
    }
}

    ....
}
1 Answers

Try the following (code snapshot not testable - so just scratchy)

struct PickFoto: View {
    @ObservedObject var observeLocation = LocationObserver.shared()!
    @State private var address: String

    init() {
        _address = State<String>(initialValue: LocationObserver.shared()?.currentAddress ?? " ")
    }

    ...

Update: synchronise private address state with external

var body: some View {
    ...
    TextView(text: $text, isEditing: $isEditing) 
       .onReceive(observeLocation.$currentAddress) { newAddress in
            self.address = newAddress
       }
    ...
}
Related