FHSTwitterEngine image not post - ios

Post image with FHStwitterEngine it return error But if i post tweet without imahe than it post successfully
-(void)postTweet:(NSString*)message withImage:(UIImage*)img {
dispatch_async(GCDBackgroundThread, ^{
#autoreleasepool {
NSString *strMsg =[NSString stringWithFormat:#"%#",message];
NSData *imgData =UIImagePNGRepresentation(img);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSError *returnCode = [[FHSTwitterEngine sharedEngine]postTweet:strMsg withImageData:imgData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *title = nil;
NSString *message = nil;
if (returnCode) {
title = [NSString stringWithFormat:#"Error %d",returnCode.code];
message = returnCode.localizedDescription;
} else {
title = #"Tweet Posted";
message = message;
}
dispatch_sync(GCDMainThread, ^{
#autoreleasepool {
UIAlertView *av = [[UIAlertView alloc]initWithTitle:title message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}
});
}
});
}
- (IBAction)btnPost:(id)sender {
NSString *str =#"Test5";
UIImage *image =[UIImage imageNamed:#"contact.png"];
if (image ==nil) {
[self postTweet:str];
}else {
[self postTweet:str withImage:image];
}
}

There is an issue with the current version of FHSTwitterEngine and posting images. I had the same issue in my app, but was able to solve it using the updates from this forked version:
https://github.com/alvani/FHSTwitterEngine/blob/master/FHSTwitterEngine/FHSTwitterEngine.m
It's easiest to just copy/paste that into FHSTwitterEngine.m, but here's the specific changes you'll need:
On or around Line 1599:
- (NSError *)sendPOSTRequestForURL:(NSURL *)url andParams:(NSDictionary *)params
...
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
Add the following code below:
if ([obj isKindOfClass:[NSData class]]) {
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
On or around Line 688:
- (NSError *)postTweet:(NSString *)tweetString withImageData:(NSData *)theData inReplyTo:(NSString *)irt {
...
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[#"media[]"] = theData;
Add the following code below:
params[#"status"] = tweetString;
Hope this helps!

Related

Background thread completion blocks possibly firing before completion

I am writing a photo upload queue manager.
Here is my process. The user can take a picture or choose one from the camera roll.
The image, along with some other string data, is placed in queue.
The queue is simply an array that contains the image path string and the other string data. The 'queued' image is saved to the documents directory of the application for later retrieval.
Every second the queue is checked to see if any images that need to be uploaded, then it does so, one-by-one.
When it uploads, the server responds with a string of success, if success then the picture is removed from list queue, the temp image is deleted and the program moves on to the next queued image.
If I call the uploadImage: method independently and pass it the image and string data, the image uploads fine. But when called from a background thread, the image is never truly uploaded even though the server responds success instantly. I feel like since the server is responding instantly with success, that the image is only partially being uploaded.
processImage: is the method that calls uploadImage: from the background.
I could really use an expert's eyes to see what might be causing the app to not fully wait on the photo to upload before continuing.
#interface ImageUploader ()
#property (nonatomic, strong) NSMutableArray * arrPhotoQueue;
#property (nonatomic, strong) NSTimer* timerUpload;
#end
#implementation ImageUploader {
NSUserDefaults * defaults; //Just were we are currently storing a list of images.
NSArray *paths;
NSString *documentsDirectory;
}
#pragma mark Public Methods
- (void) startPhotoUploadCheck {
if (!_timerUpload) {
if(![_timerUpload isValid]){
_timerUpload = [NSTimer scheduledTimerWithTimeInterval:_timerCheckInterval target:self selector:#selector(checkForPhotosToUpload) userInfo:nil repeats:YES];
}
}
}
- (void) addImageToQueue:(UIImage*)image withCallKey:(NSString*) callKey {
NSData *imageData = UIImagePNGRepresentation(image);
NSString *fileName = [NSString stringWithFormat:#"%#.png",[self randomStringWithLength:8]];
NSString *imagePath =[documentsDirectory stringByAppendingPathComponent:fileName];
NSMutableDictionary * data = [[NSMutableDictionary alloc] init];
[data setValue:fileName forKey:#"imagePath"];
[data setValue:callKey forKey:#"callKey"];
[_arrPhotoQueue addObject:data];
if (![imageData writeToFile:imagePath atomically:NO]) {
NSLog(#"Failed to cache image data to disk");
} else {
NSLog(#"Image %#", fileName);
[defaults setObject:_arrPhotoQueue forKey:#"PendingPhotos"];
[defaults synchronize];
}
[self totalImagesInQueue];
}
- (void) checkForPhotosToUpload {
//this does some logic to just see if there is a connection to the internet and that there are photos in queue then it calls
[self proceedWithUpload];
}
#pragma mark Upload Image
- (int) removePhotoFromMemory:(NSString *) callKeyOfUploadedPhoto
{
int nIndexOfUploadedPhoto = -1;
for (int i = 0; i < [_arrPhotoQueue count]; i++) {
NSString * callKey = [_arrPhotoQueue[i] objectForKey:#"callKey"];
if ([callKey isEqualToString:callKeyOfUploadedPhoto]) {
//remove uploaded photo
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:[_arrPhotoQueue[i] objectForKey:#"imagePath"]];
NSLog(#"Remove image from queue: %#", [_arrPhotoQueue[i] objectForKey:#"imagePath"]);
[[NSFileManager defaultManager] removeItemAtPath:imagePath error:nil];
nIndexOfUploadedPhoto = i;
break;
}
}
return nIndexOfUploadedPhoto;
}
- (void) proceedWithUpload {
NSMutableArray* removeArray = [[NSMutableArray alloc] init];
dispatch_group_t taskGroup = dispatch_group_create();
for (int i = 0; i < [_arrPhotoQueue count]; i++) {
dispatch_group_enter(taskGroup);
UIImage * image = [UIImage imageWithContentsOfFile:[_arrPhotoQueue[i] objectForKey:#"imagePath"]];
NSString * callKey = [_arrPhotoQueue[i] objectForKey:#"callKey"];
[self processImage:image :callKey completed:^(bool bSuccess){
if (bSuccess) {
//photo is uploaded successfully
int nPhotoIdx = [self removePhotoFromMemory:callKey];
if (nPhotoIdx > -1) {
[removeArray addObject:[NSString stringWithFormat:#"%d", nPhotoIdx]];
}
dispatch_group_leave(taskGroup);
} else {
dispatch_group_leave(taskGroup);
}
}];
}
// Here we wait for all the requests to finish
dispatch_group_notify(taskGroup, dispatch_get_main_queue(), ^{
// run code when all files are downloaded
[self removePhotoFromQueue:removeArray];
});
}
- (void) removePhotoFromQueue:(NSMutableArray*)index {
NSArray *sortedIndex = [index sortedArrayUsingComparator:^(id obj1, id obj2){
if ([obj1 isKindOfClass:[NSString class]] && [obj2 isKindOfClass:[NSString class]]) {
int nFirstIndex = (int)[obj1 integerValue];
int nSecondIndex = (int)[obj2 integerValue];
if (nFirstIndex > nSecondIndex) {
return (NSComparisonResult)NSOrderedAscending;
} else if (nFirstIndex < nSecondIndex) {
return (NSComparisonResult)NSOrderedDescending;
}
}
return (NSComparisonResult)NSOrderedSame;
}];
for (int i =0; i < [sortedIndex count]; i++) {
int nIdx = (int)[sortedIndex[i] integerValue];
[_arrPhotoQueue removeObjectAtIndex:nIdx];
}
[defaults removeObjectForKey:#"PendingPhotos"];
[defaults setObject:_arrPhotoQueue forKey:#"PendingPhotos"];
[defaults synchronize];
}
#pragma mark Image Processor
- (void) processImage:(UIImage*)image :(NSString*)callKey completed:(void(^)(bool bSuccess)) block{
__block NSMutableDictionary * message;
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
message = [self uploadImage:image CallKey:callKey];
[self uploadImage:image CallKey:callKey];
dispatch_async(dispatch_get_main_queue(), ^{
if ([[message objectForKey:#"status"] isEqualToString:#"success"]) {
block(true);
} else {
NSLog(#"Somethign is wrong");
block(false);
}
});
});
}
- (NSMutableDictionary*) uploadImage:(UIImage *)theimage CallKey:(NSString*)callKey {
NSData * imageData = UIImageJPEGRepresentation([self fixrotation:theimage], 90);
NSString * jsonString= [JSONCommunicator buildJSONForImageUpload:[self prepareDictionaryDataForUploadWithKey:callKey]];
NSURL * uploadURL = [NSURL URLWithString:MYURL];
// create the URL
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:uploadURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
[postRequest setHTTPMethod:#"POST"];
// just some random text that will never occur in the body
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *headerBoundary = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[postRequest addValue:headerBoundary forHTTPHeaderField:#"Content-Type"];
// create data
NSMutableData *postBody = [NSMutableData data];
// JSON part
[postBody appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[#"Content-Disposition: form-data; name=\"params\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
// media part
[postBody appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"UploadedFile\"; filename=\"image.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[#"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:imageData];
[postBody appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
// final boundary
[postBody appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSString *s = [[NSString alloc] initWithData:postBody encoding:NSASCIIStringEncoding];
//NSLog(#"Image String: %#", s);
// add body to post
[postRequest setHTTPBody:postBody];
// pointers to some necessary objects
NSURLResponse* response;
NSError* error;
// synchronous filling of data from HTTP POST response
NSData *responseData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
}
// convert data into string
NSString *responseString = [[NSString alloc] initWithBytes:[responseData bytes] length:[responseData length] encoding:NSUTF8StringEncoding];
NSLog(#"TOPS Response String: %#", responseString);
NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary * dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
return dictionary;
}

Payu money Payment GateWay Integration

I am trying to integrate payu money payment gateway in my app.
Payumoney collect all information and done transaction and return back to my custom defined url webpage.
My problem is how to get the response code after successful transaction from payu money gateway?
int i = arc4random() % 9999999999;
NSString *strHash = [self createSHA512:[NSString stringWithFormat:#"%d%#",i,[NSDate date]]];
NSString *txnid1 = [strHash substringToIndex:20];
NSLog(#"tnx1 id %#",txnid1);
// NSString *key = #"JBZaLc";
// NSString* salt = #"GQs7yium";
NSString *key = #"gtKFFx";
NSString* salt = #"eCwWELxi";
NSString *amount = dataMoney.usrAmount;
NSString *productInfo = #"App Products Info ";
NSString *firstname = dataMoney.usrName;
NSString *email = dataMoney.usrEmail;
NSString *phone = dataMoney.usrMobile;
NSString *surl = #"https://dl.dropboxusercontent.com/s/dtnvwz5p4uymjvg/success.html";
NSString *furl = #"https://dl.dropboxusercontent.com/s/z69y7fupciqzr7x/furlWithParams.html";
NSString *hashValue = [NSString stringWithFormat:#"%#|%#|%#|%#|%#|%#|||||||||||%#",key,txnid1,amount,productInfo,firstname,email,salt];
NSString *hash = [self createSHA512:hashValue];
NSDictionary *parameters = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:txnid1,key,amount,productInfo,firstname,email,phone,surl,furl,hash, nil] forKeys:[NSArray arrayWithObjects:#"txnid",#"key",#"amount",#"productinfo",#"firstname",#"email",#"phone",#"surl",#"furl",#"hash", nil]];
__block NSString *post = #"";
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([post isEqualToString:#""]) {
post = [NSString stringWithFormat:#"%#=%#",key,obj];
}else{
post = [NSString stringWithFormat:#"%#&%#=%#",post,key,obj];
}
}];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://test.payu.in/_payment"]]];
// change URL for live
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[web_view_PayU loadRequest:request];
#define Merchant_Key #"your merchant key "
#define Salt #"your salt key"
#define Base_URL #"https://secure.payu.in"
> //this base url in case of origional payment key's if you want to integarate with
test key's write base Url can check in payumoney Faq
**
#define Success_URL #"https://www.google.co.in/"
#define Failure_URL #"http://www.bing.com/"
#define Product_Info #"Denim Jeans"
#define Paid_Amount #"1549.00"
#define Payee_Name #"Suraj Mirajkar"
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self setTitle:#"Make A Payment"];
[self initPayment];
}
- (void)viewDidLoad {
[super viewDidLoad];
activityIndicatorView = [[UIActivityIndicatorView alloc] init];
activityIndicatorView.center = self.view.center;
[activityIndicatorView setColor:[UIColor blackColor]];
[self.view addSubview:activityIndicatorView];
}
-(void)initPayment {
int i = arc4random() % 9999999999;
NSString *strHash = [self createSHA512:[NSString stringWithFormat:#"%d%#",i,[NSDate date]]];// Generatehash512(rnd.ToString() + DateTime.Now);
NSString *txnid1 = [strHash substringToIndex:20];
strMIHPayID = txnid1;
NSString *key = Merchant_Key;
NSString *amount =[[NSUserDefaults standardUserDefaults]
stringForKey:#"orderprice"];
//NSString *amount = Paid_Amount;
NSString *productInfo = Product_Info;
NSString *firstname = Payee_Name;
NSString *email = [NSString stringWithFormat:#"suraj%d#yopmail.com",i];
//ADD A fake mail For Payment for testing purpose
// Generated a fake mail id for testing
NSString *phone = #"9762159571";
NSString *serviceprovider = #"payu_paisa";
NSString *hashValue = [NSString stringWithFormat:#"%#|%#|%#|%#|%#|%#|||||||||||%#",key,txnid1,amount,productInfo,firstname,email,Salt];
NSString *hash = [self createSHA512:hashValue];
NSDictionary *parameters = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:txnid1,key,amount,productInfo,firstname,email,phone,Success_URL,Failure_URL,hash,serviceprovider
, nil] forKeys:[NSArray arrayWithObjects:#"txnid",#"key",#"amount",#"productinfo",#"firstname",#"email",#"phone",#"surl",#"furl",#"hash",#"service_provider", nil]];
NSLog(#"%#",parameters);
__block NSString *post = #"";
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([post isEqualToString:#""]) {
post = [NSString stringWithFormat:#"%#=%#",key,obj];
} else {
post = [NSString stringWithFormat:#"%#&%#=%#",post,key,obj];
}
}];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/_payment",Base_URL]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[_webviewPaymentPage loadRequest:request];
[activityIndicatorView startAnimating];
}
-(NSString *)createSHA512:(NSString *)string {
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++) {
[output appendFormat:#"%02x", digest[i]];
}
return output;
}
#pragma UIWebView - Delegate Methods
-(void)webViewDidStartLoad:(UIWebView *)webView {
NSLog(#"WebView started loading");
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[activityIndicatorView stopAnimating];
if (webView.isLoading) {
return;
}
NSURL *requestURL = [[_webviewPaymentPage request] URL];
NSLog(#"WebView finished loading with requestURL: %#",requestURL);
NSString *getStringFromUrl = [NSString stringWithFormat:#"%#",requestURL];
if ([self containsString:getStringFromUrl :Success_URL]) {
[self performSelector:#selector(delayedDidFinish:) withObject:getStringFromUrl afterDelay:0.0];
} else if ([self containsString:getStringFromUrl :Failure_URL]) {
// FAILURE ALERT
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Sorry !!!" message:#"Your transaction failed. Please try again!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
alert.tag = 1;
[alert show];
}
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[activityIndicatorView stopAnimating];
NSURL *requestURL = [[_webviewPaymentPage request] URL];
NSLog(#"WebView failed loading with requestURL: %# with error: %# & error code: %ld",requestURL, [error localizedDescription], (long)[error code]);
if (error.code == -1009 || error.code == -1003 || error.code == -1001) { //error.code == -999
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Oops !!!" message:#"Please check your internet connection!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
alert.tag = 1;
[alert show];
}
}
- (void)delayedDidFinish:(NSString *)getStringFromUrl {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *mutDictTransactionDetails = [[NSMutableDictionary alloc] init];
[mutDictTransactionDetails setObject:strMIHPayID forKey:#"Transaction_ID"];
[mutDictTransactionDetails setObject:#"Success" forKey:#"Transaction_Status"];
[mutDictTransactionDetails setObject:Payee_Name forKey:#"Payee_Name"];
[mutDictTransactionDetails setObject:Product_Info forKey:#"Product_Info"];
[mutDictTransactionDetails setObject:Paid_Amount forKey:#"Paid_Amount"];
[self navigateToPaymentStatusScreen:mutDictTransactionDetails];
});
}
#pragma UIAlertView - Delegate Method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == 1 && buttonIndex == 0) {
// Navigate to Payment Status Screen
NSMutableDictionary *mutDictTransactionDetails = [[NSMutableDictionary alloc] init];
[mutDictTransactionDetails setObject:Payee_Name forKey:#"Payee_Name"];
[mutDictTransactionDetails setObject:Product_Info forKey:#"Product_Info"];
[mutDictTransactionDetails setObject:Paid_Amount forKey:#"Paid_Amount"];
[mutDictTransactionDetails setObject:strMIHPayID forKey:#"Transaction_ID"];
[mutDictTransactionDetails setObject:#"Failed" forKey:#"Transaction_Status"];
[self navigateToPaymentStatusScreen:mutDictTransactionDetails];
}
}
- (BOOL)containsString: (NSString *)string : (NSString*)substring {
return [string rangeOfString:substring].location != NSNotFound;
}
- (void)navigateToPaymentStatusScreen: (NSMutableDictionary *)mutDictTransactionDetails {
dispatch_async(dispatch_get_main_queue(), ^{
PaymentStatusViewController *paymentStatusViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"PaymentStatusScreenID"];
paymentStatusViewController.mutDictTransactionDetails = mutDictTransactionDetails;
[self.navigationController pushViewController:paymentStatusViewController animated:YES];
});
}
Important Note : you can check your Merchant key and Salt in seller Dashboard after Login ... Go To my account and check your merchant key and salt

GooglePlus Integration in ios

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.

I have integrated google plus in my IOS App , Now how can i get profile detail of logged in user?

I have integrated google plus in my ios app ,I am able to get access token.I have used authentication flow to integrate google plus.So now after getting access token how can i get user profile details like username, email id, profile pic etc?
My code to get access token is as below:
-(IBAction)btnGooglePlusClicked:(UIButton *)sender
{
IBwebView.hidden = FALSE;
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%#&redirect_uri=%#&scope=%#&data-requestvisibleactions=%#",GOOGLE_PLUS_CLIENT_ID,GOOGLE_PLUS_CALL_BACK_URL,GOOGLE_PLUS_SCOPE,GOOGLE_PLUS_VISIBLE_ACTIONS];
[IBwebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
// [indicator startAnimating];
if ([[[request URL] host] isEqualToString:#"localhost"]) {
// 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,GOOGLE_PLUS_CLIENT_ID,GOOGLE_PLUS_CLIENT_SECRET,GOOGLE_PLUS_CALL_BACK_URL];
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
{
[receivedData appendData:data];
NSLog(#"verifier %#",receivedData);
}
- (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];
}
I feel the the method you are using will not help to get the profile detail.
I suggest to use the proper method which ensures the best results.
Please check this out : https://developers.google.com/+/mobile/ios/
This will surely help you to get required outcome.

AFNetworking - Download File, unexpected message format 'Raw'

I am basically trying to download a file which can be from a PDF to a PNG. I am using AFNetworking 1.x.
However, I am getting an error:
NSURL *baseURL = [NSURL URLWithString:#"https://myserver.com/webservices/Services/"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
//NSLog(#"Formatted URL: %#", formattedURL);
//NSMutableURLRequest *photoRequest = [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[httpClient defaultValueForHeader:#"Accept"];
[httpClient setParameterEncoding:AFFormURLParameterEncoding];
[parameters setObject:[NSNumber numberWithInteger:#"10772"] forKey:#"FileId"];
[parameters setObject:[NSNumber numberWithBool:YES] forKey:#"requireUnCompression"];
NSMutableURLRequest *fileRequest = [httpClient requestWithMethod:#"POST" path:#"FileService.svc/DownloadFile" parameters:parameters];
//[fileRequest setHTTPBody:<#(NSData *)#>]
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:fileRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successss!");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed: %#", [operation error]);
}];
[httpClient enqueueHTTPRequestOperation:operation];
However, I am getting an error:
Failed: Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 400" UserInfo=0x12112770 {NSLocalizedRecoverySuggestion={"faultType":"InvalidOperationException","message":"The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details."}, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest: 0xc865c40> { URL: https://myserver.com/webservice/Services/FileService.svc/DownloadFile }, NSErrorFailingURLKey=https://myserver.com/webservices/Services/FileService.svc/DownloadFile, NSLocalizedDescription=Expected status code in (200-299), got 400, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xc8696a0> { URL: https://myserver.com/webservices/Services/FileService.svc/DownloadFile } { status code: 400, headers {
"Cache-Control" = private;
"Content-Length" = 327;
"Content-Type" = "application/xml; charset=utf-8";
Date = "Thu, 17 Oct 2013 19:45:07 GMT";
"Persistent-Auth" = true;
Server = "Microsoft-IIS/8.0";
"X-AspNet-Version" = "4.0.30319";
"X-Powered-By" = "ASP.NET";
} }}
Thank you in advance!
I download PDFs/Images/WordDocs in my app without AFNetworking, I also ran into issues, so I decided to just good old NSURLConnection. My NSURLRequest does not use POST data, but I modified the NSURLRequest in here for POST data.
Once the file is done downloading, I present a QLPreviewController to display it. (this can handle displaying PDFs, images, or word docs. It requires a bit more code if youd like to see that as well)
Declare 4 properties in your .h:
#property (strong, nonatomic) NSNumber *reportLength;
#property (strong, nonatomic) NSURLConnection *reportConnection;
#property (strong, nonatomic) NSMutableData *reportData;
#property (strong, nonatomic) NSString *reportURL;
also add NSURLConnectionDelegate to your delegate list
Then in the .m:
- (void)downloadReport:(NSString *)reqUID
{
NSString *file = [NSString stringWithFormat:#"%#GetReport.ashx?requestUID=%#&deviceUID=%#&token=%#", _globals.baseURL, reqUID, [MySingleton getDeviceID], _globals.token];
NSURL *fileURL = [NSURL URLWithString:file];
NSMutableURLRequest *req = [NSURLRequest requestWithURL:fileURL];
[req setHTTPMethod:#"POST"];
NSString *postString = #"FileID=10772&requireUnCompression=1";
[req setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
_reportConnection = [NSURLConnection connectionWithRequest:req delegate:self];
_reportData = [NSMutableData data];
[_reportConnection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[_reportData setLength:0];
NSLog(#"didReceiveResponse %#: %#", [response URL], [(NSHTTPURLResponse*)response allHeaderFields]);
_reportLength = [NSNumber numberWithLongLong:[response expectedContentLength]];
if(_reportLength.longLongValue == 0)
{
[_reportConnection cancel];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Empty Report" message:#"The report you requested is empty. " delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil, nil];
[alert show];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[_reportData length]];
[_reportData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSString *msg = [NSString stringWithFormat:#"Error"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"There was an issue downloading the attachment. Please try again." message:msg delegate:self cancelButtonTitle:#"Not Now" otherButtonTitles: #"Yes", nil];
[alert show];
}
//when finished save in documents directory
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
_reportURL = [NSString stringWithFormat:#"%#/%#", [dirArray objectAtIndex:0], [NSString stringWithFormat:#"%#.pdf", _currentRequestUID]];
NSError *err;
if ([_reportData writeToFile:_reportURL options:NSAtomicWrite error:&err] == NO) {
NSLog(#"writeToFile error: %#", _reportURL);
NSString *msg = [NSString stringWithFormat:#"There was an issue saving the attachment. Please try again."];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:msg delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
else //pdf downloaded, display using QLPreviewController
{
NSLog(#"Written: _reportURL: %#", _reportURL);
QLPreviewController *previewController=[[QLPreviewController alloc]init];
previewController.delegate=self;
previewController.dataSource=self;
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(btnCloseQLTouch:)];
[previewController.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects:btn, nil]];
[self presentViewController:previewController animated:YES completion:nil];
}
}
EDIT
To get the QLPreviewController working first add the <QuickLook.framework> to your project, then add these deletages in your .h:
QLPreviewControllerDataSource, QLPreviewControllerDelegate
Here are the datasource/delegate methods needed to display the file:
//quicklook datasource/ delegate
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return 1;
}
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
return [NSURL fileURLWithPath:_reportURL];
}

Resources