1

I have a situation, I don't know what causing it.

I have got a string from server like this

NSString *str=@"\\u3060\\u3044\\u3053\\u3093\\u3001\\u5927\\u6839\\n";

I am trying to decode it using the following code..

NSLog(@"%@",[self decodeString:str]);


-(NSString*)decodeString:(NSString *)inputString{
    NSData *utfStringData=[inputString dataUsingEncoding:NSUTF8StringEncoding];
    NSString *output=[[NSString alloc] initWithData:utfStringData encoding:NSNonLossyASCIIStringEncoding];
    return output;
}

I get nil as output.

But when I remove extra "\" from the input string, NSString itself shows the proper wording without even passing into decodeString function, see below

enter image description here

So I decided the replace the extra "\" from input string using following code

inputString=[inputString stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];

Above code doesn't work either.

My question is -> What am I doing wrong? How does it work?

Thanks for Helping.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • Are you trying to convert a UTF8 string to ASCII? – Guy Kogus Apr 17 '18 at 07:13
  • 1
    Your string is UTF-16 encoded, not UTF-8 – mag_zbc Apr 17 '18 at 07:15
  • you want try to clean \\ from dictionary data and store data into string –  Apr 17 '18 at 07:16
  • @RB1509 How to do that? – iphonic Apr 17 '18 at 07:17
  • Your `decodeString:` method won't work. You already have a valid string, then you're getting the UTF8 representation of it and then trying to interpret it in a different encoding. – Guy Kogus Apr 17 '18 at 07:28
  • @mag_zbc is there a way to determine encoding type for incoming string? I will try it with UTF16. – iphonic Apr 17 '18 at 07:32
  • _is there a way to determine encoding type for incoming string?_ - you're not supposed to determine encoding of incoming string, that information should be provided in your web service's documentation – mag_zbc Apr 17 '18 at 07:34
  • @mag_zbc Yes the api is returning UTF8 string the problem is the decoding works for some strings but doesn’t with some, so I thought there is definitely a difference somewhere. – iphonic Apr 17 '18 at 07:36

1 Answers1

2

You need to use CFStringTransform to convert unescape unicode characters. CFStringTransform can perform real magic like transliterations between greek and latin (or about any known scripts), but it can also be used to do mundane tasks like unescaping strings from a server:

NSString *str=@"\\u3060\\u3044\\u3053\\u3093\\u3001\\u5927\\u6839\\n";
NSString *convertedString = [str mutableCopy];

CFStringRef transform = CFSTR("Any-Hex/Java");
CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES);
NSLog(@"convertedString: %@", convertedString);     //convertedString: だいこん、大根\n

CFStringTransform is really powerful. It supports a number of predefined transforms, like case mappings, normalizations or unicode character name conversion. You can even design your own transformations.

OS X 10.11 and iOS 9 add the following method to Foundation:

- (nullable NSString *)stringByApplyingTransform:(NSString *)transform reverse:(BOOL)reverse;

Here is the code with the above method:

NSString *convertedString = [str stringByApplyingTransform:@"Any-Hex/Java" reverse:YES];
NSLog(@"convertedString: %@", convertedString);     //convertedString: だいこん、大根\n
Arnab
  • 4,216
  • 2
  • 28
  • 50
  • Brilliant!! If you could add some explanation what is happening, this solution looks similar to android *StringEscapeUtils.unescapeJava* function.. – iphonic Apr 17 '18 at 09:07
  • Making transform=YES/NO determines either to `unescape/escape`, right? – iphonic Apr 17 '18 at 09:13
  • The last parameter is boolean that, if true, specifies that the inverse transform should be used (if it exists). – Arnab Apr 17 '18 at 09:20
  • Hi, any idea why newline "\n" doesn't show a newline when I supply the convertedString to `UITextView` ? – iphonic Apr 20 '18 at 09:53
  • 1
    Hello, after the conversion, it applies another backslash before `\n` so just use `convertedString = [convertedString stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];` before suppling the `convertedString` into `UITextView` – Arnab Apr 20 '18 at 10:15
  • Yes thanks, it is working, I didn't realize that it added extra backslash. – iphonic Apr 20 '18 at 10:34