Does an iOS http 'get' have a URL length limit - ios

I'm trying to do a simple get in iOS (Objective C) using a simulator and not a real device.
NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:theGetURL]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
[newRequest setHTTPMethod: #"GET"];
NSError *requestError2;
NSURLResponse *urlResponse2;
NSData *response2 = [NSURLConnection sendSynchronousRequest:newRequest returningResponse:&urlResponse2 error:&requestError2];
NSString* secondResponse = [[NSString alloc] initWithData:response2 encoding:NSUTF8StringEncoding];
NSLog(#"error = %#",requestError.localizedDescription);
NSLog(#"response=%#",secondResponse);
NSLog(#"url response = %#",urlResponse);
This code works perfectly when I'm passing a simple url. When I try the code with a longer (around 4000 characters) url, the code doesn't work (no error is printed).
I am aware that a post is better for this kind of thing, but my question is, is this expected from a get request?
Also, my url works perfectly in my mac and iOS browsers.

As you suspect, I think you need to consider moving to use POST rather then GET. The server side limit is 8K, however it seems this can be much less for the client side.
The following discussion sums everything up well. It also seems to imply the limit for Safari is 2K, which probably means it is the same or less for iOS, which would explain your problem with 4000 characters.
maximum length of HTTP GET request?

I think your URL query parameter might have any character that is not encoded. Try to ensure it.
For encoding you may try this code
- (NSString *)encodeQueryParameter:(NSString *)str
{
CFStringRef ref = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)str,
NULL,
CFSTR(":/=,!$&'()*+;[]##?"),
kCFStringEncodingUTF8);
NSString *result = (__bridge_transfer NSString *)ref;
return result;
}

Related

How to send the character "&" via HTTP POST to server with iOS 7?

I want to send some data via http post from my App to the server. All symbols can be accepted by the server, except the &.
the server is php;
content-type is application/x-www-form-urlencoded, and charset is utf-8.
Encoding is NSUTF8StringEncoding.
I tried also changing the & with URLEncoding, i.e. & --> %26. the server can receive it, but cannot display it recht. It's shown in %26, not &.
But, the server can properly received and displayed, if it is sent by android or web side.
The code is the following:
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"xxx.com/server.php"]];
postRequest.HTTPMethod = #"POST";
[postRequest setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *bodyString = [NSString stringWithFormat:#"data=&&&&"];
postBody = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
NSURLConnection *postConnect = [[NSURLConnection alloc]initWithRequest:postRequest delegate:self];
hope this helps you
NSString *encodedString = [myString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
It won't replace your string inline; it'll return a new string. That's implied by the fact that the method starts with the word "string". It's a convenience method to instantiate a new instance of NSString based on the current NSString.
Note--that new string will be autorelease'd, so don't call release on it when you're done with it.
It should be with the function
(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)url, NULL, (CFStringRef)#"&", kCFStringEncodingUTF8))

HTTP post w/ JSON to rails server from iOS

I have succeeded in making a post using a HTTP Client by setting the content type as application/json and this json code:
{
"order": {
"name": "Tia Carter",
"location": "Corams",
"phone_number": "707",
"food": "Bobcat Burger"
}
}
The code works perfect and the order is registered in the database. I am trying to work this into my iOS app but keep getting syntax errors regarding the colons in the json. This is the objective-c code:
NSURL *nsURL = [[NSURL alloc] initWithString:#"http://0.0.0.0:3000/orders.json"];
NSMutableURLRequest *nsMutableURLRequest = [[NSMutableURLRequest alloc] initWithURL:nsURL];
// Set the request's content type to application/x-www-form-urlencoded
[nsMutableURLRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Set HTTP method to POST
[nsMutableURLRequest setHTTPMethod:#"POST"];
// Set up the parameters to send.
NSString *paramDataString = [NSString stringWithFormat:#
"{ "order": {"%#:" ="%#","%#:"="%#","%#:"="%#","%#:"="%#"}}", #"name", _name.text, #"location", _location.text, #"phone_number", _phoneNumber.text, #"food", _order.text];
// Encode the parameters to default for NSMutableURLRequest.
NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
// Set the NSMutableURLRequest body data.
[nsMutableURLRequest setHTTPBody: paramData];
// Create NSURLConnection and start the request.
NSURLConnection *nsUrlConnection=[[NSURLConnection alloc]initWithRequest:nsMutableURLRequest delegate:self];
I'd appreciate any ideas or guidance. Thanks.
I believe you have two problems:
You didn't escape quotas (put \ before all of them)
You don't need to put text "name", "location" and etc in parameters (it's not a problem per se, just a style thing)
Also, I would recommend to work with NSDictionary and convert it to JSON when you need to (it will save you a lot of nerves for unescaped quotas, missing bracket and so on).
Look this question how to convert NSDictionary to JSON:
Generate JSON string from NSDictionary in iOS

How do I strip the query (used for GET parameters) from a URL?

I'm building a small REST service to authorize users into my app.
At one point, the UIWebView I'm using to authorize the user, will go to https://myautholink.com/login.php. This page sends a JSON response with an authorization token. The thing about this page is that it receives some data via GET via my authorization form. I cannot use PHP sessions because you arrive to this page via:
header("location:https://myautholink.com/login.php?user_id=1&machine_id=machine_id&machine_name=machine_name&app_id=app_id");
Since the header function sends in headers, I cannot do a session_start(); at the same time.
I can get the UIWebView's request URL without a problem using the delegate methods:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSURLRequest *request = [webView request];
NSLog(#"%#", [[request URL] relativeString]);
if([[[request URL] absoluteString] isEqualToString:SPAtajosLoginLink])
{
//Store auth token and dismiss auth web view.
}
}
The thing is none of the NSURL methods seem to return the "clean" link without the parameters. I have looked at all the NSURL url-string related methods:
- (NSString *)absoluteString;
- (NSString *)relativeString; // The relative portion of a URL. If baseURL is nil, or if the receiver is itself absolute, this is the same as absoluteString
But absoluteString is always the full URL with the GET parameters and relativeString is always nil.
I'm scratching my head with this and I can't seem to find the solution. Any help will be appreciated.
Rather than mess about with your own string manipulation, hand off to NSURLComponents:
NSURLComponents *components = [NSURLComponents componentsWithURL:url];
components.query = nil; // remove the query
components.fragments = nil; // probably want to strip this too for good measure
url = [components URL];
On iOS 6 and earlier, you can bring in KSURLComponents to achieve the same result.
Example: http://www.google.com:80/a/b/c;params?m=n&o=p#fragment
Use these methods of NSURL:
scheme: http
host: www.google.com
port: 80
path: /a/b/c
relativePath: /a/b/c
parameterString: params
query: m=n&o=p
fragment: fragment
Or, in iOS 7, build a NSURLComponents instance, then use the methods scheme, user, password, host, port, path, query, fragment, to extract part of the URL as strings. Then build the base URL back.
NSString* baseURLString = [NSString stringWithFormat:#"%#://%#/%#", URL.scheme, ...
NSURL *baseURL = [NSURL URLWithString:baseURLString];
To update this answer for iOS 7 onwards:
NSURLComponents *components = [NSURLComponents componentsWithURL: url resolvingAgainstBaseURL: NO];
components.query = nil; // remove the query
components.fragment = nil; // probably want to strip this too for good measure
url = [components URL];
Please note also that there is no 'fragments' property. It's just 'fragment'.
Otherwise, this method is great. Much better than worrying about putting the URL back together properly with string manips.

UIWebView displays blank page on form submit

I'm an iOS newb (.NET professional), so this may be a simple issue but I couldn't find anything through the SO search or Google (and maybe not looking for the right terms).
I'm writing an app that displays information from a DD-WRT router through it's web interface. I have no problem displaying the initial page and navigating through any of the other pages, but if I make any change on a form (and it redirects to apply.cgi or applyuser.cgi), the UIWebView is blank - it's supposed to display the same page, with the form submission changes. The site works fine in Mobile Safari, which I find intriguing, but I guess UIWebView isn't totally the same.
I think the iOS code is pretty standard for display a webpage, but I'll list it below. I can't give you access to my router because, well, that's not a good idea :) Hopefully someone with a DD-WRT router can help (or know what my issue is anyway).
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *sURL = #"http://user:pass#XXX.XXX.X.X";
NSURL *url = [NSURL URLWithString:sURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
self.webView.delegate = self ;
}
And I'm doing a few things with Javascript in the webViewDidFinishLoad method, but I know that's not the culprit because it still happens when I comment it out.
Well I figured out the problem on my own. I think part of it was putting the username & password in the URL (which was just a temporary measure) because I found that method provided the same results in mobile Safari and desktop Chrome.
So I added MKNetworkKit to my project that provided a simple way to add authentication to my request, and found I had to make a specific request to POST the data, then reloaded the page the to see the changes.
In the (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType method, I check if ([request.HTTPMethod isEqualToString:#"POST"]) and do this:
NSString *sPostData = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
NSArray *aPostData = [sPostData componentsSeparatedByString:#"&"];
NSMutableDictionary *dPostData = [[NSMutableDictionary alloc] init];
//i don't know if this is the best way to set a dictionary, but it works
for (id apd in aPostData)
{
NSString *key = [apd componentsSeparatedByString:#"="][0];
NSString *val = [apd componentsSeparatedByString:#"="][1];
[dPostData setValue:val forKey:key];
}
MKNetworkEngine *engine = [[MKNetworkEngine alloc] init];
MKNetworkOperation *op = [engine operationWithURLString:[request.URL description] params:dPostData httpMethod:#"POST"];
[op setUsername:#"myUserName" password:#"myPassword" basicAuth:YES];
self.postedRequest = TRUE; //a bool I set so, when it comes to webViewDidFinishLoad, I reload the current page
[op start]; //send POST operation

Box.Net iOS SDK Moving Files and Folders

I am currently developing an iOS application and am implementing the Box.Net SDK. I have gotten everything to work except the ability to move files around, which is not a native feature of the SDK. I am trying to twist my way through it.
If you are familiar with the structure of Box.Net, each file/folder has an ID number for itself, and an ID its parent. From what I understand if I want to move a file, I am supposed to change the parent ID number on the file which will point it to the new location. I can't seem to get it to work properly though. My application seems to keep crashing.
This is what I have so far, generalized.
BoxObject *boxObject = [[[Box objectWithID:(ID#ofParent)] children] objectAtIndex:i];
[boxObject parent].boxID = 0; // <-- Problem (causes crash)
I also tried this.
[boxObject setParent:[Box folderWithID:[BoxID numberWithInt:i]]];
The boxObject variable is the file that I want to move. I am setting its parent ID equal to 0, which is supposed to be the root folder. However, my application crashes when I try to reassign the parent ID for the file. Any ideas on how to successfully move files/folders? Any help is much appreciated! Thanks in advance!
Okay. I suppose there wasn't a way to do fix this in-house with the SDK. So, I had to send out an external PUT request. I used the following code to handle moving files.
- (void)moveItem:(BoxObject *)object toParentFolderWithID:(BoxID *)parentID
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.box.com/2.0/files/%#", object.boxID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"PUT"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *auth = [NSString stringWithFormat:#"BoxAuth api_key=%#&auth_token=%#",[Box boxAPIKey],[defaults objectForKey:#"box-api-auth-token"]];
NSString *payload = [NSString stringWithFormat:#"{\"parent\": {\"id\": %#}}", parentID];
[request setHTTPBody:[NSMutableData dataWithData:[payload dataUsingEncoding:NSUTF8StringEncoding]]];
[request setValue:auth forHTTPHeaderField:#"Authorization"];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
}
Just as a reminder if you are new to the Box SDK, you will most likely need to update/refresh the data after moving the files. If not handled, your application could crash if the file doesn't exist. Hope this helps to anyone was not sure about this.

Resources