Darren Oakey
Darren Oakey

Reputation: 3654

asynchronous initialisation with swiftui

Basically - I run up against this a lot - I don't understand how you correctly do asynchronous initialisation in swift with callbacks. (with combine - I can do it). In particular - I have this code:

struct MyView : View {
    @State var initialised : Bool = false

    init()
    {
       var initialisedBinding = $initialised
       Photos.PHPhotoLibrary.RequestAuthorization {
          status in 
          if (status == Photos.PHAuthorizationStatus.authorized) {
              print("here I am")
              initialisedBinding.wrappedValue = true
              initialisedBinding.update()
          }
      }
   }

   var body : some View {
     VStack {
       if (initialised) {
           Text("yep")
       } else {
           Text("nope")
       } 
    } 
  }

And when I run it - I get the print out - but the text never changes - it always remains "nope". What am I doing wrong, and how do I do it right? (Without using combine - I can do it with like a currentValueSubject and a .onreceive - but it's extra overhead, and I really want to know why the above code doesn't work - obviously I'm understanding something bad)

Upvotes: 2

Views: 316

Answers (1)

Asperi
Asperi

Reputation: 258345

State is not ready in init yet, so you bound to nowhere. Moreover such activity in init is not good, because view can be created many times during rendering. The more appropriate place is .onAppear

struct MyView : View {
   @State var initialised : Bool = false

   var body : some View {
     VStack {
       if (initialised) {
           Text("yep")
       } else {
           Text("nope")
       } 
    }.onAppear {
       Photos.PHPhotoLibrary.RequestAuthorization {
          status in 
          if (status == Photos.PHAuthorizationStatus.authorized) {
              print("here I am")
              self.initialised = true
          }
      }
    } 
  }
}

Upvotes: 2

Related Questions