objective-cutf-8nsstringnsstringencoding

+ (instancetype) URLWithString returns nil when I try to put non-latin character


I know what's the error I've got however I don't know the way to decide it. It's okay to meet letters like Þþ, Ðð, Ææ, etc. within my Cocoa App.

By breakpoints I'd put I found that URLWithString returns nil every time when I put at least one non-latin character. Otherwise, returns some new URL only based on latin characters.

Some fragment of attempt:

NSString *baseURLString = @"https://hostdomain.com";
NSString *pathURLString = @"/restapi/someRequest?par1=arg1&par2=arg2&input=";
NSString *fullURLString = [NSString stringWithFormat:@"%@%@móðir", baseURLString, pathURLString];
NSURL *url = [NSURL URLWithString:fullURLString]; // here I get a nil while working with non-latin characters.

I'm still trying to find a solution but none of decisions here on stackoverflow didn't help me. Any idea would be appreciated! My idea is URLWithString works well only with ASCII symbols.. 🤔


Solution

  • URLWithString only works with valid URLs. Some of the characters you're passing are not valid for the query portion of an URL. See section 2 of RFC 3986. Since the URL is invalid, it returns nil.

    If you have arbitrary characters coming into your URL, you shouldn't try to build it all as a single string, since each part of the URL requires different encoding. You need to use NSURLComponents. This will automatically escape each section correctly.

    NSURLComponents *comp = [NSURLComponents new];
    comp.scheme = @"https";
    comp.host = @"hostdomain.com";
    comp.path = @"/restapi/someRequest";
    comp.query = @"par1=arg1&par2=arg2&input=óðir";
    
    NSURL *url = comp.url;
    // https://hostdomain.com/restapi/someRequest?par1=arg1&par2=arg2&input=%C3%B3%C3%B0ir
    

    Or, since the base part of the URL is static and you know it's encoded correctly, you can do it this way:

    NSURLComponents *comp = [NSURLComponents componentsWithString:@"https://hostdomain.com/restapi/someRequest"]
    comp.query = @"par1=arg1&par2=arg2&input=óðir"
    

    If you really want to build strings more directly, you can look at stringByAddingPercentEncodingWithAllowedCharacters:. Use [NSCharacterSet URLQueryAllowedCharacterSet] for the query part.