first I'd like to say that the issue I am having is in regards to how my own code is set, not IOS or AFNetworking.
I am going to show 1 example where a view is not refreshing immediately even though the updated JSON response object from the server is being recieved.
There are 2 views being used in the first view the button below takes the user to a second view where he can upload an image that will then be displayed in the first view.
- (IBAction)editImage:(id)sender {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
TDUserProfileViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"TDUserProfileImageEditViewController"];
[self.navigationController pushViewController:vc animated:YES];
}
Below is the code that uploads the new data to the server and then gets new data regarding the images's address on the server.
- (IBAction)dataSubmitToServer{
// NSLog(#"photo: %#", self.photoData);
NSString * userID = [[NSUserDefaults standardUserDefaults] objectForKey:USERID];
//make the call to the web API
NSString* command = #"setProfilePhoto";
self.params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, #"command", userID, #"userid", nil];
//////////////////
NSLog(#"%#", self.params);
self.photoName = #"newname.png";
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:BaseURLString parameters:self.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(self.userPhoto.image, 1)
name:#"image"
fileName:self.photoName
mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
[TDPublicFunctions showDefaultAlert:#"Error" body:[error description]];
}];
[self getNewProfileData];
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void)getNewProfileData{
/*start getting new data for profile pic and status message*/
NSString* command = #"displayProfileData";
NSString * userID = [[NSUserDefaults standardUserDefaults] objectForKey:USERID];
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, #"command", userID,#"userid", nil];
NSLog( #"%#", params);
[SVProgressHUD showWithStatus:#"Loading..." maskType:SVProgressHUDMaskTypeBlack];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:BaseURLString parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
[SVProgressHUD dismiss];
if([responseObject objectForKey:#"error"])
{
[[[UIAlertView alloc] initWithTitle:#"Data Retrieval Error" message:[responseObject description] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] show];
}
else
{
NSString * profilePhoto = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"profile_picture"];
NSString * status = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"status"];
NSString * statusMsg = [[[responseObject objectForKey:#"result"] objectAtIndex:0] objectForKey:#"status_message"];
if(profilePhoto && ![profilePhoto isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:profilePhoto forKey:PROFILE_PHOTO];
if(status && ![status isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:status forKey:STATUS];
if(statusMsg && ![statusMsg isKindOfClass:[NSNull class]])
[[NSUserDefaults standardUserDefaults] setObject:statusMsg forKey:STATUS_MESSAGE];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
//end of getting data for status message and profile pic
}
Now once this above process is over the HUD is supposed to stop and when the back button on the view is hit there should be a newly uploaded image in the first view. The code below is the last of many things that I have tried in order to get the view with the image to refresh:
-(void) viewWillAppear:(BOOL)animated
{
NSString * profPic = [[NSUserDefaults standardUserDefaults] objectForKey:PROFILE_PHOTO];
NSLog(#"profilepic: %#", profPic);
// NSString* status = [[NSUserDefaults standardUserDefaults] objectForKey:STATUS];
NSString * statusMsg = [[NSUserDefaults standardUserDefaults] objectForKey:STATUS_MESSAGE];
if(profPic)
[photo loadIconForProduct:profPic];
if(statusMsg)
statusMsgView.text = statusMsg;
//self.view=nil;
//[self viewDidLoad];
[self getFriendsList];
[photo setNeedsDisplay];
[self.view setNeedsDisplay];
}
After an image is uploaded it may work the first time an image is uploaded but it does not work if the user were to press the editImage button a second time and upload another image.
What is it that is being done wrong? Let me know if there is anything else that I can supply.
Thanks.
As I can see here, you are getting a URL back as the result of the profilePhoto. So you might as well use the AFNetworking function:
Im presuming photo is a UIImageView.
[photo setImageWithURL:[NSURL URLWithString:profPic] placeholderImage:[UIImage imageNamed:#"somePlaceholderImage"]];
Related
Please, I need help ;
in my ios app, user can create an account by editing a password;
but when this happens I am getting HTTP status 400
I am trying to post the data on the server which asks for JSON format
Here's what I am doing
NSLog(#"user_id: %#", user_id);
NSString *oldPassword = self.txt_mdpss.text ;
NSString *txtmdpss = self.txt_nv_mdpss.text ;
strUrl = [NSString stringWithFormat:#"https://mysite/wp-json/api/v1/user/editpasswd?user_id=%#&old_passwd=%#&new_passwd=%#",user_id,oldPassword,txtmdpss];
strUrl = [strUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[manager GET:strUrl parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
[SVProgressHUD dismiss];
NSLog(#"REPOONSE EDITER MOT DE PASSE = %#", responseObject );
if ([responseObject isKindOfClass:[NSArray class]]) {
NSMutableArray *responseArray = responseObject;
} else if ([responseObject isKindOfClass:[NSDictionary class]]) {
NSDictionary *responseDict = responseObject;
NSLog(#"-------------------> Response Editer Profile = %#",responseObject);
//NSString *strIDUser = [[NSString alloc] initWithFormat:#"%#",[responseDict objectForKey:#"user_id"]];
[self dismissViewControllerAnimated:YES completion:nil];
[[NSUserDefaults standardUserDefaults] setObject:#"no" forKey:#"isConnectedFromFB_notHavePsswd"];
Is there any way that I can print/NSLOG the string or the array that is being returned by the API in this following login code of mine:
-(void)loginToAPI:(NSString *)email password:(NSString *)password {
NSString *controller = #"login";
NSString *action = #"authenticate";
NSDictionary *params = #{#"username": email,
#"userpass": password,
#"controller": controller,
#"action": action,
#"app_id": APP_ID,
#"app_key": APP_KEY};
NSLog(#"params %#", params);
if ([self isNetworkAvailable]) {
AFHTTPRequestOperationManager *client = [AFHTTPRequestOperationManager manager];
client.responseSerializer.acceptableContentTypes = [client.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
[client POST:[[Config sharedInstance] getAPIURL]
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *jsonObject= responseObject;
NSString *status = [jsonObject objectForKey:#"status"];
NSLog(#"Request Successful, response '%#'", jsonObject);
if ([status isEqualToString:#"success"]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *data = [jsonObject objectForKey:#"data"];
NSDictionary *userDict = [data objectForKey:#"user"];
NSDictionary *djsaDict = [data objectForKey:#"djsa"];
User *currentUser = [[User alloc] initWithProperties:userDict];
[currentUser save];
DJSA_Cutomer *djsa = [[DJSA_Cutomer alloc] initWithProperties:djsaDict];
NSData *userData = [NSKeyedArchiver archivedDataWithRootObject:currentUser];
NSData *djsaData = [NSKeyedArchiver archivedDataWithRootObject:djsa];
[userDefaults setObject:userData forKey:#"currentUser"];
[userDefaults setObject:djsaData forKey:#"djsa_customer"];
[userDefaults synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName: #"LOGIN_SUCCESS" object:currentUser userInfo:nil];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName: #"LOGIN_FAILED" object:nil userInfo:nil];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request Failed with Error - loginToAPI: %#, %#", error, error.userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName: #"SERVER_ERROR" object:nil userInfo:nil];
}];
}
}
It is always failing and going to the part "Request Failed with Error - loginToAPI". Is it possible to see the actual values returned by the server so I can diagnose the problem?
Thanks!
I had the same problem. The solution to it in my case was
client.responseSerializer = [AFHTTPResponseSerializer serializer];
I did that but I was still getting same error. The problem was that I was setting client.requestSerializer instead of client.responseSerializer. Small mistakes but takes lot of time.
You can get the status code off the response property from the operation object which should give you some idea of what went wrong:
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request Failed with Error - loginToAPI: %#, %#", error, error.userInfo);
NSLog(#"%#", [NSHTTPURLResponse localizedStringForStatusCode:operation.response.statusCode]);
[[NSNotificationCenter defaultCenter] postNotificationName: #"SERVER_ERROR" object:nil userInfo:nil];
}];
Otherwise, it's best to use a tool like Charles web proxy to inspect the actual request and response. It has a free trial which should be sufficient to do what you need, and is relatively easy to set up.
Replace this line:
client.responseSerializer.acceptableContentTypes = [client.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
with this:
[client.securityPolicy setValidatesDomainName:NO];
[client.securityPolicy setAllowInvalidCertificates:YES];
client.responseSerializer = [AFHTTPResponseSerializer serializer];
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 need fetch data from server in background mode ios. but when i run app in background, didReceiveData method never called. in foreground it work fine.
when app run in background then app request data from applicationDidEnterBackground method. i cannot why didReceiveData method not call.
please help me!
i use this way may help you..
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setObject:string forKey:#"data"];
[dic setObject:ADDD_DATA_UPGRADE forKey:#"cn"];
[dic setObject:#"true" forKey:#"mode"];
[self login:dic];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
});
});
}
-(void)login:(NSDictionary*)dic
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:UPDATION_ON_SERVER_TIME];
SAAPIClient *manager = [SAAPIClient sharedClient];
[[manager responseSerializer] setAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
[manager postPath:#"" parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject)
{
if([[responseObject objectForKey:#"status"] boolValue])
{
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
[self parseResponseFromJson:responseObject];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:UPDATION_ON_SERVER_TIME];
NSLog(#"Success: %# ***** %#", operation.responseString, error);
}];
I am working on afnetworking, i have web service that takes too much time to load data and i want that UI do not freeze, i used this tutorial to run webservice on background so that i can work on other views as well, but not sucess till yet.
-(void) getArticles :(NSString*)stateAbbre completionHandler:(void (^)(id array))success
{
[MyCommonFunctions showGlobalProgressHUDWithTitle:#"Loading"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *link = [NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/depilexs/get_articles_ios.php"];
NSLog(#"%#",link);
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
[manager GET:link parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSDictionary *returnedDealDict = responseObject ;
NSArray *returnArray = [returnedDealDict objectForKey:#"Result"];
for(NSDictionary *dealDict in returnArray)
{
ArticlesDC *articles = [[ArticlesDC alloc] init];
articles.articlesID = [[dealDict objectForKey:#"id"]intValue ];
articles.articleTitle = [dealDict objectForKey:#"title" ];
articles.articleDetail = [dealDict objectForKey:#"details" ];
articles.articleDate = [dealDict objectForKey:#"date" ];
articles.articlePic = [dealDict objectForKey:#"pic" ];
articles.articleThumbPath = [dealDict objectForKey:#"thumb_path" ];
articles.articleStatus = [dealDict objectForKey:#"status" ];
[dataArray addObject:articles];
[MyCommonFunctions dismissGlobalHUD];
}
success(dataArray);
// [MBProgressHUD hideHUDForView:self.view animated:YES];
if (dataArray.count == 0)
{
ALERT_VIEW(#"Please check your internet connection.");
// [MBProgressHUD hideHUDForView:self.view animated:YES];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
ALERT_VIEW(#"Error occured while loading data.");
// [MBProgressHUD hideHUDForView:self.view animated:YES];
}];
}
and in my view did load method
[self getArticles:nil completionHandler:^(id array) {
articlesArray = array;
[tblView reloadData];
for (ArticlesDC *article in articlesArray)
{
NSString *stringWithoutSpace = [[NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/admin/%#", article.articleThumbPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: stringWithoutSpace]];
UIImage *imgOne = [UIImage imageWithData:imageData];
NSString *stringforImg = [[NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/admin/%#", article.articlePic] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imageDta = [NSData dataWithContentsOfURL:[NSURL URLWithString: stringforImg]];
UIImage *imgTwo = [UIImage imageWithData:imageDta];
[dbHandler insertArticlesIntoSqlite:article.articleTitle andDetail:article.articleDetail anddate:article.articleDate andImage:[MyCommonFunctions saveImageInDocuments:imgTwo] andThumb:[MyCommonFunctions saveImageInDocuments:imgOne]];
[defaults setInteger:1 forKey:#"getArticlesOffline"];
[defaults synchronize];
}
}];
The problem is not AF, it's that at the end of that process you call dataWithContentsOfURL twice and this runs directly on the main thread to download some images. You need to move that download to a background thread.