in AppDelegate.swift, how to present an alert window in didFinishLaunchingWithOptions?
I used window?.rootViewController?.present(alert, animated: true), but rootViewController was nil, so nothing was shown.
The app was starting with a storyboard.
in AppDelegate.swift, how to present an alert window in didFinishLaunchingWithOptions?
I used window?.rootViewController?.present(alert, animated: true), but rootViewController was nil, so nothing was shown.
The app was starting with a storyboard.
Oh, and your code, if I guess what Swift is doing, will simply break if top is not nil but top?.presentedViewController is nil. So why are you saying there is no rootViewController?
Another design approach, as suggested by Claude31 is not to warn the user about their need to connect to iCloud until they actually need to connect to iCloud. For example, I am developing an app that uses iCloud to keep track of 'transfer events'. So I don't warn the user about their iCloud connection status until they try to do a transfer event. I test
if( [NSFileManager defaultManager].ubiquityIdentityToken ){
// code that requires iCloud
}
before doing something that requires iCloud. I also keep track of stuff in the app's keychain awaiting the next synch to iCloud.
This might work for you.
(By the way, I also check that ubiquityIdentityToken to be sure it hasn't changed before doing iCloud synching)
yes, it was nil. UIApplication.shared.keyWindow?.rootViewController was nil.
yes, top was nil.
The approach taken was downloading the dataset from iCloud first before doing the atucal viewControllers display.
And it also check the connection, if it failed, remind the user of alert window.
it is normal approach as lots of other app was doing, as the sample was doing as well.
https://developer.apple.com/library/archive/samplecode/CloudKitShare
I am terribly sorry! I did a little experimenting and discovered that, just as you indicated, the topController (in the above code) is nil until the thread that called didFinishLaunchingWithOptions actually ends. You need to let it end and then show the alert. Please accept my apologies.
//replace
[self presentThisViewController:alert];
// with
[self delayAndPresent:alert];
// and add
-(void)delayAndPresent:(UIViewController *)alert{
[self performSelector:@selector(presentThisViewController:) withObject:alert afterDelay:.01f];
}