I had the same problem just now...
After a big headache i solved it... :D
(if you don't need the explanation, just look at the sample code, and the few lines above it... :D )
the thing is, the alertView creates another window, makes it the key window, and places the alertView's view in it... now when you tell FBConnect to log back in, with the dialog and all, it show's it's self inside the key window. which at the time is the alertView's window.
So we just need to make the alert's window to resign it's key status.
i did not find a way to manually do that, but luckily it does that for you. when? in the end of the run loop (and it actually takes a little bit of time ;) ).
the solution is pretty simple, let the alert's runloop end. you do this by running your re-login method in the background.
[self performSelectorInBackground:@selector(loginToFaceBook) withObject:nil];
but then we have two other issues to take care of:
- as i mentioned before, it takes it a little while, to actually cleanup the alertView's mess (the window in particular). so we need to wait for it.
- the dialog FBConnect creates has a webView inside, and the WebViews don't like being in the background... so we'll need call it in the main thread.
KennyTM has kindly suggested that it's impossible to check for other stacked alerts, i disagree... I've used this code:
BOOL shouldWait = YES ;
// wait for the alert view to dissmiss it's self
while (shouldWait) {
[NSThread sleepForTimeInterval:0.1];
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
shouldWait = [keyWindow isKindOfClass:NSClassFromString(@"_UIAlertOverlayWindow")];
}
Now i'm not sure if this is legal in the public API... but i think there are all kinds of other ways to check if the key window is the alert view's window... another one that comes to mind is to try and see it any of it's subView's is of the "UIAlertView" class... like so:
for (UIView *subView in [keyWindow subviews]) {
if (shouldWait = [subView isKindOfClass:[UIAlertView class]) {
break;
}
}
anyways, i'm sure it's a solvable problem... and after i'll submit my app, and if i'll remember (i have memory problems :/ ) i'll let you guys know if apple approved any of these technics...
and the other thing you'll need to is to "show" the dialog on the main thread. but that's easy:
FBStreamDialog* dialog = [[[FBStreamDialog alloc] init] autorelease];
[dialog performSelectorOnMainThread:@selector(show) withObject:nil];
if you want to init the dialog with a session, you'll need to do that on the main thread as well...
I had a method called "showDialodWhenAppropriate" which i perform in the background. it does the waiting, and when it's appropriate, i call another method called "showTheDialog" which i call on the main thread.
Facebook should probably implement this themselves.. but until they do, have fun. :D