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
Related
this is my viewDidLoad function working well :
- (void)viewDidLoad
{
[super viewDidLoad];
//iAds code
adview = [[ADBannerView alloc] initWithFrame:CGRectZero];
adview.frame = CGRectOffset(adview.frame, 0, 0);
adview.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adview.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[self.view addSubview:adview];
adview.delegate = self;
self.adbanerinvesiable = NO;
//php data code
NSError *er;
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost:8888/newjson.php?number=1"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (response.length != 0){
NSString *json_string = [[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding];
listt = [parser objectWithString:json_string error:&er];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No Internet conniction" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"Refresh", nil];
[alert show];
//for ID contet post
SBJsonParser *parser2 = [[SBJsonParser alloc] init];
NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost:8888/newjson.php?number=2"]];
NSData *response2 = [NSURLConnection sendSynchronousRequest:request2 returningResponse:nil error:nil];
NSString *json_string2 = [[NSString alloc]initWithData:response2 encoding:NSUTF8StringEncoding];
IDNum = [parser2 objectWithString:json_string2 error:&er];
}
}
As you can see if the connection failed it will show UIAlertView and two Buttons {ok , Refresh}.
I used this Method in case the refresh button been clicked to call viewDidLoad But not Working and giving me blank white view:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1){
[self viewDidLoad];
}
}
Any idea please ?
You should put your PHP Data Code in a method in it's own, so when you need to call that specifically you can, because you can't (or should I say shouldn't) call viewDidLoad manually. That should only be called automatically by UIViewController.
Example
- (void)viewDidLoad
{
[super viewDidLoad];
//iAds code
adview = [[ADBannerView alloc] initWithFrame:CGRectZero];
adview.frame = CGRectOffset(adview.frame, 0, 0);
adview.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adview.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[self.view addSubview:adview];
adview.delegate = self;
self.adbanerinvesiable = NO;
}
-(void)viewWillAppear:(BOOL)animated /* or: -(void)viewDidAppear: */
{
[super viewWillAppear:animtaed];
[self refreshPHData];
}
-(void)refreshPHPData
{
//php data code
NSError *er;
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost:8888/newjson.php?number=1"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (response.length != 0){
NSString *json_string = [[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding];
listt = [parser objectWithString:json_string error:&er];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No Internet conniction" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"Refresh", nil];
[alert show];
//for ID contet post
SBJsonParser *parser2 = [[SBJsonParser alloc] init];
NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost:8888/newjson.php?number=2"]];
NSData *response2 = [NSURLConnection sendSynchronousRequest:request2 returningResponse:nil error:nil];
NSString *json_string2 = [[NSString alloc]initWithData:response2 encoding:NSUTF8StringEncoding];
IDNum = [parser2 objectWithString:json_string2 error:&er];
}
}
Also, when you call viewDidLoad from your UIAlertView, you are creating a second (and third and so forth) adview because you aren't removing the previous instance. Depending on how many times the alert is shown and viewDidLoad is called, you are going to see adview stacking on top of itself. So try instead:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1){
[self refreshPHPData];
}
}
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!
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
I am trying to initiate a call from my iphone app,and I did it the following way..
-(IBAction) call:(id)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Call Besito" message:#"\n\n\n"
delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Submit", nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
NSString *phone_number = #"0911234567"; // assing dynamically from your code
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", phone_number]]];
NSString *phone_number = #"09008934848";
NSString *phoneStr = [[NSString alloc] initWithFormat:#"tel:%#",phone_number];
NSURL *phoneURL = [[NSURL alloc] initWithString:phoneStr];
[[UIApplication sharedApplication] openURL:phoneURL];
[phoneURL release];
[phoneStr release];
}
}
by the above code..I am able to successfully make a call..but when I end a call,I'm not able to return to my app
So, I want to know how to achieve,that..also please tell me how we can initiate a call using webview...
This is my code :
NSURL *url = [NSURL URLWithString:#"telprompt://123-4567-890"];
[[UIApplication sharedApplication] openURL:url];
Use this so that after call end it will return to app.
UIWebView *callWebview = [[UIWebView alloc] init];
NSURL *telURL = [NSURL URLWithString:#"tel:+9196815*****"];
[callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
Please try this it will definitely let you Back to Your App.
NSString *phoneNumber = // dynamically assigned
NSString *phoneURLString = [NSString stringWithFormat:#"tel:%#", phoneNumber];
NSURL *phoneURL = [NSURL URLWithString:phoneURLString];
[[UIApplication sharedApplication] openURL:phoneURL];
following code will not return to your app [no alertview will show before make call]
UIWebView *callWebview = [[UIWebView alloc] init];
NSURL *telURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel://%#",phoneNumber]];
[callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
following code will return to your app "alertview will show before make call"
UIWebView *callWebview = [[UIWebView alloc] init];
NSURL *telURL = [NSURL URLWithString:[NSString stringWithFormat:#"telprompt://%#", phoneNumber]];
[callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
You can also use webview, this is my code :
NSURL *url = [NSURL URLWithString:#"tel://123-4567-890"];
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 150, 100)];
[self.view addSubview:btn];
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(50, 50, 150, 100)];
webview.alpha = 0.0;
[webview loadRequest:[NSURLRequest requestWithURL:url]];
// Assume we are in a view controller and have access to self.view
[self.view insertSubview:webview belowSubview:btn];
[webview release];
[btn release];
It's not possible to return back to the app after ending a call because it's an app.
How to integrate Bing Maps into iPhone Application?
I am doing using VirtualEarthKit framework [website appears to host malware].
My code is as below :
I am getting error while getting token.
{
VECommonService *commonService = [[VECommonService alloc] init];
NSString *token;
printf("2\n");
NSError *error=[commonService getToken:&token forUserID:#"abc" password:#"def" ipAddress:#"123"];
NSString *errMsg= [error description];
printf("\n%s\n",[errMsg UTF8String]);
printf("3\n");
VEGeocodeService *geocodeService = [[VEGeocodeService alloc] init];
VEGeocodeRequest *geocodeRequest = [[VEGeocodeRequest alloc] init];
printf("4\n");
geocodeRequest.query = #"Portland State University";
geocodeRequest.token = token;
printf("5\n");
VEServiceResponse *geocodeResponse = [geocodeService geocode:geocodeRequest];
VEGeocodeResult *geocodeResult = [geocodeResponse.results objectAtIndex:0];
//NSLog([geocodeResult.location description]);
//NSLog([geocodeResult.address description]);
VEImageryService *imageryService = [[VEImageryService alloc] init];
VEGetMapURIRequest *mapRequest = [[VEGetMapURIRequest alloc] init];
mapRequest.center = geocodeResult.location;
mapRequest.token = token;
VEGetMapURIResponse *mapResponse = [imageryService getMapURI:mapRequest];
NSURL *url = mapResponse.mapURL;
//printf("\n\n URL==> %s",[url relativeString]);
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
[self.view addSubview:webView];
}
is there any way to use bing maps in an iPhone app?