I have an iOS Application which authenticates with the Google Plus API via OAuth 2.0. The issue I have is that I can't POST my moment even though I have followed the Google Documentation exactly. Here is my POST request:
NSString *gp_moment = [NSString stringWithFormat:#"https://www.googleapis.com/plus/v1/people/me/moments/vault?access_token=%#", token_gplus];
NSString *urlString = gp_moment;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
// Set the header - Content-Type.
NSDictionary *the_header = #{#"Content-type" : #"application/json",
#"userId" : #"me",
#"collection" : #"vault",
#"requestvisibleactions" : #"http://schemas.google.com/AddActivity"};
[request setAllHTTPHeaderFields:the_header];
// Set the metadata for the GP Moment (eg: name). - request_visible_actions
NSDictionary *metadata = #{#"target" : #{
#"id" : #"replacewithuniqueidforaddtarget",
#"image" : #"http://www.google.com/s2/static/images/GoogleyEyes.png",
#"type": #"http://schema.org/CreativeWork",
#"description" : #"test_desc",
#"name" : #"TESTNAME",
},
#"type" : #"http://schemas.google.com/AddActivity"};
// Convert metadata into JSON format and submit.
NSError *jError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:metadata options:NSJSONWritingPrettyPrinted error:&jError];
[request setHTTPBody:jsonData];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *returnedData;
returnedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSDictionary *headers = [response allHeaderFields];
NSLog(#"DATA: %#", [[NSString alloc] initWithData:returnedData encoding:NSASCIIStringEncoding]);
NSLog(#"%#", headers);
NSLog(#"%#", response);
NSLog(#"%#", error);
UPDATE - HOW I AM GETTING THE OAUTH TOKEN
I am getting the token by using the GTMOAuth2 iOS library provided by Google. It has 4 main classes which I am using:
This is the code I have implemented from the classes into my ViewController:
-(GTMOAuth2Authentication *)begin_authorization {
// Set the token URL to the token endpoint.
NSURL *tokenURL;
// Set a bogus redirect URI. It won't actually be used as the redirect will
// be intercepted by the OAuth library and handled in the app.
NSString *redirectURI;
GTMOAuth2Authentication *auth;
tokenURL = [NSURL URLWithString:#"https://accounts.google.com/o/oauth2/token"];
redirectURI = #"http://localhost:3000/oauth/callback/";
auth = [GTMOAuth2Authentication authenticationWithServiceProvider:#"GooglePlus" tokenURL:tokenURL redirectURI:redirectURI clientID:kMyClientID_gplus clientSecret:kMyClientSecret_gplus];
[auth setScope:#"https://www.googleapis.com/auth/plus.login"];
// Set the appropriate token type.
[auth setTokenType:#"Bearer"];
return auth;
}
-(void)authorize:(NSString *)service {
GTMOAuth2Authentication *auth = [self begin_authorization];
// Prepare the Authorization URL. We will pass in the name of the service
// that we wish to authorize with.
NSURL *authURL;
authURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth/"]];
NSString *keyname;
keyname = [NSString stringWithFormat:#"GooglePlus"];
// Display the authentication view
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithAuthentication:auth authorizationURL:authURL keychainItemName:keyname delegate:self finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[viewController setBrowserCookiesURL:[NSURL URLWithString:#"https://accounts.google.com/o/oauth2/auth/"]];
// Push the authentication view to our navigation controller instance
[[self navigationController] pushViewController:viewController animated:YES];
}
-(void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error {
if (error != nil) {
// Authentication failed
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Authorization Failed" message:[error localizedDescription] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alertView show];
}
else {
// Authentication succeeded
// Assign the access token to the instance property for later use
account_check = auth.accessToken;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:account_check forKey:#"gp_token"];
[defaults synchronize];
}
}
In the GTMOAuth2SignIn.m file I am also setting the offline_access and "requestvisisbleactions" parameters like so:
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"code", #"response_type",
clientID, #"client_id",
scope, #"scope", // scope may be nil
#"force", #"approval_prompt",
#"offline", #"access_type",
#"http://schemas.google.com/AddActivity", #"requestvisibleactions",
nil];
UPDATE - 2
I have tried looking through all the Google Plus documentation as well as looking through the differences between "requestvisisbleactions" and "request_visisble_actions" and still nothing works. Does anyone know what is wrong?
UPDATE - 3 - The error I am still getting
I keep on getting this error from Google Plus API. I just don't know why...:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "unauthorized",
"message": "Unauthorized"
}
],
"code": 401,
"message": "Unauthorized"
}
}
I believe that you need to use request_visible_actions. So your parameters might be set as
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"code", #"response_type",
clientID, #"client_id",
scope, #"scope", // scope may be nil
#"force", #"approval_prompt",
#"offline", #"access_type",
#"http://schemas.google.com/AddActivity", #"request_visible_actions",
nil];
Related
I have created one Custom type Frame work, and that frame work i added in to my app, in that custom frame work i added simple method, that will return the normal string, But my question is i want to use that framework as a API calls like login and registration and all, i used NSJSONSERIALIZATION for fetch data from json, it will return the values, but i want to use that data in my app, can any one tell me , i am very new in custom type Frameworks and all;
-(void )JsonData :(NSDictionary *)dictionary method:(NSString *)method url:(NSString *)url {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:method];
NSLog(#"apiCall RequestUrl: %#, HTTPMethod: %#, RequestData: %#", request.URL.absoluteString, method, dictionary);
if ([method isEqualToString:#"POST"] || [method isEqualToString:#"PUT"])
{
NSData *dataToSend = [NSJSONSerialization dataWithJSONObject:(NSDictionary *)dictionary options:0 error:nil];
[request setHTTPBody:dataToSend];
}
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue new] completionHandler:^(NSURLResponse *response, NSData *data, NSError *responseError)
{
NSDictionary *responseData;
if (responseError)
{
responseData = [NSDictionary dictionaryWithObjectsAndKeys:
#"Error", #"status",
responseError.localizedDescription, #"message",
nil];
}
else if ([(NSHTTPURLResponse *)response statusCode] != 200)
{
responseData = [NSDictionary dictionaryWithObjectsAndKeys:
#"Error", #"status",
#"Invalid Response from server.", #"message",
nil];
}
else if ([[Response getCustomStatus:(NSHTTPURLResponse *)response] isEqualToString:#"invalid_session"])
{
responseData = [NSDictionary dictionaryWithObjectsAndKeys:
#"Error", #"status",
#"Your session has been expired.", #"message",
nil];
}
else
{
responseData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&responseError];
}
NSLog(#"apiCall ResponseData: %#", responseData);
CustomerInfo *customer = [[CustomerInfo alloc]init];
customer.session = [[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"session"];
NSLog(#"JsonData:%#",[[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"session"]);
NSLog(#"Data:%#",customer.session);
customer.groupID = [[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"group_id"];
NSLog(#"%#",[[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"group_id"]);
NSLog(#"Data:%#", customer.groupID );
customer.cutomerID = [[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"customer_id"];
NSLog(#"%#",[[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"customer_id"]);
NSLog(#"Data:%#", customer.cutomerID );
customer.stylistProfilepicUrl = [[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"stylist_profile_url"];
NSLog(#"%#",[[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"stylist_profile_url"]);
NSLog(#"Data:%#", customer.stylistProfilepicUrl);
customer.fbUserID = [[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"fb_user_id"];
NSLog(#"%#",[[[responseData objectForKey:#"data"]objectAtIndex:0]objectForKey:#"fb_user_id"]);
NSLog(#"Data:%#", customer.fbUserID );
}];
}
This is my Frame Work code,
in my app i jsut call this code and send the parameters,
i got the response,but while i am printing the data, it showing null values in my app,
Can any one suggest me or send me any link or tutorial
If you are getting valid data, then log
NSLog(#"apiCall ResponseData: %#", responseData.description);
Check and try to print any error.description probably in the last else part
I already successfully integrated Google+ to my iOS app. But with the latest Apple store updates, the app is not allowed to open the browser to initiate the Google authentication using safari so i tried uiwebview for googleplus authentication and i am getting the access token but i cannot able to get the username and email address of the person logged in.Below i added my source,
NSString *client_id = #"***************************";;
NSString *secret = #"*******************************";
NSString *callbakc = #"https://www.example.com/oauth2callback";;
NSString *scope = #"https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile+https://www.google.com/reader/api/0/subscription";
NSString *visibleactions = #"http://schemas.google.com/AddActivity";
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize webview,isLogin,isReader;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%#&redirect_uri=%#&scope=%#&data-requestvisibleactions=%#",client_id,callbakc,scope,visibleactions];
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
// [indicator startAnimating];
NSLog(#"dgfduiussdiff %# ",[[request URL] host]);
if ([[[request URL] host] isEqualToString:#"www.example.com"]) {
// 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:#"code"]) {
verifier = [keyValue objectAtIndex:1];
NSLog(#"verifier %#",verifier);
break;
}
}
if (verifier) {
NSString *data = [NSString stringWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&grant_type=authorization_code", verifier,client_id,secret,callbakc];
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/token"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
receivedData = [[NSMutableData alloc] init];
} else {
// ERROR!
}
[webView removeFromSuperview];
return NO;
}
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSError* error;
[receivedData appendData:data];
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:receivedData
options:kNilOptions
error:&error];
NSLog(#"verifier %#",json);
}
- (void)connection:(NSURLConnection *)connection didFailWithError: (NSError *)error{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"%#", error]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *response = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
SBJsonParser *jResponse = [[SBJsonParser alloc]init];
NSDictionary *tokenData = [jResponse objectWithString:response];
// WebServiceSocket *dconnection = [[WebServiceSocket alloc] init];
// dconnection.delegate = self;
NSString *pdata = [NSString stringWithFormat:#"type=3&token=%#&secret=123&login=%#", [tokenData objectForKey:#"refresh_token"], self.isLogin];
// NSString *pdata = [NSString stringWithFormat:#"type=3&token=%#&secret=123&login=%#",[tokenData accessToken.secret,self.isLogin];
// [dconnection fetch:1 withPostdata:pdata withGetData:#"" isSilent:NO];
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Google Access TOken"
message:pdata
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
After executing the above source i getting the below response printed in nslog,
verifier 4/kMcSZ2l-d_XXPo24NSdsMnugoP_MGDGPP4D5C1LRTfY
2015-07-21 18:04:16.103 TechnoGerms.com[8981:189233] verifier {
"access_token" = "ya29.twG9kyMElyC8BgAxujF98WKN0BQ246Ey6zsKQEgSpKsNEb5JOS3QRl12La6XBy1geZnL";
"expires_in" = 3600;
"id_token" = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRhNjYyNWIzNmJjMDlkMzAwMzUzYjI4YTc0MWNlMTc1MjVhNGMzM2IifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTE0MjE4NDEwODI0NzM1ODkyMDg0IiwiYXpwIjoiMTY5NzY2MjI4OTY4LWtoNzI1dTFpZWdzNHN1bnFhOThhcHUxMHU4djhhcmFmLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJhcmp1bkBsaW5rd2FyZS5pbiIsImF0X2hhc2giOiJQVnJxTURpNDViZnVGTm9kTmlsSFlRIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1ZCI6IjE2OTc2NjIyODk2OC1raDcyNXUxaWVnczRzdW5xYTk4YXB1MTB1OHY4YXJhZi5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImhkIjoibGlua3dhcmUuaW4iLCJpYXQiOjE0Mzc0ODIwNTUsImV4cCI6MTQzNzQ4NTY1NX0.uSMrV8rOz4T4i5MhiCeQueNVGLv4NBLP-gtOcyow8t4BY9qvUO78sG4y0jPhbclPdX1kUZjzMVTeah2nU9fTYyl50dlj5FzWNy7LyM-a1GC2jEwkgWMgHdRPh6l7dqMrjQ9sU1rF-ZaiWfG7C9VJTJ76uEWRiSKKA9EFQtBil3xBtmDH07UMRxkbri2jBwaCPAWgjU8-dTarrxNESrwrO_nptaRzfGeaTyQBIYCAk6_9deXmblPgteER1OHoa65xb1OVK3ZPeZ3_dj9gjlXSyGp2ho5WIFGf2xRvW4XoROpUYqhLvrS3s-YrrZ8J5X5-3mafrs1qDjJYJogctbW7dg";
"token_type" = Bearer;
}
How i can get the username and email of person logged in by using the access token which i got above ? Please give any suggestions as i dont get any solution on google.
Thanks for your support
if you want to fetch the whole profile of the google+ user, you can use the below URL
https://www.googleapis.com/plus/v1/people/me/?access_token={YOUR_ACCESS_TOKEN}
Then call the GET method. You will be given by an array containing authorized profile details.
Another method is that, if you want to store the authorized users email, its already present in the field as id_token. It is a base64_encoded data with some fields. If you decode the id yo will get some information about the user.For example in your result you found id_token as
eyJhbGciOiJSUzI1NiIsImtpZCI6ImRhNjYyNWIzNmJjMDlkMzAwMzUzYjI4YTc0MWNlMTc1MjVhNGMzM2IifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTE0MjE4NDEwODI0NzM1ODkyMDg0IiwiYXpwIjoiMTY5NzY2MjI4OTY4LWtoNzI1dTFpZWdzNHN1bnFhOThhcHUxMHU4djhhcmFmLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJhcmp1bkBsaW5rd2FyZS5pbiIsImF0X2hhc2giOiJQVnJxTURpNDViZnVGTm9kTmlsSFlRIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1ZCI6IjE2OTc2NjIyODk2OC1raDcyNXUxaWVnczRzdW5xYTk4YXB1MTB1OHY4YXJhZi5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImhkIjoibGlua3dhcmUuaW4iLCJpYXQiOjE0Mzc0ODIwNTUsImV4cCI6MTQzNzQ4NTY1NX0.uSMrV8rOz4T4i5MhiCeQueNVGLv4NBLP-gtOcyow8t4BY9qvUO78sG4y0jPhbclPdX1kUZjzMVTeah2nU9fTYyl50dlj5FzWNy7LyM-a1GC2jEwkgWMgHdRPh6l7dqMrjQ9sU1rF-ZaiWfG7C9VJTJ76uEWRiSKKA9EFQtBil3xBtmDH07UMRxkbri2jBwaCPAWgjU8-dTarrxNESrwrO_nptaRzfGeaTyQBIYCAk6_9deXmblPgteER1OHoa65xb1OVK3ZPeZ3_dj9gjlXSyGp2ho5WIFGf2xRvW4XoROpUYqhLvrS3s-YrrZ8J5X5-3mafrs1qDjJYJogctbW7dg
The above id_token contains 2 parts separated by '.'. The first part is thebase64_encoded key and the second part is metadata.
you can decode both the data as
$key=base64_decode(eyJhbGciOiJSUzI1NiIsImtpZCI6ImRhNjYyNWIzNmJjMDlkMzAwMzUzYjI4YTc0MWNlMTc1MjVhNGMzM2IifQ)
will give you the key
$data=base64_decode(eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTE0MjE4NDEwODI0NzM1ODkyMDg0IiwiYXpwIjoiMTY5NzY2MjI4OTY4LWtoNzI1dTFpZWdzNHN1bnFhOThhcHUxMHU4djhhcmFmLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJhcmp1bkBsaW5rd2FyZS5pbiIsImF0X2hhc2giOiJQVnJxTURpNDViZnVGTm9kTmlsSFlRIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1ZCI6IjE2OTc2NjIyODk2OC1raDcyNXUxaWVnczRzdW5xYTk4YXB1MTB1OHY4YXJhZi5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImhkIjoibGlua3dhcmUuaW4iLCJpYXQiOjE0Mzc0ODIwNTUsImV4cCI6MTQzNzQ4NTY1NX0.uSMrV8rOz4T4i5MhiCeQueNVGLv4NBLP-gtOcyow8t4BY9qvUO78sG4y0jPhbclPdX1kUZjzMVTeah2nU9fTYyl50dlj5FzWNy7LyM-a1GC2jEwkgWMgHdRPh6l7dqMrjQ9sU1rF-ZaiWfG7C9VJTJ76uEWRiSKKA9EFQtBil3xBtmDH07UMRxkbri2jBwaCPAWgjU8-dTarrxNESrwrO_nptaRzfGeaTyQBIYCAk6_9deXmblPgteER1OHoa65xb1OVK3ZPeZ3_dj9gjlXSyGp2ho5WIFGf2xRvW4XoROpUYqhLvrS3s-YrrZ8J5X5-3mafrs1qDjJYJogctbW7dg)
will give you the metadata.
while decoding the data ,it will give the result as
{"iss":"accounts.google.com","sub":"114218410824735892084","azp":"169766228968-kh725u1iegs4sunqa98apu10u8v8araf.apps.googleusercontent.com","email":"arjun#linkware.in","at_hash":"PVrqMDi45bfuFNodNilHYQ","email_verified":true,"aud":"169766228968-kh725u1iegs4sunqa98apu10u8v8araf.apps.googleusercontent.com","hd":"linkware.in","iat":1437482055,"exp":1437485655}
Above result you can find the email filed. I hope this will help you.
1) I have found the Twitter rush sample code from this link Twitter with OAuth
for the integration.
I have added consumer key and secret key. But it never authorizes the app.
2) And if I use share kit it gives the error that there was a problem requesting access from twitter.
3) If I use social framework then it will give alert if user hasn't added his/her account in settings.
I need that user shouldn't go outside the app for twitter login.
Does anyone have any idea on what would be the best way to integrate with twitter?
Please help.
I Hope This will help you . . .
1.Add following classes to your project
GTMOAuthAuthentication.h/m
GTMOAuthSignIn.h/m
GTMHTTPFetcher.h/m
GTMOAuthViewControllerTouch.h/m
GTMOAuthViewTouch.xib
2 . Add following frameworks
Security.framework and SystemConfiguration.framework.
3 .set -ObjC build option for the application target's "Other Linker Flags".
4 . Then it's time for some coding .
import GTMOAuthAuthentication.h and GTMOAuthViewControllerTouch.h
- (void)signInWithTwitter
{
NSURL *requestURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/request_token"];
NSURL *accessURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/access_token"];
NSURL *authorizeURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/authorize"];
NSString *scope = #"http://api.twitter.com/";
GTMOAuthAuthentication *auth = [self authForTwitter];
[auth setCallback:#"http://www.noop.com/OAuthCallback"];
GTMOAuthViewControllerTouch *viewController;
viewController = [[GTMOAuthViewControllerTouch alloc] initWithScope:scope
language:nil
requestTokenURL:requestURL
authorizeTokenURL:authorizeURL
accessTokenURL:accessURL
authentication:auth
appServiceName:#"AppName : Twitter"
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[appDelegate.navigationController pushViewController:viewController animated:YES];
}
- (GTMOAuthAuthentication *)authForTwitter {
GTMOAuthAuthentication *auth = [[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
consumerKey:TWITTER_CONSUMER_KEY
privateKey:TWITTER_CONSUMER_SECRET];
[auth setServiceProvider:#"Twitter"];
return auth;
}
- (void)viewController:(GTMOAuthViewControllerTouch *)viewController finishedWithAuth:(GTMOAuthAuthentication *)auth error:(NSError *)error {
if(error)
{
//handle error
}
else
{
// do stuff as per your app.
}
}
NOte : if you get error message like "failed to validate oauth signature and token" then check you system time is correct or not .
If you want that user shouldn't go outside you can use ACAccountStore Account.Framework and Social.framework for iOS 6,
NSUrl *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/users/show.json"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:twittername,#"screen_name",nil];
account = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
NSArray *twitterAccounts = [account accountsWithAccountType:twitterAccountType];
// Runing on iOS 6
if (NSClassFromString(#"SLComposeViewController") && [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
[account requestAccessToAccountsWithType:twitterAccountType options:NULL completion:^(BOOL granted, NSError *error)
{
if (granted)
{
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.preparedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
// [self loadData:data];
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
NSLog(#"data:%#",newStr);
}
});
}];
});
}
}];
}
else if (NSClassFromString(#"TWTweetComposeViewController") && [TWTweetComposeViewController canSendTweet]) // Runing on iOS 5
{
[account requestAccessToAccountsWithType:twitterAccountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted)
{
TWRequest *request = [[TWRequest alloc] initWithURL:url parameters:params requestMethod:TWRequestMethodGET];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.signedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"data:%#",newStr); }
});
}];
});
}
}];
}
}
You have to retain ACAccountStore: in .h
#property (nonatomic, strong) ACAccountStore *account;
I have developed the XMPP Chat client for iOS and now I'm researching for how to do a new user registration from iOS itself. Can anyone help with the methods used to register a new user. As it needs to communicate with the Server and store the username and password to the server database. Please help I'm searching it from 2 days.
NSMutableArray *elements = [NSMutableArray array];
[elements addObject:[NSXMLElement elementWithName:#"username" stringValue:#"venkat"]];
[elements addObject:[NSXMLElement elementWithName:#"password" stringValue:#"dfds"]];
[elements addObject:[NSXMLElement elementWithName:#"name" stringValue:#"eref defg"]];
[elements addObject:[NSXMLElement elementWithName:#"accountType" stringValue:#"3"]];
[elements addObject:[NSXMLElement elementWithName:#"deviceToken" stringValue:#"adfg3455bhjdfsdfhhaqjdsjd635n"]];
[elements addObject:[NSXMLElement elementWithName:#"email" stringValue:#"abc#bbc.com"]];
[[[self appDelegate] xmppStream] registerWithElements:elements error:nil];
We will know whether the registration is successful or not using the below delegates.
- (void)xmppStreamDidRegister:(XMPPStream *)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Registration" message:#"Registration Successful!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{
DDXMLElement *errorXML = [error elementForName:#"error"];
NSString *errorCode = [[errorXML attributeForName:#"code"] stringValue];
NSString *regError = [NSString stringWithFormat:#"ERROR :- %#",error.description];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Registration Failed!" message:regError delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
if([errorCode isEqualToString:#"409"]){
[alert setMessage:#"Username Already Exists!"];
}
[alert show];
}
This solution HAS WORKED for me
NSString *username = #"rohit#XMPP_SERVER_IP_HERE"; // OR [NSString stringWithFormat:#"%##%#",username,XMPP_BASE_URL]]
NSString *password = #"SOME_PASSWORD";
AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
del.xmppStream.myJID = [XMPPJID jidWithString:username];
NSLog(#"Does supports registration %ub ", );
NSLog(#"Attempting registration for username %#",del.xmppStream.myJID.bare);
if (del.xmppStream.supportsInBandRegistration) {
NSError *error = nil;
if (![del.xmppStream registerWithPassword:password error:&error])
{
NSLog(#"Oops, I forgot something: %#", error);
}else{
NSLog(#"No Error");
}
}
// You will get delegate called after registrations in either success or failure case. These delegates are in XMPPStream class
// - (void)xmppStreamDidRegister:(XMPPStream *)sender
//- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error
New user can register at XMPP server from iOS by two methods as
Methode 1.) By In band Registration (In-band registration means that users that do not have an account on your server can register one using the XMPP protocol itself, so the registration stays "in band", inside the same protocol you're already using.) you have to use XEP-0077 extension.
And your server should also have to support In band Registration.
Use these steps for In band Registration
step 1: connect with xmppStream
- (BOOL)connectAndRegister
{
if (![xmppStream isDisconnected]) {
return YES;
}
NSString *myJID = #"abc#XMPP_SERVER_IP_HERE"; // OR [NSString stringWithFormat:#"%##%#",username,XMPP_BASE_URL]]
NSString *myPassword = #"SOME_PASSWORD";
//
// If you don't want to use the Settings view to set the JID,
// uncomment the section below to hard code a JID and password.
//
// Replace me with the proper JID and password:
// myJID = #"user#gmail.com/xmppframework";
// myPassword = #"";
if (myJID == nil || myPassword == nil) {
DDLogWarn(#"JID and password must be set before connecting!");
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connect:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error connecting"
message:#"See console for error details."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
DDLogError(#"Error connecting: %#", error);
return NO;
}
return YES;
}
NSString *password declare at #interface part of your file
step 2: When xmppStream Delegate - (void)xmppStreamDidConnect:(XMPPStream *)sender call
step 3: Start register via In-Band Registration as
- (void)xmppStreamDidConnect:(XMPPStream *)sender{
DDLogVerbose(#"%#: %#", THIS_FILE, THIS_METHOD);
[[NSNotificationCenter defaultCenter] postNotificationName:XMPPStreamStatusDidConnectNotification
object:nil
userInfo:nil];
_isXmppConnected = YES;
NSError *error = nil;
DDLogVerbose(#"Start register via In-Band Registration...");
if (xmppStream.supportsInBandRegistration) {
if (![xmppStream registerWithPassword:password error:&error]) {
NSLog(#"Oops, I forgot something: %#", error);
}else {
NSLog(#"No Error");
}
}
// [_xmppStream authenticateWithPassword:password error:&error];
}
step 4: Check registration success or failure by XMPPStream delegate
- (void)xmppStreamDidRegister:(XMPPStream *)sender
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error
Methode 2.) By XMPP Rest Api on the openFire server installed a plugin (Rest Api plugin) that allows normal registration.
Use these steps for Rest Api Registration
step 1: Install Rest Api plugin on server
step 2: Configure server for Rest Api as server -> server settings -> Rest Api then enable it.
You can use "Secret key auth" for secure user registration, so copy that from openfire server and use when rest api is called for registration.
step 3: Call Rest Api for registration
-(void)CreateUserAPI
{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"abc",#"username",#"SOME_PASSWORD",#"password",#"abc-nickname",#"name",#"abc#example.com",#"email", nil];
NSData* RequestData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
NSMutableURLRequest *request = [ [ NSMutableURLRequest alloc ] initWithURL: [ NSURL URLWithString:[NSString stringWithFormat:#"%#users",RESTAPISERVER]]];
[request setHTTPMethod: #"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:AuthenticationToken forHTTPHeaderField:#"Authorization"];
[request setHTTPBody: RequestData];
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
// handle response
if (!error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if ([httpResponse statusCode]==201)
{
NSLog(#"Registration Successful");
}else
{
NSLog(#"Registration failed");
}
}else
{
NSLog(#"Try again for registration");
}
}] resume];
}
RESTAPISERVER is a Rest api url string.
AuthenticationToken is a "Secret key auth" (copy from openfire server)
I am trying to make a basic authentication system in iOS that sends a POST to Django and on the Django side authenticates the user and starts a session. Right now I am able to send the user information by passing the values as data in the URL and authenticating it, but how do I retrieve the session data or cookie from the Django response? When I try to store or print out the cookie, it tells me the array is empty. I have tried both request.requestCookies and request.responseCookies.
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"test_user", #"username", #"pass", #"password", nil];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://127.0.0.1:8000/login/"]];
NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
if ( error ) {
NSLog( #"ERROR - %#", error.localizedDescription );
} else {
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request addRequestHeader: #"Content-Type" value:#"application/json; charset=utf-8"];
[request appendPostData:data];
[request setRequestMethod:#"POST"];
[request setCompletionBlock:^{
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:#"Login"
message:#"Login was sent"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[alerView performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];
NSLog(#"RESPONSE: %#", [[NSString alloc] initWithData:request.responseData encoding:NSUTF8StringEncoding]);//, [request.requestCookies objectAtIndex:0]);
NSLog(#"COOKIE: %#", [request.requestCookies objectAtIndex:0]);
[ASIHTTPRequest addSessionCookie:[request.requestCookies objectAtIndex:0]];
}];
Okay, so I resolved this issue and it turns out that on the server side I was putting in the data but not officially logging in with Django (was not returning the proper cookies) which meant my app was not receiving the proper header.