Resolve redirect of NSURL? - objective-c

I have a shortened URL (e.g. t.co/12345678). I would like to resolve the redirect without having to the load the entire page via NSURLConnection. Obviously, I can get it by sending an NSURLConnection and awaiting the response but this loads the entire page first. I am only looking for the redirect URL. Is this possible? If so, how?
=============
Edit: For posterity, here is the solution, as suggested by amleszk.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:shortenedURL
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:15.0f];
[request setHTTPMethod:#"HEAD"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSURL *resolvedURL = [httpResponse URL];
NSLog(#"%#", resolvedURL);
}];

same method as this: finding the download size of a URL (Content-Length)
but you want the [NSURLResponse statusCode] = 301/302/303 and the
Location header here: Getting "Location" header from NSHTTPURLResponse

Related

How to set http header for for HTTP in Objective-C?

I am trying to implement Http in IOS.
I use the following code to send GET command to the Server.
SERVER_IP = #"xxx.xx.xxx.xxx";
PORT = #"12345";
USER_ID = #"1234-1234-1234-1234-1234";
USER_PWD = #"123456";
url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#:%#/message/user/%#",SERVER_IP,PORT,USER_ID]];
[request setHTTPMethod:#"GET"];
request = [NSURLRequest requestWithURL:url];
NSDictionary *header = [request allHTTPHeaderFields];
[header setValue:#"Authorization" forKey:USER_PWD];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#",html);
}];
It show **The resource requires authentication, which was not supplied with the request** at the log.
I have set the parameter header , but I don't know how to use it.
Can someone help me and teach me how to implement GET command and setting password?
Use the following:
[request setValue:#"xxx" forHTTPHeaderField:#"Content-Type"];
But you have to change the NSURLRequest to NSMutableURLRequest, please check Zaph's answer
The header information is added to the URLRequest.
Create a NSMutableURLRequest and use the setValue:forHTTPHeaderField: method to add the header to the request.
There are many other setting available for NSMutableURLRequest.
You need to set the header on the NSURLRequest somehow, something like that will do.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[request setHTTPMethod:#"GET"];
[request setValue:USER_PWD forHTTPHeaderField:#"Authorization"];
Create an NSDictionary with all your header fields and use the following command to set the required headers.
NSDictionary *dictHeader = #{#"Content-Type": #"application/octet-stream",
#"Authorization": #"accessToken"};
[request setAllHTTPHeaderFields:dictHeader];

getting http headers by NSURLConnection sendAsynchronousRequest

How do I get http headers by using sendAsynchronousRequest? Notice that the target URL of the URLRequest only sets headers. When I use sendSynchronousRequest, I can get the http headers by using the NSURLHTTPResponse object. However, in sendAsynchronousRequest, there is only a NSURLResponse object. I have used the following cast strategy to convert NSURLResponse to NSURLHTTPResponse in sendAsynchronousRequest method. This however does not work, blockinkg the main thread without generating any error or exception.\
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *hResponse = (NSHTTPURLResponse*) response;
if ([hResponse respondsToSelector:#selector(allHeaderFields)]) {
NSDictionary *dictionary = [hResponse allHeaderFields];
_myHeader = [dictionary objectForKey:#"myHeader"];
}
}
If I don't use the above code, there is no blocking. I have also notice that the NSData returned by sendAsynchronousRequest hás zero length. Please help

Objective C Update RESTful Webservice

I have a web service that allows me to update records on in our database.
The columns in the table are as follows:
allowsActions
assetID
inventoryObjectID
objectDescription
quantity
retired
serialNumber
action
I'm using the following to GET data from the webservice.
NSString *urlString = [NSString stringWithFormat:#"%#", inventoryAndActionsWebservice];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
Then shoving into a dictionary like so:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSLog(#"WE HAS THE DATAS");
NSDictionary *inventory = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
// Then storing the values in CoreData here
}
}
What would be the syntax for updating the webservice? It expects an object in the body of the service call (POST).
NSMutableURLRequest let's you setHTTPBody: and setHTTPMethod:.#"POST"is the way to do a post. Most services need to know the body length and encoding set in headers. (seeaddValue:forHTTPHeaderField:`) for that.
The only reason this topic is tricky is because the developer is forced to grapple with two problems at once: what constitutes a valid request for my server, and (2) how do I form that request with iOS? Part (2) is actually pretty easy once you get a valid request.
The best way to proceed is to get an example working using curl (or something equivalent). Then move on to producing that request in iOS. If you have trouble, ask a question here of the form: "I know my server needs X, here's my code to produce X, but I'm getting this error Y".
So the syntax that I was looking for was ultimately this:
NSString *jSONString = [NSString stringWithFormat:#"{\"MediaInventoryObjectsId\":%d,\"AssetId\":%d,\"Quantity\":%d,\"SerialNumber\":\"%#\",\"Description\":\"%#\",\"AllowActions\":%d,\"Retired\":%d}",inventoryObjectId, assetID, quantity, serialNumber, description, allowActions, retired];
// Convert jSON string to data
NSData *putData = [jSONString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Instantiate a url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
// Set the request url format
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/%d", inventoryAndActionsWebservice, inventoryObjectId]]];
[request setHTTPMethod:#"PUT"];
[request setHTTPBody:putData];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
// Send data to the webservice
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

Store JSON iTunes Search API data

How can I use the iTunes search API from within iOS/Obj-c ?
I know of this link of course..
http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
I just don't understand how you use obj-c/iOS with it.
I want to be able to read the JSON results, whether they be broad or just 1 result and store the apps name (or would that be ID?), any images, rating etc in my server database (using parse.com).
How can I do that, and is that allowed by the Apple developer terms?
It looks like you just make the requests and parse the results. No auth or anything else fancy...
NSString *urlString = #"https://itunes.apple.com/search?term=jack+johnson";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
NSError* parseError;
id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
NSLog(#"%#", parse);
}
}];
The JSON parser will yield arrays of dictionaries for collection calls and (probably) dictionaries for single objects.

ASIHTTPRequest and NSURLRequest different result

I send request to some url with ASIHTTPRequest, and always get strange response with different HTML body. If i make same request from browser or from NSURLRequest class, i get correct response with correct HTML body.
//Here is code of NSURLRequest. I'm getting correct response;
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *resp = nil;
NSError *err = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &resp error: &err];
NSString *theString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(#"%#",theString);
//Here is code of ASIHTTPRequest. I'm getting different response. The html body is shorter than original and different;
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
}];
[request startAsynchronous];
I also tryed to send simple synchronous request with ASIHTTPRequest, but result the same. What it could be?
may be server have different logic for different request header