URL Query item from NSURLComponents are nill - ios

I am creating a NSURL URL will contain some escape character (Japanese)
NSString* currentlocationbarString = #"mbos.help.jp/search?q=専門&pg=1"
NSString *escapedString = [currentlocationbarString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSURL* url = [NSURL URLWithString:escapedString];
//url is mbos.help.jp%2Fsearch%3Fq=%E5%B0%82%E9%96%80&pg=1
When I create NSURLComponents and try to get query items it gives me nil.
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:YES];
NSArray *queryItems = urlComponents.queryItems;
//here issue with queryItems
if anybody has solution to get query items please help. Thanks in advance

Issue is not with Unicode Characters, whenever you add encoding use proper character set for my case I was using following setURLHostAllowedCharacterSet it means your NSURLComponents only give encoding for your Host, to get correct queryItems use URLQueryAllowedCharacterSet like this way.
NSString* currentlocationbarString = #"mbos.help.jp/search?q=専門&pg=1"
NSString *escapedString = [currentlocationbarString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL* url = [NSURL URLWithString:escapedString];
So now you can get queryItems.
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:YES];
NSArray *queryItems = urlComponents.queryItems;

At least one of the characters 専門 that you use in your search string is invalid Unicode in the form of unpaired UTF-16 surrogate chars, and thus cannot be encoded by stringByAddingPercentEncodingWithAllowedCharacters:, which therefore returns nil.
You can find an example in this post.
Apparently, you had to check for Japanese characters, if encoding is possible.
I must say, I did not expect that either!

Related

how to convert host of nsurl to lowercase

Let's say I have www.GOOgle.com/.......
I want to change it to www.google.com/....
and keep the rest of url as it is.
I have tried with NSURLComponents, but it didn't work.
// I am taking input from textfield and making the nsurl.
NSURLComponents *components = [NSURLComponents componentsWithString: _textfield.text]; // input from textfield
[[components host] lowercaseString];
NSURL *urlin = [components URL]; //but this gives, www.GOOgle.com
Any lead is appreciated.
As #Larme Suggests you can use method to setHost in url
see below example
NSURLComponents *components = [NSURLComponents componentsWithString: #"https://sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase"];
[components setHost:[components.host lowercaseString] ];
NSLog(#"%#",components.URL)
H
ttps://stackoverflow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase
NOTE:
http:// is required to add in String otherwise you will get host nil
eg https://www.sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase it will work
while
www.sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase
Will Not work
If your string is only url then, you can try this,
let strURL = "http://GOogLe.Com/Testt/xyz"
let url = NSURL(string: strURL)
let domain: String = (url?.host)! //get your host name
print(domain) //GOogLe.Com
let str = strURL.replacingOccurrences(of: domain, with: domain.lowercased())
print(str) //http://google.com/Testt/xyz
Convert the string to lowercase.
Then pass the converted string value to the componentsWithString method.
Sample:
NSString *lowerCaseStringValue = [_textfield.text lowercaseString];
[NSURLComponents componentsWithString: lowerCaseStringValue];

NSURL returning nil

I dont know why but when I am calling the following URL
it gives me BAD REQUEST - INVALID URL, although this URL is working fine on safari browser and other browsers as well
http://www.ysl.com/wx/shop-product/women/top-handles#{"ytosQuery":"true","department":"handbags_tophandle_w","gender":"D","brand":"","macro":"","micro":"","season":"A,P,E","color":"","size":"","site":"","section":"","sortRule":"","yurirulename":"searchwithdepartment","microcolor":"","agerange":"","macroMarchio":"","page":"2","productsPerPage":"50","modelnames":"","look":"","washtype":"","fabric":"","prints":"","suggestion":"false","suggestionValue":"","material":"","occasion":"","weight":"","gal
I am using following code:
NSString *str = [NSString stringWithFormat:#"%#",[payload stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSString* webStringURL = [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
webStringURL = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *payload = [NSURL URLWithString:webStringURL];
Any Help Guys? What is that I am doing wrong?
Don't use stringByReplacingPercentEscapesUsingEncoding: on the hole URL, but just on the GET parameters.
Now http:// will also be escaped, thus becoming http%3A%2F%2F which is not valid as an URL.

NSUrl fileURLWithPath returns strange chinese signs

I have an NSString path to my Documents folder.
NSString* stringURL = #"/var/mobile/Applications/5667FADC-F848-40CF-A309-
7BFE598AE6AB/Library/Application Support/MyAppDirectory";
When I cast it to NSUrl with
NSURL* url = [NSURL fileURLWithPath:stringUrl];
and NSLog(#"Created URL: %#",url);, i get some strange result:
///var/mobile/Applications/5667FADC-F848-40CF-A309-7BFE598AE6AB/Library/Application㤈㤋ތȀ乽啓汲唠䱒›楦敬⼺⼯慶⽲潭楢敬䄯灰楬慣楴湯⽳㘵㜶䅆䍄䘭㐸ⴸ〴䙃䄭〳ⴹ䈷䕆㤵䄸㙅䉁䰯扩慲祲䄯灰楬慣楴湯㈥匰灵潰瑲䴯䅹灰楄敲瑣牯⽹upport/MyAppDirectory/
Why is this so ?
What am I doing wrong ?
I didn't see any Chinese character when I log the value.
NSString* stringURL = #"/var/mobile/Applications/5667FADC-F848-40CF-A309-7BFE598AE6AB/Library/Application Support/MyAppDirectory";
NSURL* url = [NSURL fileURLWithPath:stringURL];
NSLog(#"%#",url);
Classical mistake. Don't use NSLog (url), use NSLog (#"%#", url). The first argument to NSLog is a format string, and % characters in format strings are interpreted, not printed. For example, %s in a format string means another C-String is expected in the argument list. Since url could contain all kinds of characters, this is likely to lead to rubbish results or even crashes.
Based on the answer you accepted from a previous question; it's because the use of stringByAddingPercentEscapesUsingEncoding will generate a printf-like formatting string containing %20S (the space between Application Support is converted to %20), which confuses NSLog():
NSURL *url = [NSURL fileURLWithString:[stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] isDirectory:YES];
NSLog(url);
use NSLog("#%", url) to avoid this error.

Data argument not used by format string but it works fine

I used this code from the Stack Overflow question: URLWithString: returns nil:
//localisationName is a arbitrary string here
NSString* webName = [localisationName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* stringURL = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#,Montréal,Communauté-Urbaine-de-Montréal,Québec,Canadae&output=csv&oe=utf8&sensor=false", webName];
NSString* webStringURL = [stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* url = [NSURL URLWithString:webStringURL];
When I copied it into my code, there wasn't any issue but when I modified it to use my url, I got this issue:
Data argument not used by format string.
But it works fine. In my project:
.h:
NSString *localisationName;
.m:
NSString* webName = [localisationName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* stringURL = [NSString stringWithFormat:#"http://en.wikipedia.org/wiki/Hősök_tere", webName];
NSString* webStringURL = [stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* url = [NSURL URLWithString:webStringURL];
[_webView loadRequest:[NSURLRequest requestWithURL:url]];
How can I solve this? Anything missing from my code?
The # in the original string is used as a placeholder where the value of webName is inserted. In your code, you have no such placeholder, so you are telling it to put webName into your string, but you aren't saying where.
If you don't want to insert webName into the string, then half your code is redundant. All you need is:
NSString* stringURL = #"http://en.wikipedia.org/wiki/Hősök_tere";
NSString* webStringURL = [stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* url = [NSURL URLWithString:webStringURL];
[_webView loadRequest:[NSURLRequest requestWithURL:url]];
The +stringWithFormat: method will return a string created by using a given format string as a template into which the remaining argument values are substituted. And in the first code block, %# will be replaced by value of webName.
In your modified version, the format parameter, which is #"http://en.wikipedia.org/wiki/Hősök_tere", does not contain any format specifiers, so
NSString* stringURL = [NSString stringWithFormat:#"http://en.wikipedia.org/wiki/Hősök_tere", webName];
just runs like this (with the warning Data argument not used by format string.):
NSString* stringURL = #"http://en.wikipedia.org/wiki/Hősök_tere";

URL for GET request

To get the JSON I was using this answer SBJsonWriter Nested NSDictionary
Now I have a sting {"key1":"bla1","key2":{"a":"a1","b":"b1","c":"c1","d":"d1"},"key3":"bla3"} that I've called theString
and I need to add it to a url http://mysyte.net:8888/JSON?
and to receive something like this http://lcwebtest.sytes.net:8888/JSON?{"key1":"bla1","key2":{"a":"a1","b":"b1","c":"c1","d":"d1"},"key3":"bla3"}
Here is what I do:
NSString *urlString = [NSString stringWithFormat:#"http://mysyte.net:8888/JSON?%#",theString];
NSLog gives http://mysyte.net:8888/JSON?{"key2":{"d":"d1","b":"b1","c":"c1","a":"a1"},"key1":"bla1","key3":"bla3"}
Then I make a url from it by
NSURL *url1 = [NSURL URLWithString:urlString];
BUT NSLog(#"%#",url1); gives me {null}
I assume NSURL does not want to read the "{" or "}" and thinks that the url was malformed.
How can I receive the url to make a GET request?
I assume NSURL does not want to read the "{" or "}" and thinks that the url was malformed.
That's right, you're not allowed to put some special characters in a URL. You want to escape the JSON string like this:
CFStringRef escaped = CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)theString, // (__bridge CFStringRef)theString if you use ARC
CFSTR(""),
CFSTR("?&=%,:+-"),
kCFStringEncodingUTF8
);
NSString *urlString = [NSString stringWithFormat:#"http://mysyte.net:8888/JSON?%#", (NSString *)escaped];
CFRelease(escaped);

Resources