15

I'm trying to read strings from an array that's coming from a plist and print those strings.

The strings in the array contain escaped UTF8 characters - for example "Nuša Florjančič" becomes "Nu\u0161a Florjan\u010di\u010d" when read from the plist. There is no way to change the content of the plist, but my program needs to display the names properly.

The strange thing is that Objective-C seems to do this automatically when I'm hardcoding the string. However, if I get the string from the plist nothing happens at all.

To give you an example, here's some code:

NSString *name1 = @"Nu\u0161a Florjan\u010di\u010d";
NSString *name2 = [list objectAtIndex:0];       
NSLog(@"name 1: %@", name1);
NSLog(@"name 2: %@", name2);

[list objectAtIndex:0] contains @"Nu\u0161a Florjan\u010di\u010d" - the only difference is that it has been set via the plist editor.

The console output is:

2011-10-22 18:00:02.595 Test[13410:11c03] name 1: Nuša Florjančič
2011-10-22 18:00:02.595 Test[13410:11c03] name 2: Nu\u0161a Florjan\u010di\u010d

I've tried all sorts of things, including transforming the string into a C-string and then creating an NSString object with a UTF-8 encoding but nothing worked at all.

I'd really appreciate any pointers from you that might help me solve this seemingly mundane problem.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
Tobi
  • 151
  • 1
  • 1
  • 3

2 Answers2

40

It sounds like the string in the plist contains the characters "\u0161" rather than the Unicode character number 0x161. So you need to decode the \u escapes in the string you've extracted from the plist. NSString can do that for you using NSNonLossyASCIIStringEncoding:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
    @autoreleasepool {
        NSString *name2escaped = @"Nu\\u0161a Florjan\\u010di\\u010d";
        NSString *name2 = [NSString
            stringWithCString:[name2escaped cStringUsingEncoding:NSUTF8StringEncoding]
            encoding:NSNonLossyASCIIStringEncoding];
        NSLog(@"name2 = %@", name2);
    }
    return 0;
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • 1
    How does this solution compare to using CFStringTransform in terms of pros & cons of the two? This one is new to me. – uchuugaka Apr 20 '13 at 04:51
  • @uchuugaka First, tell me how to use `CFStringTransform` to perform this conversion. – rob mayoff Apr 20 '13 at 17:15
  • Boolean CFStringTransform ( CFMutableStringRef string, CFRange *range, CFStringRef transform, Boolean reverse ); Basically you supply a CFMutableString, the range to operate on, the ICU transformation as a string (or one of the CF constants that are wrappers for a small subset) and finally a Boolean whether to transform in the order of the supplied transformation string or reverse it. (Such as "Hex-Any") the same ICU transformations are used elsewhere under the good in cocoa and are found in Java. Cocoa employs the ICU libraries in a lot of places. – uchuugaka Apr 21 '13 at 04:27
  • Show me an example of using `CFStringTransform` to perform this conversion. – rob mayoff Apr 21 '13 at 04:29
  • 1
    @robmayoff See this answer http://stackoverflow.com/a/11615076/104790 for an example. – Nikolai Ruhe May 13 '14 at 10:29
1

Other solution is parse your list string (I used to parse it before build it)

NSString yourFinalString = [NSString stringWithCString:[yourOriginalString cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding];

(Looks like Croatian, i think latin1 will fit properly)

VictorPurMar
  • 151
  • 9