I want to get address from latitude and longitude with GoogleGEO CODING (EX URL = http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false )
So I want to get JSON from that page by AFNetworking.
It's my code below :
IBAction)reLocation:(UIButton*)sender
{
if(sender.tag==1)
{
NSArray *gpsValue = [self getGPS];
float lat = [[gpsValue objectAtIndex:0] floatValue];
float lon = [[gpsValue objectAtIndex:1] floatValue];
NSString *string = [NSString stringWithFormat:#"%#%#,%#&sensor=true_or_false",GEOCODING_URL,[NSString stringWithFormat:#"%f", lat],[NSString stringWithFormat:#"%f",lon]]; // NSString *str = [NSString stringWithFormat:#"%f", myFloat];
NSLog(string);
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"AFNetworking success");
NSDictionary *location = (NSDictionary *)responseObject;
// 3
self.title = #"JSON Retrieved";
//[self.tableView reloadData];
NSLog(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"AFNetworking failure");
switch (operation.response.statusCode) {
case 400:
// Do stuff
NSLog(#"error 400");
break;
default:
NSLog([NSString stringWithFormat:#"%ld",(long)operation.response.statusCode]);
break;
}
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
}}
But when I click my button, always afnetworking fails and log shows 0 for status code.
I also got url log that i put in
i already checked that url is not problem (it shows json in working order)
I debug with simulator!
Is there something I miss ?
Related
This question already has answers here:
AFNetworking multiple files upload
(3 answers)
Closed 6 years ago.
I used Afnetworking in my app,I need to post 5 images to server, 5 images as array, this array was one of my **request parameters.
this is correct way or wrong one, there is any one more performance than it ? -
(IBAction)sPActionButton:(id)sender {
NSUserDefaults *def=[NSUserDefaults standardUserDefaults];
NSString * language=[def objectForKey:#"Language"];
NSString * deviceToken=[def objectForKey:#"dT"];
[par setObject:deviceToken forKey:#"dT"];
NSString *check=[def objectForKey:#"Log"];
[par setObject:check forKey:#"aT"];
//---------------------------------------------
NSString * apiKey=APIKEY;
[par setObject:apiKey forKey:#"aK"];
[par setObject:language forKey:#"lG"];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:10];
for (int x=0; x<_chosenImages.count; x++) {
NSData *imageData = UIImageJPEGRepresentation(_chosenImages[x], 0.5);
NSLog(#"%#",imageData);
NSString *str=[Base64 encode:imageData];
[images addObject:str];
}
NSLog(#"%#",images);
[par setObject:images forKey:#"image[array]"];
if ([self validateAllFields]) {
NSLog(#"par = %#",par);
//-----------------------------------------------
[MBProgressHUD showHUDAddedTo:self.view animated:NO];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:[NSString stringWithFormat:#"%#/sellPrp?",BASEURl] parameters:par
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Data"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
[MBProgressHUD hideHUDForView:self.view animated:NO];
}];
}
}
- (void)prepareForImagePosting
{
if (imageCount < self.arrAllPostImages.count)//arrAllPostImages array contains images for posting and imageCount acts as iterator
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init]; //Prepare the dictionary which contains image for posting
[dict setObject:#"1" forKey:#"upload"];
[dict setObject:[[self.arrAllPostImages objectAtIndex:imageCount]objectForKey:#"SelectedPhoto"] forKey:#"post_image"];
[self postImage:dict];
}
else
return;
}
- (void)postImage: (NSMutableDictionary *)dictPostImages
{
NSError *error = nil;
NSString *url = POSTIMAGELINK;
NSMutableDictionary *postDict = [[NSMutableDictionary alloc]init];
[postDict setObject:[dictPostImages objectForKey:#"upload"] forKey:#"upload"];
NSData *jsonRequestDict = [NSJSONSerialization dataWithJSONObject:postDict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonCommand = [[NSString alloc] initWithData:jsonRequestDict encoding:NSUTF8StringEncoding];
NSLog(#"***jsonCommand***%#",jsonCommand);
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:jsonCommand,#"requestParam", nil];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
if (isEnteredInFailureBlock == NO)
{
//here Image is posted
NSData *postPicData=UIImageJPEGRepresentation([dictPostImages objectForKey:#"post_image"], 0.5) ;
[formData appendPartWithFileData:postPicData
name:#"post_image"
fileName:[NSString stringWithFormat:#"image%d.jpg",imageCount]
mimeType:#"image/*"];
}
else
{
}
} success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSError *error = nil;
NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Request Successful, response '%#'", responseStr);
NSMutableDictionary *jsonResponseDict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"Response Dictionary:: %#",jsonResponseDict);
if ([[jsonResponseDict objectForKey:#"status"] intValue] == 1)
{
if (isEnteredInFailureBlock == NO)
{
[self.arrSuccessfullyPostedImagesDetails addObject:jsonResponseDict];
if (appDel.successfullImgPostingCount == appDel.totalPostingImagesCount)
{
}
else
{
appDel.successfullImgPostingCount++;
imageCount++;
[self prepareForImagePosting];
}
}
else
{
self.arrSuccessfullyPostedImagesDetails = [[NSMutableArray alloc]init];
appDel.successfullImgPostingCount = 0;
appDel.totalPostingImagesCount = 0;
imageCount = 0;
return;
}
}
else
{
self.arrSuccessfullyPostedImagesDetails = [[NSMutableArray alloc]init];
appDel.successfullImgPostingCount = 0;
appDel.totalPostingImagesCount = 0;
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request Error: %#", error);
isEnteredInFailureBlock = YES;
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Alert!" message:#"Posting Unsuccessful" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert show];
// if image is not successfully posted then the server is informed with #"upload" #"0" so that the entire post is deleted from server
NSMutableDictionary *failureDict = [[NSMutableDictionary alloc]init];
[failureDict setObject:#"0" forKey:#"upload"];
[self postImage:failureDict];
}];
}
I am facing anonymous behavior of service response. Sometime service fetched well and sometimes it gives an error message "A server with specified host name can't be found". I am using AFNetworking. Same service worked very well in android platform. Is there any better way to fetch them accurately in iPhone.
here is my piece of code:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSDictionary *params = #{#"email" : txtEmail.text,
#"password" : txtPassword.text,
};
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
operationManager.requestSerializer = [AFJSONRequestSerializer serializer];
operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
[operationManager POST:#"http://somelink/someuser.svc/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", operation.responseString);
NSDictionary *responseDict = responseObject;
NSLog(#"%#",[responseDict valueForKey:#"result_code"]);
if ([[responseDict valueForKey:#"result_code"] isEqualToString:#"1"]) {
NSDictionary *data = [responseObject objectForKey:#"result_data"];
NSLog(#"%#",[data objectForKey:#"email"]);
[[NSUserDefaults standardUserDefaults]setObject:[data objectForKey:#"user_id"] forKey:#"UserId"];
NSString *query = [NSString stringWithFormat:#"insert into userMaster (user_id, name_first, name_last, email, password, image, gender, rec_limit, total_followers, total_following, is_brand, category) values ('%#','%#','%#','%#','%#','%#','%#',%d,'%#','%#',%d,%d)",[data objectForKey:#"user_id"],[data objectForKey:#"name_first"],[data objectForKey:#"name_last"],[data objectForKey:#"email"],[data objectForKey:#"password"],[data objectForKey:#"image"],[data objectForKey:#"gender"],[[data objectForKey:#"rec_limit"]intValue],[data objectForKey:#"total_followers"],[data objectForKey:#"total_following"],[[data objectForKey:#"is_brand"]intValue],[[data objectForKey:#"category"]intValue]];
// NSLog(#"%#",[data objectForKey:#"intrests"]);
NSLog(#"%#",query);
int n = [service insertUpdateDeleteWithQuery:query inDatabase:#"WaveDb.sql"];
NSLog(#"%d",n);
NSArray *arr = [data objectForKey:#"intrests"];
for (int i = 0; i < arr.count; i++) {
NSLog(#"%#",[arr objectAtIndex:i]);
query = [NSString stringWithFormat:#"insert into userCategory (user_id, cat_id) values ('%#','%#')",[[NSUserDefaults standardUserDefaults]objectForKey:#"UserId"],[arr objectAtIndex:i]];
[service insertUpdateDeleteWithQuery:query inDatabase:[DataClass databaseName]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[(AppDelegate *)[[UIApplication sharedApplication]delegate]hideProgress];
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"login"];
WallViewController *main = [self.storyboard instantiateViewControllerWithIdentifier:#"wallView"];
[self.navigationController pushViewController:main animated:YES];
});
}
else {
[(AppDelegate *)[[UIApplication sharedApplication]delegate]hideProgress];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Alert!" message:#"Invalid username and password" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
} failure:^(AFHTTPRequestOperation operation, NSError error) {
NSLog(#"Error: %#", error);
dispatch_async(dispatch_get_main_queue(), ^{
[(AppDelegate *)[[UIApplication sharedApplication]delegate]hideProgress];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Alert!" message:#"Some technical error occured. Try later." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
});
}];
});
check reachability before any code execution is solved my problem.
I am using AFHTTPRequestOperationManager for login.
- (IBAction)loginAction
{
[TGProjectHandler clearCookies];
NSDictionary *params = #{#"Email": _email.text,
#"Password": _password.text,
#"IsRemember": #"true",
#"ReturnUrl": #"",
#"UserId": #0,
#"OutResponse": #0};
[_sharedHandler.requestManager POST:TGURL_LOGIN
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *e;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[operation.responseString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&e];
NSLog(#"%#\n\n%#", jsonDict, responseObject);
NSString *outResponse = responseObject[#"Object"][#"OutResponse"];
if (outResponse.integerValue == 1){
NSLog(#"login successful: %#", outResponse);
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"User_Logged_In"];
[TGProjectHandler saveCookiesToDefaults];
[self performSegueWithIdentifier:#"HomePage" sender:self];
}else
{
[[[UIAlertView alloc] initWithTitle:#"Login Failed" message:#"Invalid credentials" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[TGProjectHandler dismissHUD];
[[[UIAlertView alloc] initWithTitle:#"Login Failed" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}];
}
The service function returns UserID, but this is what I am getting in response while NSLog.
NSLog(#"%#\n\n%#", jsonDict, responseObject);
Object = {
OutResponse = 1;
ReturnUrl = "<null>";
};
Success = 1;
}
{
Object = {
OutResponse = 1;
ReturnUrl = "<null>";
};
Success = 1;
}
Why is UserId not coming in response?
By looking at your code I guess the problem might be content type in your request. Check if your content type is set properly.
For Example -
[_sharedHandler.requestSerializer setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
Also you can change response serializer to AFJSONResponseSerializerwhich will automatically convert your response to dictionary or array.
_sharedHandler.responseSerializer = [AFJSONResponseSerializer serializer];
i'm new to blocks, I have a class of requests with static methods to call me back on UIViewControllers with some blocks
this is the method implementation :
(putting a breakpoint on the block(something) DOES stop there, like it should)
+(void)requestSuggestedLocationsForText:(NSString*)text withBlock:(void (^)(NSArray*callBackArray))block
{
if ([text isEqualToString:#""] || [text isEqualToString:#" "])
{
block(nil);
return;
}
NSString * key = #"someActualKeyHere";
;
NSString * finalText;
NSArray *tagschemes = [NSArray arrayWithObjects:NSLinguisticTagSchemeLanguage, nil];
NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagschemes options:0];
[tagger setString:text];
NSString *language = [tagger tagAtIndex:0 scheme:NSLinguisticTagSchemeLanguage tokenRange:NULL sentenceRange:NULL];
if ([language isEqualToString:#"he"])
{
finalText = [text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
else
{
finalText = [text stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
}
NSString *urlString = [NSString stringWithFormat:
#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&types=geocode&sensor=true&key=%#",finalText,key];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (!responseObject && ![responseObject respondsToSelector:#selector(dataWithData:)])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving "
message:#"ERROR"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
return ;
}
NSData * responseData = [NSData dataWithData:responseObject];
NSString *responseString = [NSString stringWithUTF8String:[responseData bytes]];
NSError *err;
if ([responseString respondsToSelector:#selector(JSONObjectWithData:options:error:)])
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&err];
NSArray * predictions = [json valueForKey:#"predictions"];
block(predictions);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
}
this is how I call it, notice the NSLog, i put a breakpoint on it and its never called
which is exactly what I want to occur.
[Requests requestSuggestedLocationsForText:text withBlock:^(NSArray *callBackArray)
{
NSLog(#"ROFL");
}];
for the record, I have tried the same method with a different signature (without the returning variable name like so :
+(void)requestSuggestedLocationsForText:(NSString*)text withBlock:(void (^)(NSArray*))block;
still didn't fire my breakpoint :(
I think that this:
if ([responseString respondsToSelector:#selector(JSONObjectWithData:options:error:)])
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&err];
NSArray * predictions = [json valueForKey:#"predictions"];
block(predictions);
}
Never runs because as far as I know, NSString doesn't declare JSONObjectWithData. Your break point will never hit because it will never be called.
It seems like it could just be:
NSData * responseData = [NSData dataWithData:responseObject];
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&err];
if (!err) {
NSArray * predictions = [json valueForKey:#"predictions"];
block(predictions);
}
else {
block(nil);
}
The other way you convert it to a string, then back to data, why not just keep it as data?
I am using AFNetworking, (AFHTTPRequestOperation) to make calls to the network and get the data back. I need to make use of the code in a for loop (enumeration of cards) to check for each card and get the data back, if the operation is successful, I get the information about the cards and if it fails, I should get an alert (using an alert view). The problem is I am getting multiple alerts if it fails (because it's inside a for loop and there can be a number of cards). How can I just show one alert only when it fails to connect to the network?
I know the operation is async, but can't get this to work.
Code below:-
- (void)verifyMobileDeviceStatus
{
[self fetchRequest];
[self.contentsArray enumerateObjectsUsingBlock:^(GCards *gCard, NSUInteger idx, BOOL * stop) {
NSURL *baseURL = nil;
baseURL = [NSURL URLWithString:BASE_URL_STRING];
NSString *soapBody = [NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?><soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header/><soapenv:Body><VerifyMobileDeviceStatus xmlns=\"http://tempuri.org/\"><Request><AuthToken>%#</AuthToken></Request></VerifyMobileDeviceStatus></soapenv:Body></soapenv:Envelope>", [gCard valueForKey:#"authToken"]];
NSLog(#" auth token =%#", [gCard valueForKey:#"authToken"]);
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:baseURL];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapBody length]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[soapBody dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[request addValue:#"http://tempuri.org/VerifyMobileDeviceStatus" forHTTPHeaderField:#"SOAPAction"];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", operation.responseString);
NSString *xmlString = [operation responseString];
[parser setGCard:gCard];
[parser parseXML:xmlString];
if([gCard.merchantStatus isEqualToString:MERCHANT_STATUS_ACTIVE])
{
gCard.isPremiumAccount = [NSNumber numberWithInt:1];
}
else
{
gCard.isPremiumAccount = [NSNumber numberWithInt:0];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[parser.delegate verifyDeviceStatusParserDidFailWithError:#"Error"];
NSLog(#"error: %#", [error userInfo]);
}];
[operation start];
}];
}
- (void)verifyDeviceStatusParserDidFailWithError:(NSString *)error
{
NSString *errorString = [NSString stringWithFormat:#"Error =%#", [error description]];
NSLog(#"Error parsing XML: %#", errorString);
BlockAlertView* alert = [BlockAlertView alertWithTitle:#"Connection Failed" message:#"Connection to web service Failed. Please try again."];
[alert addButtonWithTitle:NSLocalizedString(#"OK", nil) block:^{ }];
[alert show];
[activityIndicator stopAnimating];
self.navigationController.view.userInteractionEnabled = YES;
}
It's showing the alert multiple times, if it fails and I need to show it only once.
Any help would be appreciated.
You need to make the alert view a property of the class, so.
1 - Declare a property (alert) of type BlockAlertView in the class that make the multiple requests (let's call it RequesterClass). This property will reference an unique alert view, which will be displayed only once.
2 - Put this 2 lines in the init method of the RequesterClass
_alert = [BlockAlertView alertWithTitle:#"Connection Failed" message:#"Connection to web service Failed. Please try again."];
[_alert addButtonWithTitle:NSLocalizedString(#"OK", nil) block:^{ }];
3 - Modify the verifyDeviceStatusParserDidFailWithError: as follows:
- (void)verifyDeviceStatusParserDidFailWithError:(NSString *)error
{
NSString *errorString = [NSString stringWithFormat:#"Error =%#", [error description]];
NSLog(#"Error parsing XML: %#", errorString);
if(!alert.visible)
{
[alert show];
}
[activityIndicator stopAnimating];
self.navigationController.view.userInteractionEnabled = YES;
}
Hope it helps!