afnetworking cache request to disc - ios

I'm currently using the code below to load data from a webservice (over https).
I need a way to cache this data to disc.
Ideally the flow would be like this.
Has data loaded?
If no - read from cache
If no internet connection - read from cache
If yes - continue as normal
How would this be possible?
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"someurl" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//NSLog(#"Error: %#", error);
}];

To write the data to a file, you could NSJSONSerialization to convert your response object into NSData, then save the data to a file:
NSString* filePath [NSTemporaryDirectory() stringByAppendingPathComponent:#"someFile.json"];
NSData* data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
[data writeToFile:filePath options:0 error:nil];
Then, before you make the request, check if the file exists and read from it instead of doing your request:
NSData* jsonData = [NSData dataWithContentsOfFile:filePath];
if(jsonData == nil){
// Perform network request
}else{
id responseObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
}

Related

AFHTTPRequestOperationManager request returns nil while it returns data on browser

{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
NSString *encodedString = [#"http://public.dawanda.in/category.json" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[manager GET:encodedString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"responseobj %#",responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"RESPONSE: %#", operation.responseString);
NSLog(#"Error: %#", [error debugDescription]);
NSLog(#"Error: %#", [error localizedDescription]);
}];
}
The JSON is invalid and can't be parsed, if you run the code below you will see the error object states:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Unable to convert data to string around character 1451.) UserInfo=0x7f83dea007a0 {NSDebugDescription=Unable to convert data to string around character 1451.}
NSString *urlString = #"http://public.dawanda.in/category.json";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
NSError *jsonError = nil;
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
NSLog(#"error: %#", jsonError);
}
}];
[dataTask resume];
yes Json is invalid but i just found an answer with type of encoding
NSError *error = nil;
NSString *JsonString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];//NSASCIIStringEncoding to work round invalid special charcter
NSData *objectData = [JsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&error];

How to use AFNetworking to create JSON array

I am currently trying to create a JSON array like I do here like this:
NSURL *url = [NSURL URLWithString:currentJSON];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
if (jsonData) {
result = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&error];
}
Which works fine. Apart from I want it to time out if the internet connection is not great.
So I then wen to AFNetworking where I wrote code like this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:currentJSON parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSError *error = nil;
result = [NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingMutableContainers
error:&error];
[[NSUserDefaults standardUserDefaults] setObject:result forKey:#"All"];
[[NSUserDefaults standardUserDefaults] synchronize];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
result = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"All"];
}
But this method always runs to a failure How come? What am I doing wrong?
Check that server is sending JSON using correct content type 'application/json'. AFNetowrking checks this out of the box and if receives something else (for example 'text/html'), failure block will be called.
Also AFNetworking does JSON to object parsing out of the box. 'id responseObject' is already the result of '[NSJSONSerialization JSONObjectWithData]'.
If you can't change content type sent by server, you could add that content type to accepted types using following snippet
NSMutableSet *accepted = [NSMutableSet set];
[accepted addObject:#"text/html"];
[accepted addObject:#"application/json"];
manager.responseSerializer.acceptableContentTypes = accepted;
Try this :
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) {
result = (NSDictionary *)responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
[operation start];

How to add some parameters to a JSON request?

Usually, to download a JSON, I use AFNetworking creating a singleton with this code
- (void)getJSON {
NSURLRequest * request =
[NSURLRequest requestWithURL:
[NSURL URLWithString:#"http://URL"]];
AFJSONRequestOperation * operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSArray * js = JSON;
[_delegate dati:js];
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * filePath = [[paths lastObject] stringByAppendingPathComponent:#"downloaded.json"];
NSData * data = [NSJSONSerialization dataWithJSONObject:JSON
options:NSJSONWritingPrettyPrinted
error:NULL];
[data writeToFile:filePath
atomically:YES];
}];
[operation start];
}
and calling this code in View Controller
[[DataManager sharedClass] getJSON];
and it works, but now I need to send (post) some parameters (as an authorization code, GPS coordinates, user's mail or something similar) into the request to the server to receive a specific JSON. Server is already configured and it works fine, but I can't find a guide to modify my code to do that. Does somebody knows how to proceed?
This is an example of posting data to server using JSON, for example the json is below:
NSDictionary *json = #{#"authorization_code": yourAuthorizationCode,#"gps": #{#"lat": latitude,#"lng": longitude},#"email":email};
JSON Posting
Posting on server depends also on your server requirements, so if it requires a JSON to post, this is the way:
//Create an AFHTTPRequestOperationManager
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//Depending if you need a HTTP header, you create one
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSString *yourAuthorizationCode;
NSString *latitude;
NSString *longitude;
NSString *email;
//My data to be posted via JSON
NSDictionary *json = #{#"authorization_code": yourAuthorizationCode,#"gps": #{#"lat": latitude,#"lng": longitude},#"email":email};
//Sending Post Method, with parameter JSON
[manager POST:#"http://myphp.com/api/v1/profile" parameters:json success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error at creating post: %#", error);
}];
Parameters posted via URL
In this method parameters are passed in URL, and you post them to server in URL form
//Create an AFHTTPRequestOperationManager
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *yourAuthorizationCode;
NSString *latitude;
NSString *longitude;
NSString *email;
//Sending Post Method, with parameter JSON (You can change your method of sending data to server just by replacing POST with GET)
[manager POST:[NSString stringWithFormat:#"http://myphp.com/api/v1/profile?authorization_code=%#&gps_lat=%#&gps_lng=%#&email=%#",yourAuthorizationCode,latitude,longitude,email] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error at creating post: %#", error);
}];
Hope it helps, give me feedback!

How can i identify session timeout in AFNetworking 2.0?

i am creating an object of AFHTTPRequestOperationManager *manager
NSString *BaseURLString = #"http://192.168.1.202:81//CredentialsModule/CredentialService.asmx/details";
AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];
[manager POST:BaseURLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
NSDictionary *jsonDict = (NSDictionary *) responseObject;
NSString *products = [jsonDict objectForKey:#"d"];
NSLog(#"pro %#",products);
NSString *newString = [NSString stringWithFormat:#"%#",products];
NSData* data = [newString dataUsingEncoding:NSUTF8StringEncoding];
NSError* error;
id jsonObjects = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"user id %#",jsonObjects);
[self.navigationController pushViewController:CategoryViewController animated:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"\n Error2: %ld",(long)operation.response.statusCode);
NSLog(#"\n Error2: %#", operation.responseString);
}];
suppose i am calling above web service and my session is timeout.So,i want to know is there any chance to identify session timeout before calling the service in afnetworking 2.0.
Please don't try to run web service it won't work because its on local server !!

add nsmutablearray as parameter in afnetworking

i am trying to send nsmutablearray as one parameter of dictionary e.g
NSMutableDictionary* dicUsers = [NSMutableDictionary dictionary];
[dicUsers setValue:txtTitle.text forKey:#"task_title"];
[dicUsers setValue:txtVDetail.text forKey:#"task_detail"];
[dicUsers setValue:myArray forKey:#"assign_to"];
AFHTTPClient *httpClient= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",SERVER_PATH]]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient postPath:#"Task/addTask" parameters:dicUsers success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
NSLog(#"%#",dic);// NULL RESPONSE
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#",error);
}];
sending by post method but cant get the array so how i send the array as one parameter
If you would have a look at the error of [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; you probably would get your answer:
responsObject is not a NSData objects. It is either an NSArray or an NSDictionary, as it is already the serialised object.

Resources