Alamofire support HTTP ETAG mechanism - swift

I cannot understand if Alamofire support HTTP ETAG.
I find this discussion https://github.com/Alamofire/AlamofireImage/issues/5
and another thread on:
NSURLCache and ETags
Previously i use AFNETWORKING 1.x with Etag and i found this lines of code:
NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
if ([self.response respondsToSelector:#selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:#"ETag"]) {
[mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:#"ETag"] forHTTPHeaderField:#"If-Range"];
}
In AFHTTPRequestOperation.h (AFNETWORKING 1.x.x)
I cannot understand if Etag automatically work with url cache policy:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval:60];
Or in another way..
I'm just a little bit confused..

Related

How to send HTTP POST request with gziped content?

I'm developing iPhone app and manually constructing POST requests. Currently, need to compress JSON data before sending it, so looking how to tell a server the content is compressed. Setting content type header to gzip might be not acceptable because server expects JSON data. I'm looking for transparent solution, something like just to add some header telling JSON data is compressed into gzip.
I know, the standard way is to tell the server that the client accepts encoding, but you need to make GET request with accept encoding header first. In my case, I want to post the data already encoded.
Include a Obj-C gzip wrapper, for example NSData+GZip, and use it to encode the body of your NSURLRequest. Also remember to set the Content-Encoding accordingly, so the webserver will know how to treat your request.
NSData *requestBodyData = [yourData gzippedData];
NSString *postLength = [NSString stringWithFormat:#"%d", requestBodyData.length];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"gzip" forHTTPHeaderField:#"Content-Encoding"];
[request setHTTPBody:requestBodyData];
Implmenting some general Method such as follows and setting appropriate Header might help you.
// constructing connection request for url with no local and remote cache data and timeout seconds
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:callingWebAddress]];// cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:timoutseconds];
[request setHTTPMethod:#"POST"];
NSMutableDictionary *headerDictionary = [NSMutableDictionary dictionary];
[headerDictionary setObject:#"application/json, text/javascript" forKey:#"Accept"];
[headerDictionary setObject:#"application/json" forKey:#"Content-Type"];
//Edit as #centurion suggested
[headerDictionary setObject:#"Content-Encoding" forKey:#"gzip"];
[headerDictionary setObject:[NSString stringWithFormat:#"POST /Json/%# HTTP/1.1",method] forKey:#"Request"];
[request setAllHTTPHeaderFields:headerDictionary];
// allocation mem for body data
self.bodyData = [NSMutableData data];
[self appendPostString:[parameter JSONFragment]];
// set post body to request
[request setHTTPBody:bodyData];
NSLog(#"sending data %#",[[[NSString alloc] initWithData:bodyData encoding:NSUTF8StringEncoding]autorelease]);
// create new connection for the request
// schedule this connection to respond to the current run loop with common loop mode.
NSURLConnection *aConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//[aConnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
self.requestConnenction = aConnection;
[aConnection release];

cachedResponseForRequest method not being accessed

I am trying to set up a cache, however the method I am using 'as below' is not being accessed by the thread.
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
I am initializing the connection like this, and connectionDidFinishLoading is accessed so I am not sure what I am missing.
- (IBAction)searchRequest:(NSData *)postBodyData
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:#"https://127.0.0.1:88"];
NSURL *url = [NSURL URLWithString:databaseURL];
NSString *postLength = [NSString stringWithFormat:#"%d", [postBodyData length]];
//SynchronousRequest to grab the data, also setting up the cachePolicy
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0]; //if request dose not finish happen within 60 second timeout.
// NSInputStream *fileStream = [NSInputStream inputStreamWithData:postBodyData];
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/octet-stream" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:postBodyData];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [NSMutableData data];
} else {
// Inform the user that the connection failed from the connection:didFailWithError method
}
}
any help would be appreciated.
connection:willCacheResponse: is only called in cases when the response will be cached. POST requests are not cacheable in most cases. (More details: Is it possible to cache POST methods in HTTP?)
You should probably look at something like MKNetworkKit which handles a lot of this kind of caching, particularly for REST protocols.
You can also look at Drop-in offline caching for UIWebView. You'd have to modify it significantly, but NSURLProtocol can be used to solve this kind of problem. AFCache is currently working to integrate this approach, and is another toolkit to consider. (Read through the comments in the blog post for more background on the issues.)

How to use authentication token in NSURLRequest

I'm using a service with REST API, which provides me an authentication token as the response for the sign in POST request.
Now for authentication on every request i need to send that token with the request.
How to use this token with every request i send to server ???
I'm not totally sure what you need from your question, but here is a guess.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://rest.u.rl/do/this"];
NSString *header = [NSString stringWithFormat:#"%#",token]; //format as needed
[request setValue:header forHTTPHeaderField:#"TokenFieldName"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
[request setHTTPMethod: #"POST"];
And to do this for every other one, do a if (i % 2 == 0) or something to that effect.

Specifying HTTP referer in embedded UIWebView

In my app, I allow the user to open up an external page in an embedded UIWebView. Is it possible for me to set the referer header that's sent with that request? I'd like for my app to get the 'cred' when the user opens up these external pages.
Set the referer using - setValue:forHTTPHeaderField:
NSMutableURLRequest* request = ...;
[request setValue:#"https://myapp.com" forHTTPHeaderField: #"Referer"];
But note that according to the HTTP RFC you shouldn't, because your app is not addressable using a URI:
The Referer field MUST NOT be sent if the Request-URI was obtained
from a source that does not have its own URI, such as input from the
user keyboard.
... unless you are using a custom protocol binded to your app (myapp://blah.com/blah).
You can create one and call loadRequest: manually or intercepting a normal request made by the user.
- (BOOL) webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType) navigationType
{
NSDictionary *headers = [request allHTTPHeaderFields];
BOOL hasReferer = [headers objectForKey:#"Referer"]!=nil;
if (hasReferer) {
// .. is this my referer?
return YES;
} else {
// relaunch with a modified request
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *url = [request URL];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"GET"];
[request setValue:#"https://whatever.com" forHTTPHeaderField: #"Referer"];
[self.webView loadRequest:request];
});
});
return NO;
}
}
I haven't used this myself, but it looks like NSURLProtocol is the approved way to intercept and modify URL requests. Here's a tutorial: http://www.raywenderlich.com/59982/nsurlprotocol-tutorial
I'm using your solution of casting the request to NSMutableURLRequest, but since it's not documented that this is a mutable request, there's some risk that Apple might use an immutable object in the future.

NSURLConnection or NSurl?

what is the difference between NSURLConnection and NSURL?
i mean if i am downloading a file, does it make and difference which one i use?
Rgds
for:
NSString *myUrl = #"http://www.test.com/";
NSString *returnData = [NSString stringWithContentsOfURL:[NSURL URLWithString: myUrl]];
or
NSString *myUrl = #"http://www.test.com/";
NSURLRequest *myRequest = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString:myUrl] ];
NSString *returnData = [NSURLConnection sendSynchronousRequest:myRequest returningResponse: nil error: nil ];
whats the difference?
thks
The Connection
An NSURLConnection object provides support to perform the loading of a URL request.
The Request
NSURLRequest objects represent a URL load request in a manner independent of protocol and URL scheme.
E.g. requestWithURL:
Creates and returns a URL request for a specified URL with default cache policy and timeout value.
+ (id)requestWithURL:(NSURL *)theURL
The URL
The NSURL class provides a way to manipulate URLs and the resources they reference. NSURL objects understand URLs as specified in RFCs 1808, 1738, and 2732. ...
To get the contents of a URL, NSString provides stringWithContentsOfURL: and NSData provides dataWithContentsOfURL:.
References:
NSURLConnection_Class/Reference/Reference.html
NSURL_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSURL
Best thing about NSURLConnection is its asynchronous behaviour so that you dont have to wait until the url is loaded.