I am integrating Linked-in in my iOS application to Login my app.it works fine for me ..it login successfully when i enter the credentials in the app and enters in the app successfully ....but when i logout and login again it ask for the Access-->allow access button without asking the credientials but I want allow access page should not come on the next login ...means after logout when again i click on the linkedin``login...it should directly access to the app ..should not ask for image 2..
image 2 which comes on the second time login..which i dont want to come
.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSMutableArray *toolbarButtons = [toolBar.items mutableCopy];
// toolbarItems = [[NSMutableArray arrayWithArray:toolbar.items]
// This is how you remove the button from the toolbar and animate it
// This is how you add the button to the toolbar and animate it
if (!firstTime1||![loginView canGoBack])
{
[toolbarButtons removeObject:backButton];
[toolBar setItems:toolbarButtons animated:YES];
firstTime1=YES;
}
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
BOOL requestForCallbackURL = ([urlString rangeOfString:[LinkedIn linked].linkedInCallbackURL].location != NSNotFound);
if ( requestForCallbackURL )
{
BOOL userAllowedAccess = ([urlString rangeOfString:#"user_refused"].location == NSNotFound);
if ( userAllowedAccess )
{
if ([self logoutPreviousSession])
{
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:#"SuccessfulLogin"];
[DelegateClass magazine]._loggedThrough=#"LinkedIn";
[[LinkedIn linked].requestToken setVerifierWithUrl:url];
[[LinkedIn linked] accessTokenFromProvider];
}
}
else
{
[self dismissModalViewControllerAnimated:YES];
}
}
return YES;
}
Related
I just built my first app and now I started testing it on my phone. It looks great when I first launch the app after building it, the launch images appears and then my json data is loaded via NSURL and displays properly on the app. But when I close down the app, update the data via php and mysql and re open it the launch image does not appear and my app is not updated. Is it possible to have the app launch like it did when I first launched it, always have launch image and also get the new data?
Here is my code if it helps.
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadJSON];
}
- (void)loadJSON
{
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Error" message: #"Connection Failed" delegate: self cancelButtonTitle:#"Refresh" otherButtonTitles:nil]; [alert show]; [alert release];
});
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:#"http://url.com/GetData.php"];
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:nil];
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *firstItemArray = array[0];
NSString *yesNoString = firstItemArray[0];
NSString *dateString = firstItemArray[1];
NSString *timeString = firstItemArray[2];
NSString *homeString = firstItemArray[3];
NSString *awayString = firstItemArray[4];
NSString *lastUpdatedString = firstItemArray[5];
dispatch_async(dispatch_get_main_queue(), ^{
self.YesOrNo.text = yesNoString;
self.date.text = [#"For " stringByAppendingString:dateString];
self.time.text = timeString;
self.home.text = homeString;
self.away.text = awayString;
self.lastUpdated.text = lastUpdatedString;
self.lastUpdatedText.text = #"Last Updated";
self.vs.text = #"vs";
});
});
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[self loadJSON];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[_YesOrNo release];
[_date release];
[_time release];
[_vs release];
[_home release];
[_away release];
[_lastUpdatedText release];
[_lastUpdated release];
[super dealloc];
}
#end
If someone can point me in the right direction, that would be great and appreciated, thanks.
When you hit the round home button when running an app, it just puts it into the background, where it continues to run in a type of catatonic state. When you tap its icon again, it just wakes up, and doesn't re-launch. If you'd like to have your app completely quit when the user hits the home button, use the info.plist option "UIApplicationExitsOnSuspend" also known as "Application does not run in background." Set this to YES in your info.plist, and you'll get a fresh start every time. You can access this by clicking on your project in Xcode in the Project Navigator mode, and select the "info" tab at the top middle.
As it is your first app, you should try reading about the various devices and os versions.
Read about various application states, also the methods that are present in the AppDelegateClass, that get called when the app enters into various states,try reading about them.
So what has happened in your case is the device that you are using is Multitasking one. So when you press the home button or the sleep button the game goes to background, and is not killed. So next time when you tap on the application icon on your device, it brings it back to the foreground and does not relaunch it hence your Viewdidload method won't be called and your changes won't get reflected.
So, now to terminate your app, you can go through this link
http://www.gottabemobile.com/2013/02/10/how-to-close-apps-on-iphone/
Hope this helps.
Using a Parse Framework, I am trying to have a user login to an app and if the login works when the user presses the login button, I want the view to change. In this specific case if(!error) I want the view to switch. Assuming the second view is called PostingViewController, how could I make this work?
-(IBAction)signUpButton:(id)sender
{
NSString *userInput = usernameInputField.text;
NSString *userPassword = passwordInputField.text;
PFUser *user = [PFUser user];
user.username = userInput;
user.password = userPassword;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(!error){
}
else{
NSLog(#"there was a problem");
}
}];
}
simply create an object of PostingViewController object and push it to the current navigationController
some thing similar to this might be of help...
PostingViewController *vc = [[PostingViewController alloc] initWithNibName:#"your_nib_name" andBundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vc withAnimation:YES];
[vc release];
in iOS 5.0 i was opening Twitter setting from my app by
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"prefs:root=TWITTER"]];
but , this features is removed in iOS 5.1 , hence i can not able to open twitter setting .
Now i am using
+ (void)makeRequestsWithURL: (NSURL *)url {
// Create an account store object.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[self canTweetStatus];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
// For the sake of brevity, we'll assume there is only one Twitter account present.
// You would ideally ask the user which account they want to tweet from, if there is more than one Twitter account present.
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
// Create a request, which in this example, posts a tweet to the user's timeline.
// This example uses version 1 of the Twitter API.
// This may need to be changed to whichever version is currently appropriate.
TWRequest *postRequest = [[TWRequest alloc] initWithURL:url parameters:nil requestMethod:TWRequestMethodPOST];
// Set the account used to post the tweet.
[postRequest setAccount:twitterAccount];
// Perform the request created above and create a handler block to handle the response.
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
iOS5Twitter *twitter5 = [[iOS5Twitter alloc] init];
[twitter5 performSelectorOnMainThread:#selector(displayText:) withObject:output waitUntilDone:NO];
[twitter5 release]; }];
}
}
}];
}
for making request, i am able to check wether i am loged in or not by the
if ([TWTweetComposeViewController canSendTweet])
but now i want : if i am not loged in it would be show an alert like shown in image and want to move to the twitter setting . is it possible ? or i have to manually go ti twitter setting ?
It is little tricky , i get by the removing the subviews in *TWTWeetComposeViewController*, so it shows only alert when user is not loged in and by the clicking on setting button , we can open Setting page in my app.
+ (void)setAlertForSettingPage :(id)delegate
{
// Set up the built-in twitter composition view controller.
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// Create the completion handler block.
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
[delegate dismissModalViewControllerAnimated:YES];
}];
// Present the tweet composition view controller modally.
[delegate presentModalViewController:tweetViewController animated:YES];
//tweetViewController.view.hidden = YES;
for (UIView *view in tweetViewController.view.subviews){
[view removeFromSuperview];
}
}
here , deleate is your viewcontroller , if you are using this method inside your viewcontroller just use self instead of delegate.
iOS 6 uses SLComposeViewController instead of TWTweetComposeViewController, so now you have to do this if you want it to work on iOS 6 and iOS 5:
UIViewController *tweetComposer;
if([SLComposeViewController class] != nil)
{
tweetComposer = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[(SLComposeViewController *)tweetComposer setCompletionHandler:^(SLComposeViewControllerResult result)
{
// do whatever you want
}];
}
else
{
tweetComposer = [[TWTweetComposeViewController alloc] init];
[(TWTweetComposeViewController *)tweetComposer setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
// do whatever you want
}];
}
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
[self presentViewController:tweetComposer animated:NO completion:nil];
Building upon Senior's and PJR's answers above, this is what worked for me.
Same as Senior's, except with a dimissViewController in the completion handler. For me this got around the problem that the empty view controller would stick around after I returned to the app from the settings. It would overlay my view controller and make it useless.
Brilliant solution, thanks Senior and PJR.
UIViewController *tweetComposer;
if([SLComposeViewController class] != nil)
{
tweetComposer = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[(SLComposeViewController *)tweetComposer setCompletionHandler:^(SLComposeViewControllerResult result)
{
[self dismissViewControllerAnimated:NO completion:nil];
}];
}
else
{
tweetComposer = [[TWTweetComposeViewController alloc] init];
[(TWTweetComposeViewController *)tweetComposer setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
[self dismissViewControllerAnimated:NO completion:nil];
}];
}
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
[self presentViewController:tweetComposer animated:NO completion:nil];
To remove the post view,
instead using this code:
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
use this:
tweetComposer.view.alpha = 0;
works both for twitter and facebook.
I am teaching myself how to program an iPhone app by looking at code examples from various sources online, so it is fair to say that I do not understand the language (yet).
I am have successfully built a UIWebView browser app that goes to a login page. However, I am trying to take it one step further by having the
Following Byron's code on his own stack overflow question, I have tried to follow in his footsteps.
Is it possible for a UIWebView to save and autofill previously entered form values (e.g., username & password)?
However, when the following line of code is live in the app, the browser will only load a blank page.
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
I really appreciate any assistance to help get me back on the right track. Thank you very much,
Below is my entire code:
#import "ViewController.h"
// 6/13/2012 added to cache username and password
#import
#import "SFHFKeychainUtils.h"
// -----
#interface ViewController ()
#end
#implementation ViewController
#synthesize webView;
#synthesize spinner;
-(IBAction)goBack:(id)sender{
if ([webView canGoBack]) {
[webView goBack];
}
}
-(IBAction)goForward:(id)sender{
if ([webView canGoForward]){
[webView goForward];
}
}
- (void)viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"http://xxxxxx.com/weblink/hh_login.html"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
// 6/13/2012 added to cache username and password
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
//save form data
if(navigationType == UIWebViewNavigationTypeFormSubmitted) {
//grab the data from the page
NSString *username = [self.webView stringByEvaluatingJavaScriptFromString: #"document.myForm.username.value"];
NSString *password = [self.webView stringByEvaluatingJavaScriptFromString: #"document.myForm.password.value"];
//store values locally
[[NSUserDefaults standardUserDefaults] setObject:username forKey:#"username"];
[SFHFKeychainUtils storeUsername:username andPassword:password forServiceName:#"MyService" updateExisting:YES error:nil];
}
}
// -----
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[spinner startAnimating];
}
//- (void)webViewDidFinishLoad:(UIWebView *)webView {
// [spinner stopAnimating];
//}
// 6/13/2012 added to cache username and password
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[spinner stopAnimating];
//verify view is on the login page of the site (simplified)
NSURL *requestURL = [self.webView.request URL];
if ([requestURL.host isEqualToString:#"http://xxxxxx.com/weblink/hh_login.html"]) {
//check for stored login credentials
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:#"username"];
if (username.length != 0 ) {
//create js strings
NSString *loadUsernameJS = [NSString stringWithFormat:#"document.myForm.username.value ='%#'", username];
NSString *password = [SFHFKeychainUtils getPasswordForUsername: username andServiceName:#"MyService" error:nil];
if (password.length == 0 ) password = #"";
NSString *loadPasswordJS = [NSString stringWithFormat:#"document.myForm.password.value ='%#'", password];
//autofill the form
[self.webView stringByEvaluatingJavaScriptFromString: loadUsernameJS];
[self.webView stringByEvaluatingJavaScriptFromString: loadPasswordJS];
}
}
}
// -----
#end
TRY BELOW ONE
You need to fill the credential when webview has loaded .
below is the delegate method of UIWebView called when the WebView has loaded.At this time pass the credential not as were passing before loading the UIWebView which is not correct.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if(!isLoggedIn){//just load only onetime.
//pass the login Credintails into textfield of WebView.
NSString* userId = #"userName" //here just replace that string to the username
NSString* password = #"password";//here just replace that string to the password
if(userId != nil && password != nil ){
NSString* jScriptString1 = [NSString stringWithFormat:#"document.getElementById('username').value='%#'", userId];
//username is the id for username field in Login form
NSString* jScriptString2 = [NSString stringWithFormat:#"document.getElementById('password').value='%#'", password];
//here password is the id for password field in Login Form
//Now Call The Javascript for entring these Credential in login Form
[webView stringByEvaluatingJavaScriptFromString:jScriptString1];
[webView stringByEvaluatingJavaScriptFromString:jScriptString2];
//Further if you want to submit login Form Automatically the you may use below line
[webView stringByEvaluatingJavaScriptFromString:#"document.forms['login_form'].submit();"];
// here 'login_form' is the id name of LoginForm
}
isLoggedIn=TRUE;
}
}
It'll really help you.
I'm trying to implement a custom login view to Twitter (I don't want that UIWebView).
I've downloaded many classes, and I'm so far having a nightmare with this. Now I'm trying to make Twitter + oAuth work. Here's the demo code (that works):
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
[_engine requestRequestToken];
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else
[_engine sendUpdate: [NSString stringWithFormat: #"Already Updated. %#", [NSDate date]]];
Now what I wanna do is replace that SA_OAuthTwitterController with custom UITextFields. So I'm trying this:
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
[_engine requestRequestToken];
[_engine requestAccessToken];
[_engine setUsername:#"username" password:#"password"];
[_engine sendUpdate:#"tweet"];
But I keep getting error 401. I'm probably missing a step. Anyone?
The view controller you are eliminating loads a webview that prompts the user to authenticate your application with twitter. If you don't ever have the user authenticate, you won't be able to make authenticated twitter calls. There is a way to do what you are wanting, however, you have to go through all of the OAuth steps yourself. Here are the steps as specified from a different web service (Vimeo), but the same rules apply:
Your application sends a request
with your consumer key, and signed
with your consumer secret, for a
something called a request token. If
we verify your application
correctly, we'll send you back a
request token and a token secret.
You'll then create a link for the user to click on with the request token.
When the user gets to Vimeo, they'll be prompted to allow your
application access to their account.
If they click yes, we'll send them
back to your application, along with
a verifier.
You'll then use the request token, verifier, and token secret to make
another call to us to get an access
token. The access token is what
you'll use to access the user's
information on Vimeo.
OAuth is a real pain in the rump, so good luck. ;-)
I think the bit you're missing is here, SA_OAuthTwitterEngine.m:103:
//This generates a URL request that can be passed to a UIWebView. It will open a page in which the user must enter their Twitter creds to validate
- (NSURLRequest *) authorizeURLRequest {
if (!_requestToken.key && _requestToken.secret) return nil; // we need a valid request token to generate the URL
OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL: self.authorizeURL consumer: nil token: _requestToken realm: nil signatureProvider: nil] autorelease];
[request setParameters: [NSArray arrayWithObject: [[[OARequestParameter alloc] initWithName: #"oauth_token" value: _requestToken.key] autorelease]]];
return request;
}
You will have to "fake" this user login out yourself, I believe by sending twitter the login credentials as a separate request. It appears that the setUsername method you're calling is actually called as a post operation once a valid access token has been received. See SA_OAuthTwitterEngine.m:185
//
// access token callback
// when twitter sends us an access token this callback will fire
// we store it in our ivar as well as writing it to the keychain
//
- (void) setAccessToken: (OAServiceTicket *) ticket withData: (NSData *) data {
if (!ticket.didSucceed || !data) return;
NSString *dataString = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
if (!dataString) return;
if (self.pin.length && [dataString rangeOfString: #"oauth_verifier"].location == NSNotFound) dataString = [dataString stringByAppendingFormat: #"&oauth_verifier=%#", self.pin];
NSString *username = [self extractUsernameFromHTTPBody:dataString];
if (username.length > 0) {
[[self class] setUsername: username password: nil];
if ([_delegate respondsToSelector: #selector(storeCachedTwitterOAuthData:forUsername:)]) [(id) _delegate storeCachedTwitterOAuthData: dataString forUsername: username];
}
[_accessToken release];
_accessToken = [[OAToken alloc] initWithHTTPResponseBody:dataString];
}
So the steps are as follows:
Request request token
Fake user login to twitter and get the pin value
Set the pin on the engine
Request access token
You can see where SA_OAuthTwitterController parses the pin out of the webview content in SA_OAuthTwitterController.m:156
#pragma mark Webview Delegate stuff
- (void) webViewDidFinishLoad: (UIWebView *) webView {
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource: #"jQueryInject" ofType: #"txt"];
NSString *dataSource = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (dataSource == nil) {
NSLog(#"An error occured while processing the jQueryInject file");
}
[_webView stringByEvaluatingJavaScriptFromString:dataSource]; //This line injects the jQuery to make it look better
NSString *authPin = [[_webView stringByEvaluatingJavaScriptFromString: #"document.getElementById('oauth_pin').innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (authPin.length == 0) authPin = [[_webView stringByEvaluatingJavaScriptFromString: #"document.getElementById('oauth_pin').getElementsByTagName('a')[0].innerHTML"] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[_activityIndicator stopAnimating];
if (authPin.length) {
[self gotPin: authPin];
}
if ([_webView isLoading] || authPin.length) {
[_webView setHidden:YES];
} else {
[_webView setHidden:NO];
}
}
hope this helps.
You have to use xAuth for custom user/pass controls. But it requires the permission from Twitter.