I'm trying to get a JSON file from a server then display it in a table, this works fine, however, for some reason AFNetworking is caching the JSON file even after a app restart.
How can I disable this?
NSURL *url = [NSURL URLWithString:#"http://?json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation
JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id responseObject)
{
self.dataget = [responseObject objectForKey:#"data"];
[self.tableView reloadData];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id responseObject)
{
[HUD hideUIBlockingIndicator];
}];
[operation start];
The json file is probably not cached server side:
Cache-Control: no-cache[CRLF]
Cache behavior can be set on NSMutableURLRequest objects, with setCachePolicy:. Otherwise, the built-in shared NSURLCache will respect the caching behavior defined by the server (which I would recommend tuning and taking advantage of, rather than outright disregarding).
AFNetworking doesn't do any caching. Also, the "Cache-Control" HTTP header tells the client not to cache the page (ie. AFNetworking), not the server.
It sounds like your server is caching the JSON page.
AFNetworking doesn't cache anything. You should probably check the cache control headers of the response. If i am not wrong then your server is sending some cache control headers which NSUrlConnection is taking into consideration. I would recommend you to set the caching policy of NSURLRequest to NSURLRequestReloadIgnoringLocalCacheData before making request to server
Related
I'm working on an iOS app using OAuth2 authentication.
I'm authenticated, I have no problem requesting my API, but I'm facing a problem when trying to download some files from protected URLS.
I'm using downloadTaskWithRequest from AFURLSessionManager (AFNetworking). It returns always an error 401 (not authorized) as if I was not logged in.
I can access this URL with no problem if I use the GET method, but I would like to use downloadTaskWithRequest because it permits me to have a progress indicator.
Here's my code (which isn't working):
NSURLSessionDownloadTask *downloadTask = [apiC downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *dstPath = [NSURL fileURLWithPath:dstFilePath];
return dstPath;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
// HERE I HAVE A 401
}];
Here's my code that does work:
[[OEOApiClient sharedClient] GET:url parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
// SUCCEDD !!
} failure:^(NSURLSessionDataTask *task, NSError *error) {
}];
Does downloadTaskWithRequest not support authentication? Am I doing something wrong?
OK, I was creating my request the wrong way :
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
this was the good way :
NSURLRequest *request = [mySessionManager.requestSerializer requestWithMethod:#"GET" URLString:url parameters:nil error:&serializationError];
The request you're creating and passing to downloadTaskWithRequest:… is different from the one generated by your request serializer in GET:parameters:….
Look at the implementation of GET:parameters:… to learn how AFNetworking generates requests using request serializers. Then use the same code to make an authenticated request object to pass to downloadTaskWithRequest:….
iOS client:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"host/json/demo.json"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Nginx conf on server:
location /json {
alias /var/www/json;
expires 30s;
}
First time I run the app and get json data from server correctly, then I modify the demo.json on server, restart the app, I still get old json data(even 30 second later), but using CURL commend in terminal I can get new json data.I delete the app and reinstall it then I get new json data.
Any problem with my conf or code?
Your server's response to your GET request contains cache-control HTTP headers, causing the foundation URL loading system to cache your request. See the NSURLCache Class Reference (and this NSHipster article about it) to learn more.
During debug, you could temporarily disable the cache:
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0
diskCapacity:0
diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
But this is absolutely not recommended for use in most production apps, since caching is very important to network performance on mobile devices.
If there are specific resources that should not be cached, the server should indicate these using the cache-control headers.
The method GET:parameters:success:failure is always using cache by default, so I changed to use custom AFHTTPRequestOperation without cache, like this:
NSURL *URL = [NSURL URLWithString:filePath];
NSMutableURLRequest *request = [[NSURLRequest requestWithURL:URL] mutableCopy];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
[[NSOperationQueue mainQueue] addOperation:op];
I am using AFNetworking to get JSON data from the server, but I am only getting back HTML and an error that says the following:
Expected content type {(
"text/json",
"application/json",
"text/javascript"
)}, got text/html, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x7592470>}
The code is as follows:
NSURL *url = [NSURL URLWithString:#"http://127.0.0.1:3000/games"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation;
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *req, NSHTTPURLResponse *response, id jsonObject){
NSLog(#"Response: %#", jsonObject);
}
failure:^(NSURLRequest *req, NSHTTPURLResponse *response, NSError *error, id jsonObject){
NSLog(#"Error: %#", error);
}];
[operation start];
I am using rails and the server sends back JSON when I access the page with curl. I want to force application/json to be requested, am I doing this wrong?
You probably need to tell the server what content type you want back.
Here's a common fix for this issue:
NSURL *url = [NSURL URLWithString:#"http://127.0.0.1:3000/games"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
If this doesn't work, you'll need to step through your server code to determine under what conditions it'll return JSON instead of HTML.
I have the following code for JSON Parsing:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.dropbox.com/s/qz16qyi3julygl9/facebook.json"]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"Request Success %#",[JSON class]);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failure Because %#",[error userInfo]);
}];
[operation start];
but I have Request Failure with the following error message:
NSErrorFailingURLKey = "https://www.dropbox.com/s/qz16qyi3julygl9/facebook.json";
NSLocalizedDescription = "Expected content type {(\n \"text/json\",\n \"application/json\",\n \"text/javascript\"\n)}, got text/html";
can somebody help me?
In my errorlog it prints "got text/html". So just add
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]]
It works.
[AFJSONRequestOperation addAcceptableContentTypes:#"text/plain"]
The above is deprecated from AFNetworking 2.x. Instead you can call the following on the instance of the AFHTTPRequestOperation as follows
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
Where manager is your instance of AFHTTPRequestOperation.
Source: https://github.com/AFNetworking/AFNetworking/issues/1381
Because the link you provide doesn't hotlink the file. It links to an HTML page to download the file. Try going there in a browser...
Try this link instead: https://dl.dropbox.com/s/qz16qyi3julygl9/facebook.json?dl=1 No guarantees it will work though. A lot of companies frown on directly linking to files in this way.
I have just started using AFNetworking, but I can't seem to figure out how to get the following to work.
My URL points to a PHP file which has printed out data it retrieved from a database as JSON, but with AFNetworking I get the "Expected Content Type" error.
My code is the following but with a different URL.
NSURL *url = [NSURL URLWithString:#"http://www.example.com/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation
JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id json) {
NSLog(#"JSON: %#", [json valueForKeyPath:#"results"]);
} failure:nil];
[operation start];
I figured it out! :D
<?php header("Content-type: text/json"); ?>
Put this at the top of your page before anything is printed on the screen and AFNetworking will recognise it as JSON
#Ashley Thanks for sharing this. I had the same problem and this resolved it. However it should be
header("Content-type: application/json");
and not as you state