How to make my method run when the view re-load - iphone

I want to create a login button. When I click it the facebook launches, I accept my application, the Facebook application closes and my application reloads. My problem is that the second time my application starts, after accepting on Facebook, I cannot find where to disable the login button.
I wrote this code:
-(IBAction) login:(id)sender;
{
AutoAppDelegate *delegate = (AutoAppDelegate *) [[UIApplication sharedApplication] delegate];
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
[delegate facebook].accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
[delegate facebook].expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![[delegate facebook] isSessionValid]) {
[delegate facebook].sessionDelegate = self;
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_likes",
#"read_stream",
nil];
[[delegate facebook] authorize:permissions];
} else {
logIn.hidden=YES;
lbl.text=#"";
lbl.text=#"Connected";
[self showLoggedIn];
}
}
- (void) showLoggedIn {
NSLog(#"11 Logged In ");
lbl.text=#"";
lbl.text=#"Connected";
}
- (void) showLoggedOut {
NSLog(#"11 Not Logged In ");
lbl.text=#"";
lbl.text=#"Not Connected";
}
- (void) viewWillAppear:(BOOL)animated
{
//[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
AutoAppDelegate *delegate = (AutoAppDelegate *) [[UIApplication sharedApplication] delegate];
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
[delegate facebook].accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
[delegate facebook].expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![[delegate facebook] isSessionValid]) {
// [self showLoggedOut];
NSLog(#"Not Connected");
} else {
// [self showLoggedIn];
NSLog(#"Connected");
}
}
The viewWillAppear works the first time, but when I give permissions in the Facebook application, my application restarts but not viewWillAppear method!

You need to put the code in your application delegate (applicationWillEnterForeground), as it's the only thing to get notified automatically when the app is re-opened (your view is not necessarily re-drawn).

Have you tried to calling setNeedsDisplay on the view after the Facebook thing is done?

Related

Repeating authorization Window

I'm using Xcode 4.3.1
In my app I try to use Facebook SSO.My requirement is at the first time the app should ask for the authorization after that it should check whether the app is authorized by the user and should move to the next process(even after the task in the device is cancelled).I don't that authorization window to repeat again and again.
in Appdelegate:
facebook=[[Facebook alloc]initWithAppId:appid andDelegate:first];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(#"%#Defaults:",[defaults objectForKey:#"FBAccessTokenKey"]);
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"])
{
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
accessToken=facebook.accessToken;
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
date=facebook.expirationDate;
}
In my view Controller:
-(IBAction)LoginClick:(id)sender
{
NSUserDefaults *defaults1 = [NSUserDefaults standardUserDefaults];
[defaults1 setObject:xapp.facebook.accessToken forKey:#"FBAccessTokenKey"];
[defaults1 setObject:xapp.facebook.expirationDate forKey:#"FBExpirationDateKey"];
[defaults1 synchronize];
if (![xapp.facebook isSessionValid])
{
permissions = [[NSArray alloc] initWithObjects:#"read_stream",#"publish_stream", nil];
[xapp.facebook authorize:permissions];
}
else if([xapp.facebook isSessionValid])
{
NSLog(#"Hiii");
permissions=nil;
[xapp.facebook authorize: nil];
}
}
How can I make the authorization window to not appear after the app is authorized...
Alright, you are asking for permissions each time you run your app in your AppDelegate. To prevent this, you have to make a separate method for permission that will be granted only if the login button is pressed and checked if the app is permitted or not. Try this in your AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window makeKeyAndVisible];
facebook = [[Facebook alloc] initWithAppId:#"YOURAPPID" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"] && [defaults objectForKey:#"FBExpirationDateKey"])
{
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
return YES;
}
Above your fbDidLogIn method in your AppDelegate add this method, you have to add the FBUser protocol to your AppDelegate:
-(void)fbLogin:(id<FBUser>)_listener
{
listener = _listener;
if(![facebook isSessionValid])
{
NSArray* permissions = [[NSArray arrayWithObjects:
#"publish_stream",
#"read_stream",
nil] retain];
[facebook authorize:permissions];
}
else
{
[listener facebookDidLogin];
}
}
And in your ViewController modify your login method like this:
-(IBAction)LoginClick:(id)sender
{
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate fbLogin:self];
}
The FBUser.h is a custom header file that defines the protocol method -(void)fbDidLogIn. This is just to make sure that, the app does not ask login permission each it time launches.
#import <Foundation/Foundation.h>
#protocol FBUser <NSObject>
-(void)facebookDidLogin;
#end
By this, the login method is only called when the app needs to login to Facebook and do something.
Hope this helps you. Cheers!

Facebook connect restarts my iPhone app

I'm building an iPhone App where i want to add Facebook login.
In viewDidLoad i've added:
facebook = [[Facebook alloc] initWithAppId:#"MYAPPID" andDelegate:self];
facebook.sessionDelegate=self;
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
When the user taps a button i invoke a function that does:
NSArray *permissions = [[NSArray arrayWithObjects:#"read_stream", #"publish_stream", #"offline_access",nil] retain];
[facebook authorize:permissions ];
It launches safari and makes the facebook login; the problem is that when it returns to the app, it relaunches the app, while i need to return directly to my ViewController, not to the FirstViewController.
What am i doing wrong?
Found the answer in an old SO thread
In facebook.m :
- (void)authorize:(NSArray *)permissions {
self.permissions = permissions;
[self authorizeWithFBAppAuth:NO safariAuth:NO];
}

ios facebook api not fire fbLogin

i need to use the facebook api:
in the appdelegate.m I have this code:
// Initialize Facebook
facebook = [[Facebook alloc] initWithAppId:#"MY_TOKEN" andDelegate:self];
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"] && [defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
after, in another view I have this:
AppDelegate* dlg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *permissions = [[NSArray alloc] initWithObjects:#"offline_access", nil];
if (![[dlg facebook] isSessionValid]) {
[[dlg facebook] authorize:permissions];
}
and works fine: call safari with the authorization to use my app, I click Ok to authorize and my app is called again... my app visualize the last view before the authorize, but the event
- (void)fbDidLogin
{
NSLog(#"fbDidLogin");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
in AppDelegate.m (my appdelegate have FBSessionDelegate) is not fired (also the other events of FBSessionDelegate like fbDidNotLogin are not fired...
where is my error?
thanks in advance
I think you forgot about this two methods and perhaps forgot to add your Facebook app id to URL types in info file. for more detail
// Pre 4.2 support
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [facebook handleOpenURL:url];
}
// For 4.2+ support
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [facebook handleOpenURL:url];
}

NSUserDefaults doubts in iphone SDK

I am integrating twitter in my app for sharing a text. My architecture of twitter integration is I have two Button _btnTwitter and _btntwitteLogout and when the user successfully login the twitter his name will display in _btntwitterLogout as title.
When the user tap the _btntwitterLogout it logs out the twitter and logout button hides and login button comes.every thing went ok.but when the user tap the login button(_btnTwitter) the Twitter login popup cmes for login purpose,here is the problem that am facing ,when the popup comes the user tap the cancel button of that popup the popup disappears and here the previous username of the user in the logout button.it didn't changes. I have put user defaults to check.
-(IBAction)_clickbtnTwitter:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Twitter_logged"];
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btntwitterLogeout.hidden = NO;
_btnTwitter.hidden=YES;
if (_engine) return;
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else {
[_engine sendUpdate: [NSString stringWithFormat: #"Already Updated. %#", [NSDate date]]];
}
}
}
then logout code
-(IBAction)_clickbtntwitterlogeout:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"Twitter_logged"];
crosstwitterimage.hidden = YES;
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btntwitterLogeout.hidden = YES;
_btnTwitter.hidden=NO;
_btnTwittermain.enabled = NO;
[_engine clearAccessToken];
[_engine clearsCookies];
[_engine setClearsCookies:YES];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"authData"];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"authName"];
NSLog(#"%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"authName"]);
NSLog(#"%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"authData"]);
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"Twitter_logged"];
[_engine release];
_engine=nil;
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
NSString* domainName = [cookie domain];
NSRange domainRange = [domainName rangeOfString:#"twitter"];
if(domainRange.length > 0)
{
[storage deleteCookie:cookie];
}
}
}
in viewwillappear
BOOL logged = [[NSUserDefaults standardUserDefaults] boolForKey:#"Twitter_logged"];
;
if (logged == YES) {
_btnTwitter. hidden = YES;
_btntwitterLogeout.hidden = NO;
crosstwitterimage.hidden = NO;
_btnTwittermain.enabled =YES;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Checks if there is a saved User Name
if([defaults objectForKey:#"kTwitterUserName"])
{
NSString *username = [defaults objectForKey:#"kTwitterUserName"];
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
crosstwitterimage.hidden = NO;
}
}
else
{
_btnTwitter. hidden = NO;
crosstwitterimage.hidden = YES;
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btnTwittermain.enabled =NO;
crosstwitterimage.hidden = YES;
}
but when i tap the cancel button in loginwindow of twitter,an comes back the username with the logout button shows ,if the user is already logedout from twitter.
is there any problem in my code.
thanks in advance.
EDIT
#pragma mark SA_OAuthTwitterEngineDelegate
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: #"authData"];
[defaults synchronize];
}
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {
return [[NSUserDefaults standardUserDefaults] objectForKey: #"authData"];
}
#pragma mark SA_OAuthTwitterControllerDelegate
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults synchronize];
}
- (void) OAuthTwitterControllerFailed: (SA_OAuthTwitterController *) controller {
NSLog(#"Authentication Failed!");
}
- (void) OAuthTwitterControllerCanceled: (SA_OAuthTwitterController *) controller {
NSLog(#"Authentication Canceled.");
}
#pragma mark TwitterEngineDelegate
- (void) requestSucceeded: (NSString *) requestIdentifier {
NSLog(#"Request %# succeeded", requestIdentifier);
}
- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {
NSLog(#"Request %# failed with error: %#", requestIdentifier, error);
}
Yes there is a problem. Whenever you hit the _btnTwitter, you are setting the Twitter_logged to yes. That's not correct. You should only set it to yes when there is a successful login. That is when the user has NOT hit cancel on the twitter login window.
In other words, you need to set the Twitter_logged to YES once the user has actually logged in, not when the user clicked on the button _btnTwitter
Seems like SA_OAuthTwitterController has a delegate property pointing to self. You should handle code to set Twitter_logged YES in that delegate method.
Hope that helps.
Edit:
Given the latest code here is where you should add the NsUserDefaults data
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults setBool:YES forKey:#"Twitter_logged"]; // Right here - mbh
[defaults synchronize];
}

Facebook IOS SDK trying to make singleton class?

Hy, i am trying to make from Facebook IOS SDK (Octomber 2011) a class of my own in where i can make all the methods and functions that i need and just import this class in any of my application view controllers and call it.
So this way i don't need to do all the initialization and delegation to the controllers in where i use the facebook.
So i want to do like this, [myfacebookclass initwithappID:myappid]
[myfacebookclass postmessage:#"some message"];
The thing is when i am seting authorizeWithFBAppAuth:YES safariAuth:YES flags in facebook.m ( the original class) and i do a postmessage it redirects me on Facebook Application or Safari and check's for permision, i hit ok and then redirects me in my application and doesn't post message.
WHen i am trying to post message i do like this :
This is in my own facebook class
myfacebookclass *facebook2;
+(void)initWithAppID:(NSString*) facebookAppId {
if (facebook2 == nil) {
facebook2 = [myfacebookclass new];
[facebook2 setWithAppId:facebookAppId];
}
}
- (void) postMessage1:(NSString *)messageToPost {
if ([self.facebook isSessionValid]) {
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
self.applicationID, #"api_key",
messageToPost, #"message",
nil];
[self.facebook requestWithGraphPath:#"me/feed" andParams:params andHttpMethod:#"POST" andDelegate:self];
} else {
NSArray * neededPermissions = [[[NSArray alloc] initWithObjects:#"user_about_me", #"publish_stream", nil] autorelease];
[self.facebook authorize:neededPermissions];
}
}
+ (void)postMessage:(NSString*) message {
[facebook2 postMessage1:message];
}
I also implemented:
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [facebook handleOpenURL:url];
}
i've didn't modified facebook.m or other classes in Facebook IOS SDK.
a good practice when making a singleton class is to use shared instance. Correct singleton also has to include some memory management overridden methods. In your case it can be done like this:
#implementation FacebookManager
static FacebookManager *mySharedFacebookManager;
+ (FacebookManager*)sharedFacebookManager {
#synchronized(self) {
if(mySharedFacebookManager == nil) {
mySharedFacebookManager = [[self alloc] init];
}
}
return mySharedFacebookManager;
}
+ (id)allocWithZone:(NSZone *)zone {
#synchronized(self) {
if(mySharedFacebookManager == nil) {
mySharedFacebookManager = [super allocWithZone:zone];
return mySharedFacebookManager;
}
}
return nil;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX;
}
- (oneway void)release {
}
- (id)autorelease {
return self;
}
In your case you may have Facebook type object as ivar, and some methods to wrap over FB API, for example like this:
- (id)init {
self = [super init];
if(self) {
facebook = [[Facebook alloc] initWithAppId:FB_APP_ID andDelegate:self];
// restore previous session
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
...
}
return self;
}
- (void)login {
NSArray *permissions = [NSArray arrayWithObjects: #"user_about_me", #"publish_stream", nil];
[facebook authorize:permissions];
}
- (void)postToFeed:(NSString*)messageToPost {
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
messageToPost, #"message",
nil];
[facebook requestWithGraphPath:#"me/feed"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
}
From other classes which have to deal with Facebook the construction is simple:
[[FacebookManager sharedFacebookManager] login];
...
[[FacebookManager sharedFacebookManager] postToFeed:#"Hello World!"];
I hope this snippets will help you.
To manage your facebook session you have to remember accessToken manually in FBSessionDelegate methods like that:
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
- (void)fbDidLogout {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"FBAccessTokenKey"];
[defaults removeObjectForKey:#"FBExpirationDateKey"];
[defaults synchronize];
}