kuklis kuklis - 5 months ago 19
iOS Question

Layout updates slowly after application becomes active

My goal is to check the authorization status of

UNUserNotificationCenter
(when the app becomes active again / enters the foreground) and turn a
UISwitch
either on or off, based on the info.

The function works and gets triggered right away but the UISwitch takes 3-5 seconds to update. Is there a better way to update it?

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(checkNotificationSettings), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}

func checkNotificationSettings() {
self.center.getNotificationSettings { (settings) in
switch settings.authorizationStatus {
case .authorized:
self.notificationSwitch.isOn = true
case .notDetermined, .denied:
self.notificationSwitch.isOn = false
}
}
}

Answer Source

getNotificationSettings basically requests notification settings for this app asynchronously so it takes some time until completion block is executed.

Apple documentation for the above method also says that the completion block may be executed on a background thread. However, everything that interacts with the UI must be run on the main thread otherwise they may not be performed regularly just like in your case.

You should wrap it up with DispatchQueue.main to relay UI-related work to main queue and everything should work as expected:

self.center.getNotificationSettings { settings in
  DispatchQueue.main.async { 
    ...
    self.notificationSwitch.isOn = true
  }
}