Search code examples
iosswiftswiftuiswiftui-navigationlinkswiftui-navigationview

Navigate to next screen when Location Authorisation Status Change using SwiftUI + Combine


Below is the code. Here, LocationManager is the Observable class where I have marked "locationStatus" property as @Published. Now, what I want to achieve is when user sees the location Popup and gives Location access, it should navigate to next screen. Can someone please help me with this one? Thanks in advance

 struct MyLocationScreen: View {
    
    @ObservedObject var locationManager = LocationManager()
    @State var isShowLinkTarget :Bool = false

    var body: some View {
        NavigationView{
          ZStack{
             Button(action: {

               let locStatus = self.locationManager.locationStatus

               if locStatus == .authorizedWhenInUse || locStatus == .authorizedAlways {
                   self.showLinkTarget = true
               } else {
                   self.locationManager.requestAuthorization()
                   self.locationManager.startUpdate()
               }

         }) {
             Text("Share Location")
               
            }
            NavigationLink(destination: NextScreen(), isActive: $showLinkTarget) {
                Text("")
            }
          }
        }
    }
}

Solution

  • I can’t provide a line to line code, but I can show you an idea that you can go with. Instead making CLLocationStatus @published, make it a propertyObserver, that when changes sets a boolean @published property to true which will trigger UI refresh, and also handle navigation for you..

    import SwiftUI
    
    struct MyLocationScreen: View {
        
        @ObservedObject var locationManager = LocationManager()
        @State var isShowLinkTarget :Bool = false
        
        var body: some View {
            NavigationView{
                ZStack{
                    Button(action: {
                        
                        /*
                         Once locationManager(), CLLocation property changes it's going to set @published isGranted to true in model class. Which will then trigger body refresh, and navigation can use this updated state.
                         
                         NOTE-: Below i am assigning object just as an example, this has to be your  code.
                         */
                        
                        locationManager.locationStatus = CLAuthorizationStatus()
                        
                        // You can implement below two line alone
                        
                        //                self.locationManager.requestAuthorization()
                        //                self.locationManager.startUpdate()
                        
                    }) {
                        Text("Share Location")
                        
                    }
                    NavigationLink(destination: Text(""), isActive: $locationManager.isGranted) {
                        Text("")
                    }
                }
            }
        }
    }
    
    
    class LocationManager: ObservableObject,Identifiable {
        
        var id  = UUID().uuidString
        @Published var isGranted:Bool = false
        
        var locationStatus:CLAuthorizationStatus?{
            didSet{
                
                // Some logic if you want like
                
    //            if locationStatus == .authorizedWhenInUse || locationStatus == .authorizedAlways {
    //                self.isGranted = true
    //            }
    //
                
                isGranted = true
            }
        }
    }
    
    class CLAuthorizationStatus{
        
    }