After implementing facebook login replaceScene freezes - objective-c

I have implemented facebook login according to https://developers.facebook.com/docs/facebook-login/ios/v2.1#login-apicalls
I have implemented this functionality in my AppDelegate. instead of - (IBAction)buttonTouched:(id)sender method I have same code under -(void)toggleFacebookOnOff; and accessing it from other classes via [(AppDelegate *)[[UIApplication sharedApplication] delegate] toggleFacebookOnOff];
When facebook session is NOT open and I call login method i.e my app redirects to facebook app and then back,calling method [[CCDirector sharedDirector] replaceScene:<#(CCScene *)#> withTransition:<#(CCTransition *)#>] Freezes whole application, no exceptions, no nothing.
Notes:
[[CCDirector sharedDirector] replaceScene:(CCScene *)]; is still functional.
I have noticed that actions are not performed anymore, e.g in different scene I have CCActionEaseInOut to scale sprite from 0.1f to 1.f and this sprite stays scaled.
problems are occurring after app redirects to FB app end then beck, no problem is occurring when I call FBSession openActiveSessionWithReadPermissions with parameter: allowLoginUI:NO.
Anyone has fix for this issue?

Related

setStatusBarOrientation:animated: not working in iOS 6

I've used this code to force an orientation change back to portrait when the user is finished watching the video (it allows viewing in landscape mode), before popping the video view controller off the navigation controller:
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
This worked perfectly until iOS 5.1.1. I've even tried to use the new present/dismiss methods after reading in another post that those should be used now:
[self presentViewController:mVC animated:NO completion:NULL];
[self dismissViewControllerAnimated:NO completion:NULL];
The problem is it doesn't work at all. After I rotated the video viewer to landscape and then pop it, my settings view (table view controller) comes back, but also in landscape mode.
I've even tried the tip from Here
"The setStatusBarOrientation:animated: method is not deprecated outright. However it now works only if the supportedInterfaceOrientations method of the topmost full screen view controller returns 0. This puts the responsibility of ensuring that the status bar orientation is consistent into the hands of the caller."
So I've experimented with setting a flag to force supportedInterfaceOrientations to return 0 (before calling the first code block above) but it doesn't work either.
Does anybody have a solution for this?
Thanks for your time and effort.
setStatusBarOrientation method has changed behaviour a bit. According to Apple documentation:
The setStatusBarOrientation:animated: method is not deprecated
outright. It now works only if the supportedInterfaceOrientations
method of the top-most full-screen view controller returns 0
Your root view controller should answer false to the method shouldAutorotate in order that your app responds to setStatusBarOrientation:animated
From Apple Documentation: "if your application has rotatable window content, however, you should not arbitrarily set status-bar orientation using this method"
To understand that, put a breakpoint in the shouldAutorotate method and you will see that it is called juste after setting the status bar orientation.
Here is how I fixed.
https://stackoverflow.com/a/14530123/1901733
The current question is linked with the question from the url above.
The statusBarOrientation is a real problem in ios6.

IOS FacebooSDK 3.0 FBLoginVIew in modal viewController

I have modal view controller displayed on rightBarButtonItem click. I'm using FbLoginView in this controller as in sample ios-Facebook SDK 3.0 Error 5 When Posting Status Update.
But i'm unable to show modal view controller more than one time.
I tried to release FBLoginView on ViewDidUnload but it always crashes on second atempt to open modal view controller.
Got the same problem and deal with it for couple days already. And finally this is my solution:
if (!FBSession.activeSession.isOpen) {
theLoginView = [[FBLoginView alloc] init];
theLoginView.frame = CGRectOffset(theLoginView.frame,
([[UIScreen mainScreen] bounds].size.width-theLoginView.frame.size.width)/2,
([[UIScreen mainScreen] bounds].size.height-theLoginView.frame.size.height)/2 -50);
theLoginView.delegate = self;
[self.view addSubview:theLoginView];
[theLoginView sizeToFit];
}
//Only close the session when application is terminating, this will save the token information:
- (void)applicationWillTerminate:(UIApplication *)application {
[FBSession.activeSession close];
}
//And keep the FBSession within the app until the user want to logout:
[FBSession.activeSession closeAndClearTokenInformation];
Right now for me its working completely fine. Hope this help.
The FB SDK doesn't seem to like you creating more than one FBLoginView. Maybe you can if you properly terminate the session, but I found it easier just to create the LoginView once and keep it around.
I did this as follows:
1) in my .m modal view controller file, I created a static variable
static FBLoginView* loginView;
2) When loading the modal view controller in my viewDidLoad, instead of
FBLoginView *loginview = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginview.frame = CGRectOffset(loginview.frame, 10, 10);
I added a check to find if its already initialized, like this:
if (!loginView) {
loginView = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginView.frame = CGRectOffset(loginView.frame, 10, 10);
}
Beyond that, I just followed the example of FB's HelloFacebook project.
Not pretty code, but it seems to work.
I had the same problem. Try to add something like this:
if(!yourFBLoginView)
{
yourFBLoginView = [FBLoginView alloc] init...];
}
And/or do not forget to close your active session when you dismissing your modalViewController.
if ([[FBSession activeSession] isOpen])
{
[[FBSession activeSession] close];
}
I think the answer for me (a variant of what was said) was only that I needed to have:
[FBSession.activeSession closeAndClearTokenInformation];
in the:
(void)applicationWillTerminate:(UIApplication *)application
function. The problem specifically for me was, while I was testing...I was constantly terminating the app without actually logging out the user without ever destroying the FBSession, so that when I went back into the app to test what I had changed - my Facebook user was still logged in, and thus some of the conditionals were being incorrectly met. I think this is very important for anyone who is testing (and I'm actually thinking that you should have that line in there anyway) to make sure to clear the session every time the application terminates to avoid this problem...I can imagine a scenario where my app just crashed on somebody and now they are reopening it and they experience the crash because the session was never cleared.

unable to 'click' on adverts

I have the following in my applicationDidFinishLaunching method:
ADBannerView* iAdView = [[ADBannerView alloc] initWithFrame:CGRectZero];
iAdView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[[[CCDirector sharedDirector] openGLView] addSubview:iAdView];
Ads are visible but I can't click on any of them. What am I missing?
Check out these links, it seems you don't know about all the delegate methods and setup iAd actually needs.
http://developer.apple.com/library/ios/DOCUMENTATION/UserExperience/Reference/iAd_ReferenceCollection/_index.html
http://developer.apple.com/library/ios/documentation/userexperience/Reference/ADBannerView_Ref/Reference/Reference.html
http://developer.apple.com/library/ios/DOCUMENTATION/UserExperience/Conceptual/iAd_Guide/
If you see a blank white box and an unhandled error in your console ("no delegate or delegate does not implement didFailToReceiveWithError"), then the touch isn't working because no ad has been received yet. You'll need to implement the delegate method if you want to handle the receive error.
If you wait a while, an ad will probably appear. Then you'll be able to interact with it. If not, it's possible that you haven't signed up for the iAd program yet in iTunes Connect.

quit the application by setting NSTimer?

is their any better way to quit the application programmatically?
recently i made a radio application that have a user setup to set a time using NSTimer for quit the app process ( i mean sleep time). when the time reaches the app should be stop its process and quit.
i used these statements to quit the app when time reaches,
[[UIApplication sharedApplication] suspend];
[[UIApplication sharedApplication] terminateWithSuccess];
theTimer=[NSTimer scheduledTimerWithTimeInterval:(1.0/1.0) target:self selector:#selector(countTime) userInfo:nil repeats:YES];
counter-=1;
timeLeft.text=[NSString stringWithFormat:#" %d",counter];
if (counter==0.0) {
[theTimer invalidate];
[[UIApplication sharedApplication] suspend];
[[UIApplication sharedApplication] terminateWithSuccess];
is their any problem by using [[UIApplication sharedApplication] suspend];
[[UIApplication sharedApplication] terminateWithSuccess]; methods
any other better way to quit the app, or at least freeze the app process..
i need help?
Apple will not approve any application that deliberately suspends or terminates itself. You may use only those methods listed in the official documentation, which does not include suspend or terminateWithSuccess.
I've always used exit(0). I suppose that if you have to run code before the app quitting you should call it before exit(0).
Apple discourages the use of exit() because from the user point of view it looks like a crash. But they also say there is no API call to gracefully terminate your app.
If you're looking for a way to terminate your app without the user pressing home, during sleep time, I assume he won't confuse it with a crash, since he won't be paying attention to your app and exit() leaves no crash log.
So, your options are:
Forget this and just beep after some time to remind him to close the app. (terrible!)
Close the app using your private calls and risk Apple's rejection.
Close the app using exit() and stick with POSIX (accepted) calls.
tanq for your replays, so i just forget about quitting my application programatically. next way is to stop playing my MPMoviePlayerController object. got the next level problem
my settings page for sleepTime and music playing pages, both are different viewControllers
so i can't access MPMoviePlayerController object directly in time settings page, so i created a method on music playing page
MPMoviePlayerController *player=[[MPMoviePlayerController alloc]initWithContentURL:[NSURL URLWithString:#"http://www.radioparadise.com/musiclinks/rp_64aac.m3u"]];
[player prepareToPlay];
[player play];
- (IBAction)StopPlay:(id)sender
{
[player stop];
}
so i created an object for music playing page and i called this method from settings page.,
this is my code in settingsPage
#class MusicPlayingPage;
#interface secondView : UIViewController
{
MusicPlayingPage *audio;
}
and called the method in settingsPage
[audio stopPlay];
control reaches correctly to streamingPage, but it seems like player is not stoping play, i can't access any of these player options [player stop]; , [player pause];
any problem for this method in musicPlayingPage
- (IBAction)StopPlay:(id)sender
{
[player stop];
}
sorry if my question is not understandable.

Displaying Login View on app resume

What is the best way to display a view (in my case a login screen) on app resume. From looking around, I've been playing with the applicationDidBecomeActive event in my AppDelegate, but I cannot seem to get my head around how to properly display a view from here.
I've tried to grab the current window by using self.window and/or it's subviews, but from the AppDelegate self.window is nil.
So far this application seems to be wired up correctly, but I am baffled by two things.
A) why is self.window nil from within my AppDelegate's applicationDidBecomeActive event handler.
B) what is the correct/normal way of display a login view (or the like) on application resume.
Implement a custom UIViewController for all of your applications to inherent from. In this view controller implement logic in the viewWillAppear message to determine and show the login screen if necessary.
//CustomViewController.h
#interface CustomViewController : UIViewController
#end
//CustomerViewController.m
#implementation CustomViewController
-(void)viewWillAppear:(BOOL)animated{
if(login_required){
LoginViewController *loginView = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil];
[self presentModalViewController:loginView animated:false];
}
}
#end
Then, simply, in your login view controller make sure you call:
[self dismissModalViewControllerAnimated:false];
The benefits of this approach are two fold. Firstly, it's a very simple implementation. However, most compellingly, having a base class for an application's view controller presents the opportunity to extract common logic.
Jason,
I have worked on a security tutorial provided by Chris Lowe on raywenderlich.com that was intended to demonstrate how to use basic iOS security to lock the application.
The premise behind this tutorial though was that the application would prompt for login upon first launch and if application was resumed upon unlocking the device through the use of NSNoftificationCenter in viewDidLoad and subscribe the the notifications: deviceWillLock and deviceWillUnlock. All of this assumes the device is set to lock.
Basic iOS Security Tutorial Part 2 - This is the part that has the NSNotification registration.
Basic iOS Security Tutorial Part 1 - This is the first part of the tutorial for clarity.
I also ran into this problem and came across this question whilst researching a solution. I didn't want to create the intermediate super class for my views and I wasn't sure how it would work out with navigation controllers. I have come up with another solution that works well for me - so thought I would share it. It is based around the use of NSNotificationCenter .
In your app delegate create a property to hold a reference to the currently displayed view controller - say currentViewController.
Then in the applicationDidFinishLaunching method, register a block observer to update the currentViewController property like this:
[[NSNotificationCenter defaultCenter] addObserverForName:#"CurrentViewChanged"
object:nil
queue:nil
usingBlock:^(NSNotification *note)
{self.currentViewController = (UIViewController *)note.object;} ];
In your view controller implementations, update the viewDidAppear methods to notify the observer that a new view controller is being displayed by adding the following line
[[NSNotificationCenter defaultCenter] postNotificationName:#"CurrentViewChanged" object:self];
Finally, include code in the applicationDidBecomeActive method in your app delegate to force the modal display of your login screen.
UIStoryboard *mainStoryBoard = self.window.rootViewController.storyboard;
UnlockViewController *uvc = [mainStoryBoard instantiateViewControllerWithIdentifier:#"modalUnlockView"];
uvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.currentViewController presentViewController:uvc animated:YES completion:NULL];
A couple of additional items to note :-
You can disable the login screen display at anytime by posting a notification where the view controller passed is nil.
You only need to post the notification once for a navigation view controller at the top level. All view controllers in the navigation controller stack will be covered. I haven't checked, but I suspect the same is true for a tab view controller.
If you want to display the login screen the first time you enter the app after startup then include the following line in the applicationDidFinishLaunching method.
self.currentViewController = self.window.rootViewController;
I hope this is of some use.
Thanks