Chapter 6: Dismiss of alert box

In the extension of the UIViewController we declare an alert function like this:

func alert(title: String, text: String?) -> Observable<Void> {
    return Observable.create { [weak self] observer in
      let alertVC = UIAlertController(title: title, message: text, preferredStyle: .alert)
      alertVC.addAction(UIAlertAction(title: "Close", style: .default, handler: {_ in
        observer.onCompleted()
      }))
      self?.present(alertVC, animated: true, completion: nil)
      return Disposables.create {
        self?.dismiss(animated: true, completion: nil)
      }
    }
  }

In Chapter 6 we also use it here:

private func errorMessage() {
		alert(title: "No access to Camera Roll",
		      text: "You can grant access to Combinestagram from the Settings app")
			.take(5.0, scheduler: MainScheduler.instance)
			.subscribe(onDisposed: { [weak self] in
				self?.dismiss(animated: true, completion: nil)
				_ = self?.navigationController?.popViewController(animated: true)
			})
			.disposed(by: bag)
	}

As I see it, when we call dispose on the alert box we have:

  • 1 dismiss from the alert function
  • 1 dismiss from the errorMessage function’s onDispose closure
  • 1 popViewController from the errorMessage function’s onDispose closure

I removed the dismiss from the alert function and it still worked correctly.

My question is: are we calling dismiss too many times? Is it possible that this would create in production code issues?

once the observable has completed it won’t emit any elements, what kind of problems in production are you worried about?

If I understood correctly in the alert function it will be dismissed upon diposal. But then in the onDipose of the errorMessage function, we call dismiss again on the alert (which is the visible controller at that time). So the dismiss function won’t be called twice?

It will be but that won’t have any effect the second time … you might want to dispose a subscription different ways (as in this chapter) - you either dispose when there time is up or when the user presses the alert button, whichever happens first will dispose the subscription

So in order to get this straight: dismiss will be called twice, but the second call will have no effect. Am I right?

No this is absolutely not what I wrote just above.

Sorry for asking again I am just trying to understand the flow. According to my understanding, when a user presses Close this is when the Observable is disposed. According to the alert function when it is disposed the following closure of Disposables.create is invoked:

{
  self?.dismiss(animated: true, completion: nil)
}

We also have the onDisposed closure in the subscription on the alert function which will run when the Observable is disposed:

{ [weak self] in
	self?.dismiss(animated: true, completion: nil)
	_ = self?.navigationController?.popViewController(animated: true)
}

Maybe I have not understood correctly, but won’t both those closures run when the Observable is disposed?
If so, won’t dismiss run twice?

Sorry I finally understood which part of the code you refer to … yes, calling dismiss multiple times on the same view controller is fine, you can just add as many calls to dismiss as you want in your code to give it a try … calling this method does not have any effect if the VC isn’t currently presenting a view controller

Thanks a lot Marin :slightly_smiling_face:

This topic was automatically closed after 166 days. New replies are no longer allowed.