Login form for Evernote in ios - iphone

i downloaed the evernote sample app from the evernote site for Iphone sdk.i integrated it with my application,i can save note to evernote and import back ,but the only problem is login form missing.the username and password is stored statically in the sample app.i dont know how to authenticate this to dynamically.it is using singlton desing.
in.h
extern NSString * const username;
extern NSString * const password;
#interface evernoteloginpage : UIViewController {
.m
NSString * const username = #"nips55";
NSString * const password = #"annyan555";
#implementation evernoteloginpage
but i need it dynamically,i have two textfiled and a login button i need to add the textfiled values to username and password.i tried a lot but no luck.if anyone knows how to add a loginform for evernote ,please help me.
thanks in advance.
EDIT
now i sucessfully login with the help of this code,but again ther problem is if the login is sucess it will redirect to next page as shown in the code,if the user enter the wrong username or password,ithe app crashes.how to handele the rror mamangement in this code.
-(IBAction)_clickevernotelogin:(id)sender
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Keep this key private
NSString *consumerKey = [[[NSString alloc]
initWithString: #"app" ] autorelease];
[[NSUserDefaults standardUserDefaults] setObject:consumerKey forKey:#"consumerkeyevrnote"];
NSString *consumerSecret = [[[NSString alloc]
initWithString: #"12345678"] autorelease];
// For testing we use the sandbox server.
NSURL *userStoreUri = [[[NSURL alloc]
initWithString: #"https://www.evernote.com/edam/user"] autorelease];
NSString *noteStoreUriBase = [[[NSString alloc]
initWithString: #"https://www.evernote.com/edam/note/"] autorelease];
// These are for test purposes. At some point the user will provide his/her own.
NSString *username = [[[NSString alloc]
initWithString: _txtevernoteUsername.text] autorelease];
NSString *password = [[[NSString alloc]
initWithString: _txtevernotepasswrd.text] autorelease];
[[NSUserDefaults standardUserDefaults] setObject:_txtevernoteUsername.text forKey:#"usernameevernote"];
[[NSUserDefaults standardUserDefaults] setObject:_txtevernotepasswrd.text forKey:#"passwrdevernote"];
THTTPClient *userStoreHttpClient = [[[THTTPClient alloc]
initWithURL:userStoreUri] autorelease];
TBinaryProtocol *userStoreProtocol = [[[TBinaryProtocol alloc]
initWithTransport:userStoreHttpClient] autorelease];
EDAMUserStoreClient *userStore = [[[EDAMUserStoreClient alloc]
initWithProtocol:userStoreProtocol] autorelease];
EDAMNotebook* defaultNotebook = NULL;
BOOL versionOk = [userStore checkVersion:#"Cocoa EDAMTest" :
[EDAMUserStoreConstants EDAM_VERSION_MAJOR] :
[EDAMUserStoreConstants EDAM_VERSION_MINOR]];
if (versionOk == YES)
{
EDAMAuthenticationResult* authResult =
[userStore authenticate:username :password
:consumerKey :consumerSecret];
EDAMUser *user = [authResult user];
NSString *authToken = [authResult authenticationToken];
NSLog(#"Authentication was successful for: %#", [user username]);
NSLog(#"Authentication token: %#", authToken);
NSURL *noteStoreUri = [[[NSURL alloc]
initWithString:[NSString stringWithFormat:#"%#%#",
noteStoreUriBase, [user shardId]] ]autorelease];
[pool drain];
// this is next page if the login sucess
evernotemainpage *detailViewController = [[evernotemainpage alloc] initWithNibName:#"evernotemainpage" bundle:nil];
//detailViewController.firstString = firstString;
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}

Unfortunately, the Eevernote API currently does not contain any code samples for iOS. If you need information or an example on how to do this check out this article.
http://digitalpericope.net/?p=27

Related

Attach image to message composer in ios 6

How to attach an image to native message composer in ios6? I want to implement the same sharing via message function we can see in default photos app.
Thanks
For Mail:
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
NSData *exportData = UIImageJPEGRepresentation(pic ,1.0);
[mailController addAttachmentData:exportData mimeType:#"image/jpeg" fileName:#"Photo.jpeg"];
[self presentModalViewController:mailController animated:YES];
The only way is through email currently. Unless you want to create a own MMS gateway to allow your app to support MMS..
For Message:
After reading up, instead of using MFMessageComposeViewController,you could UIApplication sharedApplication.
Example:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.persistent = YES;
NSData *data = UIImageJPEGRepresentation(pic ,1.0);
pasteboard.image = [UIImage imageWithData:data];
NSString *phoneToCall = #"sms: 123-456-7890";
NSString *phoneToCallEncoded = [phoneToCall stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSURL *url = [[NSURL alloc] initWithString:phoneToCallEncoded];
[[UIApplication sharedApplication] openURL:url];
Longpress and click on Paste and message will be pasted...
Hope this helps... pic refers to the UIImage you are passing...
{
NSMutableDictionary * attachment = [[NSMutableDictionary alloc]init];
[attachment setObject: UIImageJPEGRepresentation(imageView.image,0.5) forKey:#"attachmentData"];
[attachment setObject: #"productImage.jpeg" forKey:#"attachmentFileName"];
[attachment setObject: #"jpeg" forKey:#"attachmentFileMimeType"];
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject: #"subject" forKey:#"subject"];
[params setObject: #"matterText" forKey:#"matterText"];
[params setObject: [[NSMutableArray alloc]initWithObjects:attachment, nil] forKey:#"attachments"];
}
#pragma mark - Sharing Via Email Related Methods
-(void)emailInfo:(NSMutableDictionary*)info
{
if (![MFMailComposeViewController canSendMail])
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Email Configuration"
message:#"We cannot send an email right now because your device's email account is not configured. Please configure an email account from your device's Settings, and try again."
delegate:nil
cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
MFMailComposeViewController *emailer = [[MFMailComposeViewController alloc] init];
emailer.mailComposeDelegate = self;
NSString * subject = [info objectForKey:#"subject"];
NSString * matterText = [info objectForKey:#"matterText"];
if(subject)
[emailer setSubject:subject];
if(matterText)
[emailer setMessageBody:matterText isHTML:NO];
NSMutableArray * attachments = [info objectForKey:#"attachments"];
if (attachments)
{
for (int i = 0 ; i < attachments.count ; i++)
{
NSMutableDictionary * attachment = [attachments objectAtIndex:i];
NSData * attachmentData = [attachment objectForKey:#"attachmentData"];
NSString * attachmentFileName = [attachment objectForKey:#"attachmentFileName"];
NSString * attachmentFileMimeType = [attachment objectForKey:#"attachmentFileMimeType"];
[emailer addAttachmentData:attachmentData mimeType:attachmentFileMimeType fileName:attachmentFileName];
}
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
emailer.modalPresentationStyle = UIModalPresentationPageSheet;
}
[self.navigationController.topViewController presentViewController:emailer animated:YES completion:nil];
}
I think you cant attach an image in the message composer. It is only possible in mail composer.

Passing coords of annotation Mapkit tapped

In my app, I have a set of location and their relative annotation. I have a button where cliking it, i go to a method that call a URL web service to get the google street view.
My code is:
- (NSString*)urlStreetview:(id<MKAnnotation>)annotation{
CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
NSLog(#"lat:%f",pinLocation.coordinate.latitude);
NSLog(#"lon:%f",pinLocation.coordinate.longitude);
NSString *lat_string = [[NSString alloc] initWithFormat:#"%f", pinLocation.coordinate.latitude];
NSString *lon_string = [[NSString alloc] initWithFormat:#"%f", pinLocation.coordinate.longitude];
NSString *url1 = [NSString stringWithFormat:#"http:myweb/streetview.php"];
NSString *url2 = [url1 stringByAppendingString: #"?lat="];
NSString *url3 = [url2 stringByAppendingString:lat_string];
NSString *url4 = [url3 stringByAppendingString:#"&lon="];
NSString *url = [url4 stringByAppendingString:lon_string];
NSLog(#"url:%#",url);
return url;
}
I wrote the previous method to have a url that is composed with the LatLong of the annotation.
I have a button called PressMe on the annotation pin. When I push it, I want to to excute the previous method, to calle the url, but I do not understand how pass the selected annotation to the streetView method.
- (IBAction)PressMe:(id)sender
{
UIViewController *webViewController = [[[UIViewController alloc] init] autorelease];
UIWebView *uiWebView = [[[UIWebView alloc] initWithFrame: CGRectMake(0,0,320,480)] autorelease];
[uiWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: [self urlStreetview: ????]]]]; //HERE IS MY MY PROBLEM
[webViewController.view addSubview: uiWebView];
webViewController.title = #"web bar";
[self.navigationController pushViewController:webViewController animated:YES];
//[[self navigationController] pushViewController:thirdViewController animated:YES];
}
thanks in advance!
I am going to answer my question myself. I just resolve my problem an it work perfectly. The code allows to show a web view in order to have a steet View google service of the annotation map Kit annotation. Obviusly, as I am relatively new iphone developer,if someone wants to add/suggest/improve, he is welcome.
My button implementation:
- (IBAction)PressMe:(id)sender
{
UIViewController *webViewController = [[[UIViewController alloc] init] autorelease];
UIWebView *uiWebView = [[[UIWebView alloc] initWithFrame: CGRectMake(0,0,320,480)] autorelease];
[uiWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: self.urlStreetview]]];
[webViewController.view addSubview: uiWebView];
webViewController.title = #"web bar";
[self.navigationController pushViewController:webViewController animated:YES];
//[[self navigationController] pushViewController:thirdViewController animated:YES];
}
With this button I call my (following) method "urlStreetview" the, with the annotation selected, composes a string in order to have a complet url with the apropriete GET php parameter. The url is the direction of my (very simple) web service that allow to call the google API street View.
- (NSString*)urlStreetview{
//there can only be one selected annotation so get the one at index 0
id<MKAnnotation> selectedAnnotation = [_mapView.selectedAnnotations objectAtIndex:0];
CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:selectedAnnotation.coordinate.latitude longitude:selectedAnnotation.coordinate.longitude];
//Now I have the annotation coordinate selected, so now I am able to compound the urladdingo to my base url:http://myurl/streetview.php, the GET part, I mean the lat lon coords:
NSString *lat_string = [[NSString alloc] initWithFormat:#"%f", pinLocation.coordinate.latitude];
NSString *lon_string = [[NSString alloc] initWithFormat:#"%f", pinLocation.coordinate.longitude];
NSString *url1 = [NSString stringWithFormat:#"http://myurl/streetview.php"];
NSString *url2 = [url1 stringByAppendingString: #"?lat="];
NSString *url3 = [url2 stringByAppendingString:lat_string];
NSString *url4 = [url3 stringByAppendingString:#"&lon="];
NSString *url = [url4 stringByAppendingString:lon_string];
NSLog(#"url:%#",url);
return url;
}
I hope It can be useful!

NSUserDefault doesn't works

i am developing an app which has a evernote integration,everything works perfect but my problem is ,if i login with my account and uplode or downlode note to my aPP,then i logout from the evernote and login as a another user,it stills downlod and uplode note to previous account,,but login is sucess.
i put NsuserDefault for username and password textfileds and syncoronize it and pass it in evernote singlton shared class.my login looks like this
-(IBAction)_clickevernotelogin:(id)sender
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Keep this key private
NSString *consumerKey = [[[NSString alloc]
initWithString: #"myapp" ] autorelease];
[[NSUserDefaults standardUserDefaults] setObject:consumerKey forKey:#"consumerkeyevrnote"];
NSString *consumerSecret = [[[NSString alloc]
initWithString: #"agft5623636"] autorelease];
NSURL *userStoreUri = [[[NSURL alloc]
initWithString: #"https://www.evernote.com/edam/user"] autorelease];
NSString *noteStoreUriBase = [[[NSString alloc]
initWithString: #"https://www.evernote.com/edam/note/"] autorelease];
// These are for test purposes. At some point the user will provide his/her own.
NSString *username = [[[NSString alloc]
initWithString: _txtevernoteUsername.text] autorelease];
NSString *password = [[[NSString alloc]
initWithString: _txtevernotepasswrd.text] autorelease];
[[NSUserDefaults standardUserDefaults] setObject:_txtevernoteUsername.text forKey:#"usernameever"];
[[NSUserDefaults standardUserDefaults] setObject:_txtevernotepasswrd.text forKey:#"passwrdevernote"];
[[NSUserDefaults standardUserDefaults]synchronize];
THTTPClient *userStoreHttpClient = [[[THTTPClient alloc]
initWithURL:userStoreUri] autorelease];
TBinaryProtocol *userStoreProtocol = [[[TBinaryProtocol alloc]
initWithTransport:userStoreHttpClient] autorelease];
EDAMUserStoreClient *userStore = [[[EDAMUserStoreClient alloc]
initWithProtocol:userStoreProtocol] autorelease];
EDAMNotebook* defaultNotebook = NULL;
BOOL versionOk = [userStore checkVersion:#"Cocoa EDAMTest" :
[EDAMUserStoreConstants EDAM_VERSION_MAJOR] :
[EDAMUserStoreConstants EDAM_VERSION_MINOR]];
if (versionOk == YES)
{
#try {
NSError *error = nil;
NSString *unameever = _txtevernoteUsername.text;
NSString *pwdever = _txtevernotepasswrd.text;
[[NSUserDefaults standardUserDefaults] setObject:unameever forKey:#"usernameever"];
BOOL flag = [SFHFKeychainUtils storeUsername:unameever andPassword:pwdever forServiceName:#"mybibleappever" updateExisting:TRUE error:&error];
EDAMAuthenticationResult* authResult =
[userStore authenticate:username :password
:consumerKey :consumerSecret];
EDAMUser *user = [authResult user];
NSString *authToken = [authResult authenticationToken];
NSLog(#"Authentication was successful for: %#", [user username]);
NSLog(#"Authentication token: %#", authToken);
[[NSUserDefaults standardUserDefaults] setObject:authToken forKey:#"usernameevernotetocken"];
[[NSUserDefaults standardUserDefaults] setObject:[user username] forKey:#"usernameevernoteshow"];
NSURL *noteStoreUri = [[[NSURL alloc]
initWithString:[NSString stringWithFormat:#"%#%#",
noteStoreUriBase, [user shardId]] ]autorelease];
}
#catch (EDAMUserException * e) {
NSString * errorMessage = [NSString stringWithFormat:#"Please enter valid username & password", [e errorCode]];
UIAlertView *alertDone = [[UIAlertView alloc] initWithTitle: #"Evernote" message: errorMessage delegate: self cancelButtonTitle: #"Ok" otherButtonTitles: nil];
_acteverloginimage.hidden = YES;
_acteverlogin.hidden =YES;
[alertDone show];
[alertDone release];
return;
}
[pool drain];
}
my logout looks like this
[_btnusernameshow setTitle:nil forState:UIControlStateNormal];
NSError *error = nil;
NSString *usernameever = [[NSUserDefaults standardUserDefaults] objectForKey:#"usernameever"];
BOOL flag = [SFHFKeychainUtils deleteItemForUsername:usernameever andServiceName:#"mybibleappever" error:&error];
[[NSUserDefaults standardUserDefaults ]removeObjectForKey:#"usernameevernote"];
[[NSUserDefaults standardUserDefaults ]removeObjectForKey:#"passwrdevernote"];
[[NSUserDefaults standardUserDefaults ]removeObjectForKey:#"usernameevernotetocken"];
[[NSUserDefaults standardUserDefaults ]removeObjectForKey:#"usernameever"];
my evernote singlton class which share the instance look like this
here i am passing the nsuerdefault value to change the authentication information to this class
- (void) connect {
if (authToken == nil)
{
// In the case we are not connected we don't have an authToken
// Instantiate the Thrift objects
NSURL * NSURLuserStoreUri = [[[NSURL alloc] initWithString: userStoreUri] autorelease];
THTTPClient *userStoreHttpClient = [[[THTTPClient alloc] initWithURL: NSURLuserStoreUri] autorelease];
TBinaryProtocol *userStoreProtocol = [[[TBinaryProtocol alloc] initWithTransport:userStoreHttpClient] autorelease];
EDAMUserStoreClient *userStore = [[[EDAMUserStoreClient alloc] initWithProtocol:userStoreProtocol] autorelease];
// Check that we can talk to the server
bool versionOk = [userStore checkVersion: applicationName :[EDAMUserStoreConstants EDAM_VERSION_MAJOR] : [EDAMUserStoreConstants EDAM_VERSION_MINOR]];
if (!versionOk) {
// Alerting the user that the note was created
UIAlertView *alertDone = [[UIAlertView alloc] initWithTitle: #"Evernote" message: #"Incompatible EDAM client protocol version" delegate: self cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alertDone show];
[alertDone release];
return;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(evrloginnotif:) name:#"evrloginnotiff" object:nil];
//Checks if there is a saved User Name
NSError *error = nil;
if([defaults objectForKey:#"usernameever"]&&[defaults objectForKey:#"passwrdevernote"])
{
username = [defaults objectForKey:#"usernameever"];
password = [defaults objectForKey:#"passwrdevernote"];
//BOOL flag = [SFHFKeychainUtils storeUsername:username andPassword:password forServiceName:#"mybibleappever" updateExisting:TRUE error:&error];
// Returned result from the Evernote servers after authentication
EDAMAuthenticationResult* authResult =[userStore authenticate:username :password : consumerKey :consumerSecret];
// User object describing the account
self.user = [authResult user];
// We are going to save the authentication token
self.authToken = [authResult authenticationToken];
// and the shard id
self.shardId = [user shardId];
// Creating the user's noteStore's URL
noteStoreUri = [[[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#%#", noteStoreUriBase, shardId] ] autorelease];
// Creating the User-Agent
UIDevice *device = [UIDevice currentDevice];
NSString * userAgent = [NSString stringWithFormat:#"%#/%#;%#(%#)/%#", applicationName,applicationVersion, [device systemName], [device model], [device systemVersion]];
// Initializing the NoteStore client
THTTPClient *noteStoreHttpClient = [[[THTTPClient alloc] initWithURL:noteStoreUri userAgent: userAgent timeout:15000] autorelease];
TBinaryProtocol *noteStoreProtocol = [[[TBinaryProtocol alloc] initWithTransport:noteStoreHttpClient] autorelease];
noteStore = [[[EDAMNoteStoreClient alloc] initWithProtocol:noteStoreProtocol] retain];
}
}
}
how to solve this bug,,thanks
EDIT
but when i rebuild the app,i am getting the correct notes from the username
NSUserDefaults *Test = [NSUserDefaults standardUserDefaults];
[Test removeObjectForKey:#"usernameevernote"];
[Test removeObjectForKey:#"passwrdevernote"];
[Test removeObjectForKey:#"usernameevernotetocken"];
[Test removeObjectForKey:#"usernameever"];
[Test synchronize];
maybe you should have remove objects and synchronize it again so it will remove all objects.
Add "[[NSUserDefaults standardUserDefaults] synchronize];" line everywhere you set value or remove key from NSUserDefault.
May be synchronization is the problem.

How to show/hide UIImageView when I want

I'm having a little problem with an iPhone app I'm currently developing.
When the user touch a button, it calls an IBAction named refreshQuestion, which is supposed to show an image hover the screen to ask the user to wait a moment, then it has to call another function, and finally it has to hide the image.
The problem is that the image won't appear. As well as the network activity indicator.
Any help?
Here is the code :
- (IBAction)refreshQuestion:(id)sender{
pleaseWait.hidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self loadData];
pleaseWait.hidden = YES;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
EDIT :
Here is my LoadData function :
- (void)loadData{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString * idUtilisateur = [userDefaults objectForKey:#"idUtilisateur"];
NSString * stringUrlQuestion = [NSString stringWithFormat:#"http://www.mywebsiteURL"];
NSURL * urlQuestion = [NSURL URLWithString:stringUrlQuestion];
QuestionParser * parser = [[QuestionParser alloc] init];
[parser parseXMLAtURL:urlQuestion parseError:nil] ;
int nbQuestions = [parser.arrayOfQuestion count];
[parser release];
NSFetchRequest *requete = [[NSFetchRequest alloc] init];
NSEntityDescription *entite = [NSEntityDescription entityForName:#"Question" inManagedObjectContext:self.managedObjectContext];
[requete setEntity:entite];
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"idQuestion" ascending:YES];
NSArray * sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[requete setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
NSError * error;
NSMutableArray *mutableFetchResult = [[self.managedObjectContext executeFetchRequest:requete error:&error] mutableCopy];
[requete release];
if(mutableFetchResult == nil){
NSLog(#"Erreur viewWillAppear : %#", error);
}
questionDuJour = [mutableFetchResult objectAtIndex:0];
if (nbQuestions == 0){
UIAlertView* alertViewConnection = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Error while retreiving data" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertViewConnection show];
[alertViewConnection release];
}
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:#"EEEE d MMMM"];
NSLocale * localisation = [[[NSLocale alloc] initWithLocaleIdentifier:#"fr_FR"] autorelease];
[outputFormatter setLocale:localisation];
labelJour.text = [NSString stringWithFormat:#"%#",[outputFormatter stringFromDate:questionDuJour.dateQuestion]];
textQuestion.text = questionDuJour.textQuestion;
citation.text = [NSString stringWithFormat:#"%#",questionDuJour.citation];
labelAuteur.text = [NSString stringWithFormat:#"%#",questionDuJour.auteur];
[outputFormatter release];
NSLog(#"stop animating");
}
I think your code [self loadData] executes in microseconds.
Check by using this code alone,
pleaseWait.hidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
EDIT:
Check this, if you still get the same problem check whether you have assigned IBoutlet or not. Because what you are doing is the correct way.
Sounds like everything is executing on the UI Thread. Post your loadData method so we can see what its doing. Chances are you have to convert this method to use one of the asynchronous techniques which will return immediately and allow the UI thread to continue. You can then detect when its done loading the data and change the visibility of the image again.

Get Twitter oauth key in similar way to Facebook oauth key

I have an iPhone app which currently loads up a UIWebView using the facebook graph api oauth url (https://graph.facebook.com/oauth/authorize?...) - a user then enters their login details, and on submitting I retrieve the the access token from the URL. (In a manner as this I believe http://www.capturetheconversation.com/technology/iphone-facebook-oauth2-graph-api) This is then passed to my java server which performs the various actions using RestFB
My question is, is there a similar way to do this with Twitter? Currently it seems the only way to get the data is to download a library and use that; yet this is an approach I would rather not use as it would take up unnecessary space seeing as all the commands will actually be run from my Java server.
Any advice would be greatly appreciated
Thanks,
Dan
Twitter uses OAuth 1.0a authentication, but not OAuth 2.0.
Steps to get an access token on Twitter:
Create your own application on Twitter and get consumer key and secret.
Download open source OAuth library, OAuthConsumer in my case.
Write registration code, see example below.
p.s. Set application type as web application, it turns on callback instead of PIN code.
static NSString* kMyApplicationConsumerKey = #"XXXXXXXXXXX";
static NSString* kMyApplicationConsumerSecret = #"XXXXXXXXXXX";
#interface TwitterConnector : NSObject {
OAConsumer* consumer;
OAToken* requestToken;
OAToken* accessToken;
}
- (void)start;
#end
#implementation TwitterConnector
- (void)start {
consumer = [[OAConsumer alloc] initWithKey:kMyApplicationConsumerKey secret:kMyApplicationConsumerSecret];
NSURL* requestTokenUrl = [NSURL URLWithString:#"http://api.twitter.com/oauth/request_token"];
OAMutableURLRequest* requestTokenRequest = [[[OAMutableURLRequest alloc] initWithURL:requestTokenUrl
consumer:consumer
token:nil
realm:nil
signatureProvider:nil] autorelease];
OARequestParameter* callbackParam = [[[OARequestParameter alloc] initWithName:#"oauth_callback" value:#"twitter://authorized"] autorelease];
[requestTokenRequest setHTTPMethod:#"POST"];
[requestTokenRequest setParameters:[NSArray arrayWithObject:callbackParam]];
OADataFetcher* dataFetcher = [[[OADataFetcher alloc] init] autorelease];
[dataFetcher fetchDataWithRequest:requestTokenRequest
delegate:self
didFinishSelector:#selector(didReceiveRequestToken:data:)
didFailSelector:#selector(didFailOAuth:error:)];
}
- (void)didReceiveRequestToken:(OAServiceTicket*)ticket data:(NSData*)data {
NSString* httpBody = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
requestToken = [[OAToken alloc] initWithHTTPResponseBody:httpBody];
NSURL* authorizeUrl = [NSURL URLWithString:#"https://api.twitter.com/oauth/authorize"];
OAMutableURLRequest* authorizeRequest = [[[OAMutableURLRequest alloc] initWithURL:authorizeUrl
consumer:nil
token:nil
realm:nil
signatureProvider:nil] autorelease];
NSString* oauthToken = requestToken.key;
OARequestParameter* oauthTokenParam = [[[OARequestParameter alloc] initWithName:#"oauth_token" value:oauthToken] autorelease];
[authorizeRequest setParameters:[NSArray arrayWithObject:oauthTokenParam]];
UIWebView* webView = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[[[UIApplication sharedApplication] keyWindow] addSubview:webView];
[webView release];
webView.delegate = self;
[webView loadRequest:authorizeRequest];
}
- (void)didReceiveAccessToken:(OAServiceTicket*)ticket data:(NSData*)data {
NSString* httpBody = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
accessToken = [[OAToken alloc] initWithHTTPResponseBody:httpBody];
// FINISHED!
}
- (void)didFailOAuth:(OAServiceTicket*)ticket error:(NSError*)error {
// ERROR!
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] scheme] isEqualToString:#"twitter"]) {
// Extract oauth_verifier from URL query
NSString* verifier = nil;
NSArray* urlParams = [[[request URL] query] componentsSeparatedByString:#"&"];
for (NSString* param in urlParams) {
NSArray* keyValue = [param componentsSeparatedByString:#"="];
NSString* key = [keyValue objectAtIndex:0];
if ([key isEqualToString:#"oauth_verifier"]) {
verifier = [keyValue objectAtIndex:1];
break;
}
}
if (verifier) {
NSURL* accessTokenUrl = [NSURL URLWithString:#"https://api.twitter.com/oauth/access_token"];
OAMutableURLRequest* accessTokenRequest = [[[OAMutableURLRequest alloc] initWithURL:accessTokenUrl
consumer:consumer
token:requestToken
realm:nil
signatureProvider:nil] autorelease];
OARequestParameter* verifierParam = [[[OARequestParameter alloc] initWithName:#"oauth_verifier" value:verifier] autorelease];
[accessTokenRequest setHTTPMethod:#"POST"];
[accessTokenRequest setParameters:[NSArray arrayWithObject:verifierParam]];
OADataFetcher* dataFetcher = [[[OADataFetcher alloc] init] autorelease];
[dataFetcher fetchDataWithRequest:accessTokenRequest
delegate:self
didFinishSelector:#selector(didReceiveAccessToken:data:)
didFailSelector:#selector(didFailOAuth:error:)];
} else {
// ERROR!
}
[webView removeFromSuperview];
return NO;
}
return YES;
}
- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
// ERROR!
}
#end