arm1.ru

Escaping image URLs with Russian filenames in Objective-C

Management at the office started uploading images with Russian filenames into news on the portal — things like Фото-Ресторана.jpg.

Images from news items are shown inside the app, so the app fetches them by these URLs.

The URL arrives in the app already percent-encoded, e.g.:


http://allcafe.ru/s/pic/news/!_2012/2012_12/%D0%A0%D0%B5%D1%81%D1%82%D0%BE%D1%80%D0%B0%D0%BD-Graf-in-%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3-%D0%B7%D0%B8%D0%BC%D0%BD%D1%8F%D1%8F-%D1%82%D0%B5%D1%80%D1%80%D0%B0%D1%81%D0%B0.jpg

The app uses a class called AsynchronousUIImage that I found online about a year ago. It just loads the image asynchronously via NSURLConnection.

- (void)loadImageFromURL:(NSString *)anUrl {
    anUrl = [anUrl stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:anUrl] 
        cachePolicy:NSURLRequestReturnCacheDataElseLoad 
        timeoutInterval:30.0
    ];

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

The catch turned out to be in stringByAddingPercentEscapesUsingEncoding. Since the URLs come in already percent-encoded, it looks like double-encoding was happening and the image simply wouldn’t load. And if the NSURLConnectionDelegate method connection:didFailWithError: isn’t implemented, you get a crash — which is what hit me.

The funny conclusion: if you have URLs containing Cyrillic characters, you have to escape them either on the server before sending them to the client, or in the client. Doing it in both places — doesn’t work. Doing it nowhere — also doesn’t work :)

Luckily I fixed it on the server side without breaking anything and avoided shipping an emergency client update. By the way, on Android there is no such problem.

keyboard_return