How to clear username and password on CocoaLibSpotify logout? - objective-c

I'm using the CocoaLibSpotify library to develop an iOS application that will utilize the Spotify API. I've got it just about where I want it, but I've run into a bit of a problem.
When the user touches my "Logout of Spotify" button, I execute the following code:
-(IBAction)logoutButtonTouched:(id)sender
{
// Clear out the user's settings that I am saving.
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
[[SPSession sharedSession] logout:^(void) {
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
controller.allowsCancel = NO;
}];
}
This does indeed logout the user and display the SPLoginViewController, but my problem is, the username and password field still contain the values that they'd logged-in with. Does anyone know of a way to clear these fields when I display the SPLoginViewController?

This functionality isn't in the login controller, which is indeed a bug.
You can do it like this. Please note that this is really fragile code and will fail if any internal detail of the login controller changes, and it will in the future:
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
id internalLoginViewController = [controller.viewControllers objectAtIndex:0];
UITextField *loginField = [internalLoginViewController valueForKey:#"usernameField"];
UITextField *passwordField = [internalLoginViewController valueForKey:#"passwordField"];
loginField.text = #"";
passwordField.text = #"";

Related

Save the session even if the app is killed Objective C

I'm developing an app in Objective C and everything is cool but i am really new in this, so i was wondering if there is a way to save the session from a user that has already logged in into my app, I save the username + password cause I use them later but when i close the app, (kill it), i have to log in again, so i was hoping that you guys could help me with this:
Here is how i save the session in my code:
NSString *user = [textUser text];
NSString *password = [textPassword text];
[[NSUserDefaults standardUserDefaults] setObject:user forKey:#"userName"];
[[NSUserDefaults standardUserDefaults] setObject:password forKey:#"userPassword"];
[[NSUserDefaults standardUserDefaults] synchronize];//here is where i save the user info but i want it to stay even if the app is killed
So what i think i need is a method that checks if NSUserDefaults is empty or not, then go straight to my home-screen-activity
Thanks!
I'm not sure, whether I understood your Q correctly!? Do you want to know how to check, whether there are already log-in data?
NSString *user = [[NSUserDefaults standardUserDefaults] objectForKey:#"userName"];
if (user)
{
// User name already has been stored
…
}
else
{
// User name is not stored
}
Use this Method to check login:
method returns YES if user already logged in else returns NO.
-(BOOL)CheckLogin{
if ([[NSUserDefaults standardUserDefaults]valueForKey:#"userName"] && [[NSUserDefaults standardUserDefaults]valueForKey:#"userPassword"]) {
//go straight to my home-screen-activity
return YES;
}
else{
//required to login
return NO;
}
}
Hope this helps.

Programmatically logging in to website with saved username and password

One of the functions of an app I am making involves logging the user into our Campus Portal website. For ease of use, the user may enter a username and password into the app once, and it will be saved for all future log-ins. When the user clicks a button, the information will automatically be sent to log in, and the website will be displayed in a UIWebView.
Let us say that the username and password are each stored in an NSString. How can I use this data to log in to this website programmatically and display the page it in a UIWebView?
I know little about posting and forms, so any help is appreciated.
Would something like this Stackoverflow answer help?
Here's the shell of my code for this
- (IBAction)btnGo:(id)sender {
username = usernameField.text;
password = passwordField.text;
if (saveSwitch.isOn) {
//Save data if the user wants
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
usernameSaved = username;
passwordSaved = password;
[appDelegate.listOfPortalCredentials replaceObjectAtIndex:0 withObject:usernameSaved];
[appDelegate.listOfPortalCredentials replaceObjectAtIndex:1 withObject:passwordSaved];
}
//Insert username and password to web form, log in to portal
//This is where I need help
}
Edit:
Thanks to Karthik I was able to find the HTTP Post using Firebug. It gave me:
appName=ridgefield&portalUrl=portal%2Fridgefield.jsp%3F%26rID%3D0.18423783694092&username=<username>&password=<password>&B1=Log+In&url=portal%2Fmain.xsl%3FrID%3D0.6845596700302482&lang=en
where and represent the real username and password. I believe this is what I need. Using this, how can I display the logged-in page in a UIWebView? Do I just need to load the above URL in the UIWebView?
Use UIWebView, and do a http POST to https://ic.ridgefield.org/campus/verify.jsp with username and password.
To understand how it works, install Firebug on Firefox browser and go to 'Net' tab on firebug, and then open your website and enter some username/password.
You should mimic that action using code. (I always get invalid username or password response from server, coz i dont have an account and i try some random ones, and since there is no signup on the site, there is no way for me to verify this)
UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.frame];
[self.view addSubview:webView];
NSString* username = #"";
NSString* password = #"";
NSURL* url = [NSURL URLWithString:#"https://ic.ridgefield.org/campus/verify.jsp"];
NSString* body = [NSString stringWithFormat:#"appName=ridgefield&username=%#&password=%#", username, password];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30];
request.HTTPMethod = #"POST";
request.HTTPBody = [body dataUsingEncoding:NSStringEncodingConversionAllowLossy];
[webView loadRequest:request];

Show screen on first launch only in iOS

Tweetbot and Clear show's on the first start of the app a small tutorial screen how the app works. The screen with the small tutorial only pops up on the first start up of the app (1 time)
How and with what can i make a similar thing? Can anyone push me in the right direction?
View i mean:
I'm assuming by Xcode you actually mean iOS.
What you need to do is use the NSUserDefaults class to store a flag indicating whether the user has seen the tutorial screen before.
When your app first loads (or at the point you want to decide whether or not to show the tutorial screen), do something like this:
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"hasSeenTutorial"])
[self displayTutorial];
This checks the saved NSUserDefaults for the current user for a value named "hasSeenTutorial", which won't exist yet. Since it doesn't exist, it will call displayTutorial. displayTutorial refers to your method for creating the tutorial view. You can figure out that part.
Then, once the user closes the tutorial screen:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasSeenTutorial"];
That value will be saved for your user profile, meaning the next time it checks it, it will be true, so displayTutorial won't be called.
In your viewDidLoad:
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults]
objectForKey:#"aValue"]]) {
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"aValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
//Action here
}
Certainly, if we would like to tell user something about features after update (not only app launched first time), the solution below could be suitable.
In your viewDidLoad:
NSString *currentBundleVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleVersion"];
NSString *previousBundleVersion = [[NSUserDefaults standardUserDefaults] objectForKey:#"PreviousBundleVersion"];
if (![currentBundleVersion isEqualToString:previousBundleVersion] ) {
// Here you can initialize your introduction view and present it!
}
Once the user closes the intro:
NSString *currentBundleVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleVersion"];
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:currentBundleVersion forKey:#"PreviousBundleVersion"];
[standardUserDefaults synchronize];
}
In this case app bundle version stored in your standardUserDefaults will be differ from current bundle version only after update and shown only once as well as at first launch.
Initialise your user defaults with a BOOL, something called instructionsSeen (or whatever you want) and set it to NO in your App delegate's initialize method.. In your app, test this value and if it is NO display your tutorial screen. As part of showing and displaying this screen, set the instructionsSeen to YES and store it in your defaults.
This way the demo screen will only show on first launch, unless the user uninstalls and installs the app again.
You could also show the demo for a small number of launches (say 3). In this case, don't use BOOL use a number and increment it instead.
Xamarin.iOS Version within AppDelegate:
UIStoryboard storyboard = UIStoryboard.FromName("Main", null);
if (NSUserDefaults.StandardUserDefaults.BoolForKey ("hasSeenTutorial") == false) {
UIViewController vc = storyboard.InstantiateViewController ("StartPageViewController");
this.Window.RootViewController = vc;
} else {
UIViewController vc = storyboard.InstantiateViewController ("NonStartPageViewController");
this.Window.RootViewController = vc;
}
this.Window.MakeKeyAndVisible ();
In my StartPageViewController, I have a button which sets NSUserDefaults to true, so the next time it runs, it will start off with the NonStartPageViewController:
partial void RegisterButton_TouchUpInside (UIButton sender)
{
NSUserDefaults.StandardUserDefaults.SetBool(true,"hasSeenTutorial");
NSUserDefaults.StandardUserDefaults.Synchronize();
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"firstRun"]) {
[defaults setObject:[NSDate date] forKey:#"firstRun"];
[self displayTutorial];
}
Swift version :
if !(NSUserDefaults.standardUserDefaults().boolForKey("seenTutorial")) {
//Tutorial part
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "seenTutorial")
}
Everyone is making this more complex and vauge than it needs to be... Simple complete solution.
In the ViewDidLoad:
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"FirstLoadKey"]) {
self.imageView.hidden = YES;
}else{
self.imageView.hidden = NO;
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"FirstLoadKey"];
[[NSUserDefaults standardUserDefaults]synchronize];
}

Can't show the right URL in my iPad simulator

I'm building an iPad app and that's a browser. I have a little problem because in a text field, I can write any web direction, such http://www.google.com/. The problem is that when I change the page, at, for example, http://www.apple.com/ , it stills says google. I have written the code, but I don't know why it doesn't work!
-(void)currentURL{
int i= 0;
while (i == 0) {
url = [request URL];
NSLog(#"%#", url.absoluteString);
textfield.text = url.absoluteString;
}}
Please I need some help!
replace this:
textfield.text = url.absoluteString;
with this:
if(textfield)
{
if(url)
{
textfield.text = [url absoluteString];
} else {
NSLog( #"my request or URL is nil");
}
} else {
NSLog( #"I didn't set my textfield");
}
You need to implement the web view delegate which will tell you when the page inside the web view changes, e.g. when the user clicks a link. You can then use the delegate methods to update your text field to the new URL.
if you've done that and your textfield isn't updating, you've probably forgotten to connect your textfield in your nib file to the textfield outlet of your class, so your self.textfield property is nil and setting its text does nothing.

objective-c : Twitter login error on iPad : Whoa there

I've been using the classic Ben Gottlieb Twitter Open Source project to create a twitter login for iPad.
My code to instantiate the engine and display the login controller is:
if (!_engine) {
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
[_engine setConsumerKey:#"kConsumerKey"];
[_engine setConsumerSecret:#"kConsumerSecret"];
}
if (![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
if ([controller respondsToSelector:#selector(setModalPresentationStyle:)] == YES) {
controller.modalPresentationStyle = UIModalPresentationFormSheet;
}
[self presentModalViewController:controller animated:YES];
return;
}
}
In addition, I set the URLS for SA_OAuthTwitterEngine to https:
self.requestTokenURL = [NSURL URLWithString: #"https://twitter.com/oauth/request_token"];
self.accessTokenURL = [NSURL URLWithString: #"https://twitter.com/oauth/access_token"];
self.authorizeURL = [NSURL URLWithString: #"https://twitter.com/oauth/authorize"];
and my TWITTER_DOMAIN in MGTwitterEngine.m has been changed to:
#define TWITTER_DOMAIN #"api.twitter.com/1"
Running this code in the simulator for both iPhone and iPad works like a charm. HOWEVER, whenever I test this code on an iPad device, I'm thrown this error:
Whoa there! The request token for this page is invalid. It may have
already been used, or expired because it is too old. Please go back to
the site or application that sent you here and try again; it was
probably just a mistake
(Screenshot attached).
Any suggestions on how to get the standard login screen to appear will be greatly appreciated
I had the same problem and tried Jeff's way. It didn't work either. For some unknown reason, check your time settings and set to automatically set the time. This worked for me.
I ran into the same issue. What happens is that the request doesn’t get a request token. You can explicitly call that:
SA_OAuthTwitterEngine *myEngine;
[myEngine requestRequestToken];
Hope this helps!