NSLog outputs unicode characters as garbage when debugging on the iPhone - iphone

EDIT: NSLog output works well in the simulator, but doesn't work when connected to a real device. And it seems that it is a bug — http://openradar.appspot.com/11148883. Also it happens that it is related to the LLDB, switching Xcode to GDB resolves the problem. Either it's possible to JetBrain's AppCode, which works well with the LLDB.
I have a bunch of unicode strings in the application, and if I try to output any of those strings using something like NSLog(#"%#", aString) then all the ASCII characters in the string will be printed fine but all the cyrillic letters will be messed up, so instead of
newLocation: coordinate:60.019584,30.284954 'Удельная'
I'm getting:
newLocation: coordinate:60.019584,30.284954 '–ü–æ–∫–ª–æ–Ω–Ω–æ–≥–æ—Ä—Å–∫–∞—è'
And that's quite hard to do any debugging with that kind of output. And because that app is targeted for the Russian market only I can't just change locale and use English strings.
So I wonder if there any way to make NSLog work well with unicode characters? And I'm looking only for some kind of one-liner solution, I know that there are some ways to write half a page of code and output unicode chars, but I'm looking for something shorter. Ideally I'm looking for some method of NSString that will make it all work. e.g.
NSLog(#"%#", [aString someThingThatMakesUnicodeWorkWithXcodeConsole]);

Yes, obviously you can create a string that will contain and output cyrillic letters. When I was learning Objective-C, I had the same problem in the begining(I'm as well was working with Russian words and stuff like that). So solution is to convert the string to other format like this:
NSString *string = [NSString stringWithCString:"Привет, как дела?" encoding:4];
NSLog(#"%#", string);
or
NSString *string = [NSString stringWithUTF8String:"Этот вариант короче!"];
NSLog(#"%#", string);
Hope it helps you!
P.S It means that you need to make create your strings as C-Style Strings, and set their encoding parameter to 4(UTF-8). You can see all list of avaliable parameters in the documentation to NSStringEncoding in NSString.

As far as I know it is relevant to NSLog() and LLDB on some Xcode versions. Have a try with one of these solutions:
Check log in Xcode Organizer >> Devices >> your device >> Console.
Use GDB as your debugger instead of LLDB if you are using the latter one. This can be changed from the schema options. Please refer to the steps in the comment by "cocos2d man" below.
Upgrade to Xcode 4.3.2. Some people say it solved this issue, but I haven't confirmed this myself.

Try to convert it in to UTF8 string.
NSString *str = [aString UTF8String]
NSLog(#"%#", str);
Hope this helps.

Try putting it like NSLog(#"%#", aString);
EDIT :
you can convert it in UTF8 string. This could get you through.
NSString *str = [aString UTF8String];
Hope this helps.

Try this. It works for me.
NSLog(#"%#", [NSString stringWithCString:[[places description] cStringUsingEncoding:NSASCIIStringEncoding] encoding:NSNonLossyASCIIStringEncoding]);

Related

decoding quoted-printables

I am looking for a way to decode quoted-printables.
The quoted-printables are for arabic characters and look like this:
=D8=B3=D8=B9=D8=A7=D8=AF
I need to convert it to a string, and store it or display..
I've seen post on stackoverflow for the other way around (encoding), but couldn't find decoding.
Uhm, it's a little hacky but you could replace the = characters with a % character and use NSString's stringByReplacingPercentEscapesUsingEncoding: method. Otherwise, you could essentially split the string on the = characters, convert each element to a byte value (easily done using NSScanner), put the byte values into a C array, and use NSString's initWithBytes:length:encoding: method.
Note that your example isn't technically in quoted-printable format, which specifies that a quoted-printable is a three character sequence consisting of an = character followed by two hex digits.
In my case I was coming from EML... bensnider's answer worked great... quoted-printable (at least in EML) uses an = sign followed by \r\n to signify a line wrapping, so this was the code needed to cleanly translate:
(Made as a category cause I loves dem)
#interface NSString (QuotedPrintable)
- (NSString *)quotedPrintableDecode;
#end
#implementation NSString (QuotedPrintable)
- (NSString *)quotedPrintableDecode
{
NSString *decodedString = [self stringByReplacingOccurrencesOfString:#"=\r\n" withString:#""]; // Ditch the line wrap indicators
decodedString = [decodedString stringByReplacingOccurrencesOfString:#"=" withString:#"%"]; // Change the ='s to %'s
decodedString = [decodedString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // Replace the escaped strings.
return decodedString;
}
#end
Which worked great for decoding my EML / UTF-8 objects!
Bensnider's answer is correct, the easy way of it.
u'll need to replace the "=" to "%"
NSString *s = #"%D8%B3%D8%B9%D8%A7%D8%AF";
NSString *s2 = [s stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
s2 stored "سعاد" which makes sense so this should work straight forward with out a hack
In some cases the line ends are not "=\r\n" but are only "=\n", in which case you need another step:
decodedString = [self stringByReplacingOccurrencesOfString:#"=\n" withString:#""];
Otherwise, the final step fails due to the unbalanced "%" at the end of a line.
I know nothing of the iPhone, but most email processing libraries will contain functions to do this, as email is where this format is used. I suggest searching for MIME decoding type functions, similar to those at enter link description here.
The earlier posters approach also seems fine to me - I feel he is being a little too self-deprecating in describing it as hacky :)
Please see a working solution that takes a quoted-printable-containing strings and resolves those graphemes. The only thing you should pay attention to is the encoding (that answer is based upon UTF8, by it can be easily switched to any other): https://stackoverflow.com/a/32903103/2799410

How to avoid UTF8 characters inside my NSDictionary?

i'm saving a NSString inside an NSArray and that NSArray inside an NSDictionary. While doing this, a process inside my NSDictionary notifies me if my string is like Hi I'm XYZ. Then in the place of single quote the appropriate UTF character is getting stored.
So how to avoid this or how can I get my actual text along with special characters from NSArray or from my NSDictionary?
Any help is thankful.
NSString internally uses Unicode characters. So it easily can handle all sorts of characters from different languages.
You cannot choose the internal encodig of NSString. It's always Unicode. If you have an encoding problem, then you have either created the NSString instance incorrectly or you have output the instance the wrong way.
And there's no such thing as an UTF character.
Please better describe your problem and show the relevant source code.

Newline chars somehow get added to my strings. And cant remove them

On some of my strings there seems to be somekind of newline char. I think this is the case because when i do a simple NSLog
NSLog(#"Test: %#",aNSMutableString);
I would get output like below
Test:
I am a String
I've tried using
[mutableString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
But it does not remove whatever it is thats forcing the newline to happen.
In a string that i parse out from a file which has 4 characters 'm3u8' has 5 chars when I check the length of the new string.
Anybody got an idea of what might be going on?
Thanks
-Code
P.S.
I know I could just zap the first char out of all my strings but it feels like a hack and i still wont know whats going on.
[mutableString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
The above will not directly modify your mutableString. It returns a new autoreleased NSString with the characters trimmed. See NSString doc.
e.x.
NSString *trimmedString = [mutableString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSLog(#"Test: %#", trimmedString);
should give you expected results.
I think #Sam 's answer will fix your problem, but I think the origin of your problem is the file source. Do you know how it is encoded? Is it part of a download? My guess is that you have a Windows' file with "\n\r" terminating lines and you are using Unix string tools that are breaking on "\n", thus leaving a leading "\r".
Verify the source of the file and read the document lines with the appropriate encoding.

Tilde in device name causing problems with NSOutputStream socket

In the networking between the iPhone and desktop versions of our application, the iPhone sends over the device name for use on the desktop. The problem is that some of the beta testers have tildes (`) in their device names. For some reason when this is in the device name it prevent the socket from sending the actual string data.
I've tried simply cleaning up the device name before sending it, but the tilde in the device name (as entered in iTunes) is not recognized at runtime as a tilde. Here's the code that doesn't work:
NSString *safedevicename = [[UIDevice currentDevice] name];
safedevicename = [safedevicename stringByReplacingOccurrencesOfString:#"`" withString:#"'"];
It finds no occurrences of a tilde, and replaces nothing. I've also used rangeOfString to search for tildes and it returns nothing. I'm 100% sure the character, at least as it's entered in iTunes, is a tilde.
Also, when printing a description of the string to the console, the character is encoded as \u00b4, and when hovering over the variable it appears as a period ..
Anyone know how I can grab this character and get it out of there? Also, isn't there a way in objective C to more easily clean up the string to make sure it's safe to send over a socket?
EDIT:
Also something that might be useful, to write the NSString to the NSOutputString I use the following line of code:
len = [oStream write:[[writeString dataUsingEncoding:NSASCIIStringEncoding] bytes] maxLength:[writeString lengthOfBytesUsingEncoding:NSASCIIStringEncoding]];
EDIT #2:
This line of code works to replace the Tilde, but I'm sure there are other characters I should be worrying about:
safedevicename = [safedevicename stringByReplacingOccurrencesOfString:#"\\u00b4" withString:#"'"];
Jason's comment was the correct answer: I needed to change the encoding from NSASCIIStringEncoding to NSUTF8StringEncoding.

NSString #"\" adding backslash character objective-c

Does anyone know of an easy way to add a single backslash (\) to a NSString in Objective-C? I am trying to have a NSString *temp = #"\/Date(100034234)\/";
I am able to get a double backslash or no backslash, but unable to get a single backslash. Any help would be appreciated. Thanks
The string #"\\" is a single backslash, #"\\\\" is a double backslash
The strings and NSLog are working fine for me (iPhone SDK 3.1.2 and Xcode 3.2.1):
NSLog(#"\\"); // output is one backslash
NSLog(#"\\\\"); // output is two backslashes
NSLog(#"\\/Date(100034234)\\/"); // output is \/Date(100034234)\/
See this answer.
This is a bug in NSLog. I found a mailing list archive with a message dated in 2002 of someone that filed a bug for this here. The person also said this:
Nothing has been done as far as I can tell. I don't understand how
they've done it, but the escaping does work for the string, just not for
NSLog.
So I guess you will have to come up with your own implementation of a log message if you really want backslashes.
This code does give the requested output:
NSString *temp = #"\\/Date(100034234)\\/";
NSLog(#"%#",temp);
However I had an issue with my JSON toolkit (SBJSON) that replaced all occurrances of "\\" with "\\\\", which did cause issues as described in the other answers and the comments.
The result was a string looking like:
#"\\\\/Date(100034234)\\\\/"
See my answer here
The solution was using:
temp = [temp stringByReplacingOccurancesOfString:#"\\\\" withString:#"\\"];
Where you want a \ add or remove. just \\ on that place.