FBConnect - sessionValid - AFTER delete application at the facebook-website - ios

In my iOS iPhone app I use facebook connect. The SSO works wonderfully, I can post to wall etc., But there is one problem:
I start my app
allow facebook to connect
everything is fine in the app
BUT NOW ...
I delete the application on the facebook website!
If I start my app now - the NSLOG says, the FB-Connections is OK. ..?
So I thought, If I delete the applications online in my account, the iphone app has NO validSession and has to ask for a new login, but this failed.
What is wrong? How can I check that in the right way? Or how log is the sessionValid? Is there a timelimit before the method will run again? So was my check (delete online, start app again) to quick?
---- UPDATE:
- (void)fbLogin:(id)sender{
NSLog(#"FB Login Alert");
[self checkForPreviouslySavedAccessTokenInfo];
if (!isConnected == YES) {
NSLog(#"NO - Facebook Connection");
UIAlertView *popupFacebook = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Headline_FacebookL", #"Headline")
message:NSLocalizedString(#"Facebook-Text", #"Facebook")
delegate:self
cancelButtonTitle:NSLocalizedString(#"later",#"Facebook Login später")
otherButtonTitles:NSLocalizedString(#"Facebook",#"Login"), nil];
popupFacebook.tag = alertFacebook;
[popupFacebook show];
[popupFacebook release];
}
else{
NSLog(#"Facebook Connection OK");
}
}
(void)checkForPreviouslySavedAccessTokenInfo:
-(void)checkForPreviouslySavedAccessTokenInfo{
// Initially set the isConnected value to NO.
isConnected = NO;
NSLog(#"FB Status erst mal auf NEIN");
// Check if there is a previous access token key in the user defaults file.
appDelegate.facebook = [[Facebook alloc] initWithAppId:#"XXXXXXXXX" andDelegate:(AppDelegate *) [[UIApplication sharedApplication] delegate]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
appDelegate.facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
appDelegate.facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
// Check if the facebook session is valid.
// If it’s not valid clear any authorization and mark the status as not connected.
if (![appDelegate.facebook isSessionValid]) {
//[facebook authorize:permissions];
isConnected = NO;
NSLog(#"FB NO");
}
else {
isConnected = YES;
NSLog(#"FB YES");
}
}
SWITCH:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"clicking");
//NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex];
if (alertView.tag == alertWelcome ) {
if (buttonIndex == 0) {
NSLog(#"close");
}
}
else if (alertView.tag == alertFacebook ) {
if (buttonIndex == 0) {
NSLog(#"später");
}
if (buttonIndex == 1) {
//self.label.text = NSLocalizedString(#"Facebook",#"Login"),
[self fbActive:nil];
NSLog(#"Login to FB");
}
}
}
Permissions:
-(void)fbActive:(id)sender{
if (![appDelegate.facebook isSessionValid]) {
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_likes",
#"read_stream",
#"user_status",
#"publish_stream",
//#"publish_actions",
//#"manage_pages",
#"read_requests",
nil];
[appDelegate.facebook authorize:permissions];
NSLog(#"FB - Permissions");
[permissions release];
}
}

Related

Switch state saved if sms sent

I have been trying to connect a switch to an SMS text which worked out fine, i was even able to save the state the switch was left in.
However now i need to save the state only if the SMS is sent, and if the user doesn't send the message but a switch is already turned on it should then alert them with a AlertView.
So far i have been able to save the state the switch was left it and connect a label to signify if it is "ON" or "OFF" in the SMS.
- (void)viewDidLoad {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
self->switch1.on = ([[standardDefaults stringForKey:#"switchKey"]
isEqualToString:#"On"]) ? (YES) : (NO);
if(switch1.on){
label.text = #"ON";
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
[defults setObject:label.text forKey:#"labelkey"];
[defults synchronize];
} else label.text = #"OFF"; {
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
[defults setObject:label.text forKey:#"labelkey"];
[defults synchronize];
}
label.text = [[NSUserDefaults standardUserDefaults]objectForKey:#"labelkey"];
}
- (IBAction)switchChanged:(UISwitch *)sender {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if (sender.on == 0) {
label.text = #"OFF";
[standardDefaults setObject:#"Off" forKey:#"switchKey"];
} else if (sender.on == 1) {
label.text = #"ON";
[standardDefaults setObject:#"On" forKey:#"switchKey"];
}
[standardDefaults synchronize];
}
This is how i send the SMS.
- (IBAction)sendRequest:(id)sender
{
MFMessageComposeViewController *messageVC = [[MFMessageComposeViewController alloc] init];
messageVC.body = [#[label.text] componentsJoinedByString:#""];
messageVC.recipients = #[_phoneNumber.text];
messageVC.messageComposeDelegate = self;
[self presentViewController:messageVC animated:NO completion:NULL];
}
By using MFMessageComposeViewControllerDelegate delegate, you can find Message is sent or cancelled by user.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
//show alert here as per your requirement break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Refer this link -> Send sms

Navigation in iOS using Objective-C

i have an ios app which uses a login page and after authenticating it enters into the inbox page.But after entering the inbox page it comes back automatically to the login page
Login.m
{
if ([username length] == 0 || [password length] == 0)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"Make sure you enter a username and password!"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
else
{
NSString *query = [NSString stringWithFormat:#"SELECT * FROM Login_Info WHERE username='%#'",username]; // Execute the query.
NSLog(#" query = %#", query );
// Get the results.
if (self.arrLogin_Info != nil) {
self.arrLogin_Info = nil;
}
self.arrLogin_Info = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
[def setObject:[self.arrLogin_Info objectAtIndex:0] forKey:#"idKey"];
[def setObject:[self.arrLogin_Info objectAtIndex:1] forKey:#"usernameKey"];
[def setObject:[self.arrLogin_Info objectAtIndex:2] forKey:#"passwordKey"];
[def setObject:[self.arrLogin_Info objectAtIndex:3] forKey:#"emailKey"];
NSLog(#" query output = %#", self.arrLogin_Info);
NSString *val = [self.arrLogin_Info objectAtIndex:2];
// NSLog(#" val = %#",val);
if ([val isEqualToString:password] )
{
// NSLog(#" Inside if before entering app");
[self.navigationController popToRootViewControllerAnimated:YES];
}
else
{
//NSLog(#" Inside else before entering app");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Sorry!"
message:#"Please ensure you have entered the correct password!"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}
}
#end
Inbox.m
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
id u = [def objectForKey:#"idkey"];
if(u)
{
NSString *query = [NSString stringWithFormat:#"Select *from Messages where recipient_ID=%#",u];
self.msg = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
// [self.tableView reloadData];
}
else
{
[self performSegueWithIdentifier:#"showLogin" sender:self];
}
// [self.tableView reloadData];
}
- (IBAction)logout:(id)sender {
//[PFUser logOut];
[self performSegueWithIdentifier:#"showLogin" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"showLogin" ])
{
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
}
Your Inbox view controller uses the presence of an object for the key 'idkey' in NSUserDefaults to determine whether the user is already logged in, or whether to show the login screen.
I presume that this line in login.m
[def setObject:[self.arrLogin_Info objectAtIndex:0] forKey:#"idKey"];
is supposed to be setting that key, but you don't show where you initialise def - so my guess is that this is nil and you aren't saving the data in NSUserDefaults.
Also, all of this -
if (self.arrLogin_Info != nil) {
self.arrLogin_Info = nil;
}
self.arrLogin_Info = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
can be simplified to this
self.arrLogin_Info = [self.dbManager loadDataFromDB:query];

Error in Facebook SDK iOS. FBSDKLog: An existing state change handler was assigned to the session and will be overwritten

I'm trying to make a function that login and logout the user when i click on the segmented button in the settings of my app. when the user clicks on Yes and the user is not yet login to Facebook, I'm opening a session and make the user login using safari, and when the user clicks on the No button, i want the app to logout the user and re-enter its email and password when the Yes button is clicked again.
and the code is this:
- (IBAction)fbSegmentTapped:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex)
{
case 0:{
if (FBSession.activeSession.isOpen) {
//Session is active
NSLog(#"Active 1");
if ([[NSUserDefaults standardUserDefaults] valueForKey:FB_TOKEN] !=nil) {
[self sendPostRequestToAPI_Yes];
}else{
NSLog(#"FB Token null");
}
} else {
// try to open session with existing valid token
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"public_profile", #"email", #"user_friends",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
//Session is active
NSLog(#"Active 2");
if ([[NSUserDefaults standardUserDefaults] valueForKey:FB_TOKEN] !=nil) {
NSLog(#"Move to Yes function");
[self sendPostRequestToAPI_Yes];
}else{
NSLog(#"You nid to login the user");
[self userLogin];
}
} else {
// you need to log the user
[self userLogin];
dataClass.fb_flag = #"false";
NSLog(#"user must login first");
}
}
break;
}
case 1:{
//No
NSLog(#"Clear the token and remove the session");
[self sendPostRequestToAPI_No];
break;
}
default:
break;
}
}
this function is when the user clicks no
-(void) sendPostRequestToAPI_No{
NSDictionary * dict2 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects: FB_PROVIDER, [[NSUserDefaults standardUserDefaults] valueForKey:#"id"], nil]
forKeys:[NSArray arrayWithObjects:#"name",#"user_id", nil]];
[webServiceController postRequestFromUrl:[NSString stringWithFormat:#"%#%#", ROOT_SERVER_URL, FB_SETTINGS_NO_URL] withDictionary:dict2];
}
and this is for Yes
-(void) sendPostRequestToAPI_Yes{
NSLog(#"%# - %# - %# - %#", [[NSUserDefaults standardUserDefaults] valueForKey:FB_EMAIL], [[NSUserDefaults standardUserDefaults] valueForKey:FB_PROVIDER_ID], [[NSUserDefaults standardUserDefaults] valueForKey:FB_TOKEN], [[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN]);
NSLog(#"Provider ID: %# and Email: %#", [[NSUserDefaults standardUserDefaults] valueForKey:#"id"], [[[NSUserDefaults standardUserDefaults] valueForKey:FB_USER_DETAILS] valueForKey:#"email"]);
if ([[NSUserDefaults standardUserDefaults] valueForKey:FB_TOKEN]!=nil) {[self userLogin];}
else{
NSDictionary * dict2 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:
FB_PROVIDER,
[[NSUserDefaults standardUserDefaults] valueForKey:FB_EMAIL],
[[NSUserDefaults standardUserDefaults] valueForKey:FB_PROVIDER_ID],
PUBLIC_KEY,
SECRET_KEY,
[[NSUserDefaults standardUserDefaults] valueForKey:FB_TOKEN],
[[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN],
nil]
forKeys:[NSArray arrayWithObjects:#"name",#"email",#"provider_id", #"public_key", #"secret_key",#"token",#"session_token", nil]];
[webServiceController postRequestFromUrl:[NSString stringWithFormat:#"%#%#", ROOT_SERVER_URL, FB_SETTINGS_YES_URL] withDictionary:dict2];
}
}
What could be the error?. it always returns: FBSDKLog: An existing state change handler was assigned to the session and will be overwritten.

Permission to read user's birthday, name and email

I am trying to integrate Facebook in my app. I need the user's birthday, name and email.
I have integrated the Facebookloginview from the sdk.
If I click on log in, the app switches to Safari and the page shows that I have already authorized the app. But I cannot get the email or the birthday
If I change the permissions like user_location, and then log out and log in the app shows that it is already authorized but it is not!
If I implement a button on the xib and then add to the ibaction this code works.
AppDelegate *appDelegate [[UIApplication sharedApplication] delegate];
// If the person is authenticated, log out when the button is clicked.
// If the person is not authenticated, log in when the button is clicked.
if (FBSession.activeSession.isOpen) {
[appDelegate closeSession];
} else {
// The person has initiated a login, so call the openSession method
// and show the login UX if necessary.
[appDelegate openSessionWithAllowLoginUI:YES];
}
}
Why doesn't it work with the facebookloginview?
Here is my facebook loginviewcontroller.m
- (void)viewDidLoad
{
[super viewDidLoad];
loginview = [[FBLoginView alloc]init];
loginview.readPermissions = #[#"email"];
//Facebook start
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:NO];
if (!appDelegate.session.isOpen) {
// create a fresh session object
appDelegate.session = [[FBSession alloc] init];
// if we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button, and so
// we check here to make sure we have a token before calling open
if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// we recurse here, in order to update buttons and labels
[self updateView];
}];
}
}
}
-(void) loginViewShowingLoggedOutUser:(FBLoginView *)loginView{
self.loginlabel.text = #"";
self.FBimageViewOutlet.profileID = nil;
NSLog(#"bin hier geklickt3");
}
-(void) loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
loginView.readPermissions = #[#"email"];
FBRequest *me = [FBRequest requestForMe];
[me startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *my,
NSError *error) {
self.loginlabel.text = [NSString stringWithFormat:#"Hi, %# %# geboren am %#",my.first_name,my.last_name,my.birthday];
self.FBimageViewOutlet.profileID = my.id;
self.picView.profileID =my.id;}];
//self.loginlabel.text = [NSString stringWithFormat:#"Hi, %# %# geboren am %#",user.first_name,user.last_name,user.birthday];
self.FBimageViewOutlet.profileID = user.id;
//Hier wird gender von Facebook abgefragt
NSLog(#"%#",[user objectForKey:#"gender"]);
NSLog(#"%#",[user objectForKey:#"locale"]);
NSLog(#"%#",[user objectForKey:#"age_range"]);
NSLog(#"%#",[user objectForKey:#"username"]);
NSLog(#"%#",[user objectForKey:#"link"]);
NSLog(#"%#",[user objectForKey:#"location"]);
NSLog(#"%#",[user objectForKey:#"hometown"]);
NSLog(#"%#",[user objectForKey:#"birthday"]);
NSLog(#"%#",[user objectForKey:#"last_name"]);
NSLog(#"%#",[user objectForKey:#"first_name"]);
NSLog(#"%#",[user objectForKey:#"email"]);
NSLog(#"%#",[user objectForKey:#"user_email"]);
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
[defaults setObject:[user objectForKey:#"gender"] forKey:#"user_gender"];
[defaults setObject:[user objectForKey:#"locale"] forKey:#"user_locale"];
[defaults setObject:[user objectForKey:#"age_range"] forKey:#"user_age_range"];
[defaults setObject:[user objectForKey:#"username"] forKey:#"user_username"];
[defaults setObject:[user objectForKey:#"link"] forKey:#"user_link"];
[defaults setObject:[user objectForKey:#"location"] forKey:#"user_location"];
[defaults setObject:[user objectForKey:#"hometown"] forKey:#"user_hometown"];
[defaults setObject:[user objectForKey:#"birthday"] forKey:#"user_birthday"];
[defaults setObject:[user objectForKey:#"last_name"] forKey:#"user_lastname"];
[defaults setObject:[user objectForKey:#"first_name"] forKey:#"user_firstname"];
}
- (void)loginView:(FBLoginView *)loginView
handleError:(NSError *)error {
AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
// If the person is authenticated, log out when the button is clicked.
// If the person is not authenticated, log in when the button is clicked.
if (FBSession.activeSession.isOpen) {
[appDelegate closeSession];
} else {
// The person has initiated a login, so call the openSession method
// and show the login UX if necessary.
[appDelegate openSessionWithAllowLoginUI:YES];
}
NSString *alertMessage, *alertTitle;
if (error.fberrorShouldNotifyUser) {
// If the SDK has a message for the user, surface it. This conveniently
// handles cases like password change or iOS6 app slider state.
alertTitle = #"Facebook Error";
alertMessage = error.fberrorUserMessage;
} else if (error.fberrorCategory == FBErrorCategoryAuthenticationReopenSession) {
// It is important to handle session closures since they can happen
// outside of the app. You can inspect the error for more context
// but this sample generically notifies the user.
alertTitle = #"Session Error";
alertMessage = #"Your current session is no longer valid. Please log in again.";
} else if (error.fberrorCategory == FBErrorCategoryUserCancelled) {
// The user has cancelled a login. You can inspect the error
// for more context. For this sample, we will simply ignore it.
NSLog(#"user cancelled login");
} else {
// For simplicity, this sample treats other errors blindly.
alertTitle = #"Unknown Error";
alertMessage = #"Error. Please try again later.";
NSLog(#"Unexpected error:%#", error);
}
if (alertMessage) {
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
}

How can I make UIAlertView modal?

I want to show a login dialogue and login error dialogue if necessary.
I use UIAlertView to show these dialogues, but the process keep running while showing the UIAlertView.
I wrote a code below. Now NSUserDefaults doesn't keep those value, so I expected login dialogue is shown and wait until button to be tapped.
But when run this, error dialogue is shown and after tapping OK for this, login dialogue is shown.
How can I fix this?
Thanks in advance.
- (void)storeEvernote
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
evID = [defaults stringForKey:#"evID"];
evPW = [defaults stringForKey:#"evPW"];
NSLog(#"%#", evID);
if( evID == NULL || evPW == NULL )
{
login = true;
[self showLoginDialogue];
}
else
{
evernoteID = evID;
evernotePW = evPW;
}
if( evernoteID == NULL || evernotePW == NULL )
{
login = false;
[self showErrMessage];
return;
}
[self getEvernoteNotebooks];
}
- (void)showLoginDialogue
{
UIAlertView *loginDialogue = [[UIAlertView alloc] initWithTitle:#"Evernote Login" message:#"Enter your Evernote Info" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Login", nil];
loginDialogue.delegate = self;
loginDialogue.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
[loginDialogue show];
}
- (void)showErrMessage
{
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:#"Login Failure" message:#"Invalid ID & Password" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[loginalert show];
}
The first time that storeEvernote method runs, evID and evPW are NULL so the first if is true, it shows the LoginDialoge then it continues to second if and because evernoteID and evernotePW are still NULL so the condition in second if statement is also true, so it shows the errorMessage. To fix this, move the second if statement to delegate method of the loginDialogue ALSO ADD return; to the end of first if statement for example:
- (void)storeEvernote
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
evID = [defaults stringForKey:#"evID"];
evPW = [defaults stringForKey:#"evPW"];
NSLog(#"%#", evID);
if( evID == NULL || evPW == NULL )
{
login = true;
[self showLoginDialogue];
return;
}
else
{
evernoteID = evID;
evernotePW = evPW;
}
[self getEvernoteNotebooks];
}
//The login dialoge delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//Process user input
...
if( evernoteID == NULL || evernotePW == NULL )
{
login = false;
[self showErrMessage];
return;
}
[self getEvernoteNotebooks];
}

Resources