application didFinishLaunchingWithOptions wird aufgerufen, bevor der Storyboards fertig sind laden?
Habe ich eine app, die einen Facebook-login beim Start mit code ziemlich genau ähnlich wie diese: Facebook Tutorial Lecker, außer mit Storyboards.
Den Grundtenor des Codes ist, dass auf der app beim starten der app delegate überprüft, um zu sehen, ob Sie bereits angemeldet sind, und wenn man geradeaus geht es in die Hauptansicht, und wenn nicht, fragt er den wichtigsten anzeigen präsentieren ein login-Ansicht, damit der Benutzer sich anmelden können.
Hab ich schon gelöst mein anderes Problem mit in der Lage zu sagen, die Haupt-Ansicht in der storyboard-eine andere Ansicht, indem Sie immer die wichtigsten anzeigen aus der Sicht bietet, und rufen dann ein Wechsel auf die Ansicht. Das alles funktioniert Prima, jedoch habe ich ein letztes problem zu lösen:
Soweit ich weiß, die application didFinishLaunchingWithOptions Methode ist soll genannt zu werden nach die storyboards wurden vollständig geladen ist. Aber in meinem code, wenn ich versuchen zu sagen, die Haupt-Ansicht eine andere Ansicht, es gibt mir eine Fehlermeldung im Grunde sagen, es ist nicht geladen, doch (Warnung: Versuch < QLoginViewController: 0x955c020> auf < UINavigationController: 0xa28c6e0> dessen Blick ist nicht in die Fenster-Hierarchie!).
Wenn ich sagen, es präsentieren die Ansicht, nachdem eine Verzögerung allerdings:
[self performSelector:@selector(showLoginViewAnimated:) withObject:NO afterDelay:.001];
(wo showLoginViewAnimated: ist die Methode, sagt der Hauptansicht präsentiert die login-Ansicht), dann funktioniert es einwandfrei.
Kann mir jemand helfen, herauszufinden, was läuft hier falsch und wie könnte ich es beheben? Die Durchführung der Selektor mit einer Verzögerung ist offensichtlich ein schlechter workaround, wie ich nie wissen kann, ob ein anderes Gerät vielleicht länger dauern, um zu laden, die Aussicht...
Hier ist mein appDelegate didFinishLaunchingWithOptions code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Override point for customization after application launch.
self.navigationController = (UINavigationController *)self.window.rootViewController;
//Navigation Bar Color
[[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:255.0/255.0 green:128.0/255.0 blue:60.0/255.0 alpha:1.0]];
/* Facebook Login */ //THIS IS THE RELEVANT CODE:
//See if we have a valid token for the current state
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
//Yes, valid token exists - open the session (don't display login page)
[self openSession];
} else {
//No, valid token does not exist - display the login page.
if ([self.navigationController isViewLoaded]) {
[self showLoginViewAnimated:NO]; //MY ATTEMPT TO AVOID USING THE DELAY IF POSSIBLE
}
else {
[self performSelector:@selector(showLoginViewAnimated:) withObject:NO afterDelay:.001]; //Delay needed to allow for storyboard loading
}
}
return YES;
}
Und hier ist die showLoginViewAnimated: code:
- (void)showLoginViewAnimated:(BOOL)animated
{
UIViewController *topViewController = [self.navigationController topViewController];
UIViewController *presentedViewController = [topViewController presentedViewController];
//If the login screen is not already displayed, display it. If the login screen is
//displayed, then getting back here means the login in progress did not successfully
//complete. In that case, notify the login view so it can update its UI appropriately.
if (![presentedViewController isKindOfClass:[QLoginViewController class]]) {
if (animated) {
[topViewController performSegueWithIdentifier:@"ShowLoginViewAnimated" sender:self];
}
else {
[topViewController performSegueWithIdentifier:@"ShowLoginViewStatic" sender:self];
}
}
else {
QLoginViewController *loginViewController = (QLoginViewController *)presentedViewController;
[loginViewController loginFailed];
}
}
In der ursprünglichen, nicht-storyboard-version der app, die showLoginViewAnimated: Methode würde nicht aufgerufen werden, in application didFinishLaunchingWithOptions, bis ich hatte bereits manuell erstellt, die Ansichten etwa so:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//Override point for customization after application launch.
self.viewController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
Also ich würde schon zu 100% wissen sicher, dass die Ansichten existieren, bevor ich versuche, Ihnen zu sagen, zu präsentieren, neue Ansichten. In der storyboard-version der app jedoch keines dieser code vorhanden ist, so dass ich einfach darauf Vertrauen, dass theoretisch die application didFinishLaunchingWithOptions Methode nicht aufgerufen, bis die storyboard-Ansichten sind vollständig geladen - aber das scheint nicht der Fall zu sein. Vielleicht tut es asynchron statt? Ich habe keine Ahnung...
Irgendwelche Ideen?
Vielen Dank für jede Hilfe!!!
EDIT: Hier ist der original code aus dem tutorial, das funktioniert einwandfrei - und ist fast genau das gleiche, nur mit Federn. Ich habe die (BOOL)animated parameter der showLoginView Methode in meinem code, aber das ist etwas anderes und ändert nichts (hab ich überprüft).
Hier ist die ursprüngliche (nicht-storyboard) appDelegate didFinishLaunchingWithOptions Methode:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//Override point for customization after application launch.
self.viewController = [[FBLViewController alloc] initWithNibName:@"FBLViewController" bundle:nil];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
//See if we have a valid Facebook token for the current state
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
//Yes, so just open the session (this won't display any UX).
[self openSession];
}
else {
//No, display the login page.
[self showLoginView];
}
return YES;
}
Und hier ist das original (nicht-storyboard) showLoginView Methode:
- (void)showLoginView
{
UIViewController *topViewController = [self.navController topViewController];
UIViewController *presentedViewController = [topViewController presentedViewController];
//IF the login screen is not already displayed, display it. If the login screen is
//displayed, then getting back here means the login in progress did not successfully
//complete. In that case, notify the login view so it can update its UI appropriately.
if (![presentedViewController isKindOfClass:[FBLLoginViewController class]]) {
FBLLoginViewController *loginViewController = [[FBLLoginViewController alloc] initWithNibName:@"FBLLoginViewController" bundle:nil];
loginViewController.delegate = self;
[topViewController presentViewController:loginViewController animated:NO completion:nil];
}
else {
FBLLoginViewController *loginViewController = (FBLLoginViewController *)presentedViewController;
[loginViewController loginFailed];
}
}
Oops! Danke mm!!
InformationsquelleAutor Fateh Khalsa | 2013-04-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fügen Sie diese Zeile zu
didFinishLaunchingWithOptions
:bevor die Facebook login-code.
InformationsquelleAutor Fateh Khalsa
Das Haupt-storyboard geladen wird, aber die view-Controller funktionieren noch genau so wie vor: Sie existieren nicht, bis es benötigt wird, und dann haben Sie zu laden, Ihre Ansichten nach wie vor. Ihr code muss noch in einer view-controller ist
viewDidLoad
oderviewWillAppear
oder was auch immer genauso, wenn Sie wurden mit Federn, erstellen von view-Controller im code.Versuchen Sie nicht, zu sagen, der Rahmen, was sein "sollte". Arbeiten mit dem, was das framework eigentlich macht.
Definitiv vereinbart. Von 'sollte', meinte ich, dass ich gelesen habe in mehreren anderen Orten, die didFinishLaunchingWithOptions erst aufgerufen, nachdem die storyboards sind bereits geladen, und die erste Ansicht auf dem Bildschirm (die - und korrigieren Sie mich, wenn ich falsch bin - heißt das ich sollte in der Lage sein zu Fragen, dass Sie einen neuen controller an dieser Stelle). Definitiv offen für die Arbeit mit was auch immer ich brauche, damit es funktioniert, aber ich würde gerne halten Sie den login-code in der appDelegate, wenn ich kann. Danke.
Gut, dann haben Sie falsch gelesen. Der erste Blick ist nicht auf dem Bildschirm, und das interface ist nicht wirklich bis nachdem
didFinishLaunching
. Das ist, warum, wenn Sie das hinzufügen einer Verzögerung, das springen zu einem Punkt auch nach das. Sie können verwenden diese Technik, aber Sie sollte nicht. Sie sollten das tun, was ich sagte: fügen Sie Ihren code in der richtigen Stelle, in Bezug auf das laden des view-Controller.Vielen Dank Matt. Gibt es eine Möglichkeit, dies zu tun, ohne meine code-Kontrolle für die Facebook-login jedes mal, wenn Sie die Hauptansicht geladen? Ich würde am Liebsten nur einmal überprüfen, wenn die app startet, aber wenn das nicht möglich ist würde ich verstehen.
InformationsquelleAutor matt