Tilde in device name causing problems with NSOutputStream socket - iphone

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.

Related

What's with the dashes in some iOS error messages?

I sometimes see error messages in the log file of my iOS device with at least part of the text containing dashes between each letter, like this:
... ’-t -b-e -c-o-m-p-l-e-t-e-d-. -(-k-C-F-E-r-r-o-r-D-o-m-a-i-n-C-F-N-e-t-w-o-r-k -e-r-r-o-r -2-.-)-" -U-s-e-r-I-n-f-o-=-0-x-1-4-5-f-d-0 -{-k-C-F-G-e-t-A-d-d-r-I-n-f-o-F-a-i-l-u-r-e-K-e-y-=-8-}
I'm just curious as to any meaning this might have (certainly doesn't do much for readability, but I suppose it's easy to spot), or if it's just a random problem. (My device is jailbroken, if that makes a difference).
Update: I was able to format a log message similarly by calling NSLog with a non-ASCII character at the beginning:
NSLog(#"€ Line will be formatted strangely");
I suspect that the message was in UTF16 (or some other double-byte character set) and was incorrectly mapped in as ASCII when converting to an NSString.

NSLog outputs unicode characters as garbage when debugging on the 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]);

encoding information in filenames (iPhone/mac)

I want to encode a short title in filenames. The problem is that occasionally the title will contain a character such as a colon or a slash. Is there a standard encoding that would be typical/appropriate for this?
EDIT: to clarify, I want to encode the title in such a way that the encoded title could be used as a filename. Or is that called percent escaping?
The way I do this is with a category on NSURL, which I use to get the NSURL for a filename in a particular directory. Once I have this NSURL, I can fetch or save the file using the URL after performing the usual checks about whether or not the file already exists and handling those cases accordingly.
The relevant code snippet is:
+ (NSURL *)adnURLForFileName:(NSString *)fileName inDirectory:(NSSearchPathDirectory)searchDirectory {
NSString *percentEscapedFileName = [fileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *URLForDirectory = [[fileManager URLsForDirectory:searchDirectory inDomains:NSUserDomainMask] objectAtIndex:0];
return [NSURL URLWithString:percentEscapedFileName relativeToURL:URLForDirectory];
}
You can download the full category code from GitHub - NSURL+ADNFileHelpers
You could use -stringByReplacingOccurrencesOfString:withString: to replace the slash character with U+2044, the "solidus" aka "fraction slash". It looks like this: ⁄
http://en.wikipedia.org/wiki/Solidus_(punctuation)
The slash is not allowed in the Unix APIs. The colon is not allowed in HFS and in the old File Manager APIs. The same filename character will show up as a colon in the former and as a slash in the latter. In practice: you can use the Finder to rename a file to "/" (because the Finder uses the traditional Mac separator of :), but it will show up as ":" if you use ls.
If you need to allow both colons and slashes, you need to encode the characters somehow. You could use URL-style escaping, but if you expect the user to look at the filename in the Finder or in some other program, it's going to look horrible. It's better to escape just the path separator. For example, if you're using the Unix style APIs (path separator /), you could encode / as :- and : as :: (to avoid ambiguity). Or you could use some other little-used character for the escape.
I have approached this problem by filtering the title before using it in the filename. NSString has some useful methods, such as stringByStandardizingPath and stringByReplacingOccurrencesOfString:withString:. The filtering approach is lossy, in that the original title information might not be restorable. Similarly, I don't think encoding would work because iOS allows such a wide range of characters in its filenames. One possible alternative solution could be a plist archive with key=filename, value=title.

Stig JSON library parse error: How do you accommodate new lines in JSON?

I have some xml that is coming back from a web service. I in turn use xslt to turn that xml into json (I am turning someone else's xml service into a json-based service). My service, which is now outputting JSON, is consumed by my iphone app using the de facto iphone json framework, SBJSON.
The problem is, using the [string JSONValue] method chokes, and I can see that it's due to line breaks. Lo and behold, even the FAQ tells me the problem but I don't know how to fix it.
The parser fails to parse string X
Are you sure it's legal JSON? This framework is really strict, so won't accept stuff that (apparently) several validators accepts. In particular, literal TAB, NEWLINE or CARRIAGE RETURN (and all other control characters) characters in string tokens are disallowed, but can be very difficult to spot. (These characters are allowed between tokens, of course.)
If you get something like the below (the number may vary) then one of your strings has disallowed Unicode control characters in it.
NSLocalizedDescription = "Unescaped control character '0x9'";
I have tried using a line such as: NSString *myString = [myString stringByReplacingOccurrencesOfString:#"\n" withString:#"\\n"];
But that doesn't work. My xml service is not coming back as CDATA. The xml does have a line break in it as far as I can tell (how would I confirm this). I just want to faithfully transmit the line break into JSON.
I have actually spent an entire day on this, so it's time to ask. I have no pride anymore.
Thanks alot
Escaping a new line character should work. So following line should ideally work. Just check if your input also contains '\r' character.
NSString *myString = [myString stringByReplacingOccurrencesOfString:#"\n" withString:#"\\n"];
You can check which control character is present in the string using any editor which supports displaying all characters (non-displayable characters as well). e.g. using Notepad++ you can view all characters contained in a string.
It sounds like your XSLT is not working, in that it is not producing legal JSON. This is unsurprising, as producing correctly formatted JSON strings is not entirely trivial. I'm wondering if it would be simpler to just use the standard XML library to parse the XML into data structures that your app can consume.
I don't have a solution for you, but I usually use CJSONSerializer and CJSONDeserializer from the TouchJSON project and it is pretty reliable, I have never had a problem with line breaks before. Just a thought.
http://code.google.com/p/touchcode/source/browse/TouchJSON/Source/JSON/CJSONDeserializer.m?r=6294fcb084a8f174e243a68ccfb7e2c519def219
http://code.google.com/p/touchcode/source/browse/TouchJSON/Source/JSON/CJSONSerializer.m?r=3f52118ae2ff60cc34e31dd36d92610c9dd6c306

How to safely encode µ or the micro-symbol into an NSString programmatically?

I need a representation of µ or "micro". That funny small u with the long tail on the left side. Maybe you can see it here: µ
Some weeks ago I was reading in the docs, that it's a bad idea to type any special characters into the source code. So to prevent problems, could I encode that special character µ somehow like web folks do with , in an NSString? And if so, is there an overview of these codes or a way to get the correct code?
Take a look at this thread:
How do I escape a Unicode character in my Objective-C source code?
NSString *stuff = #"The Greek letter Beta looks like this: \u03b2"
For the iPhone, and for Mac OS X using the Xcode 3.x tool chain (targeting 10.2 or later, which you must be if you're using Xcode 3.x), it is safe and supported to use a literal µ in the string constant. The only caveat is that you must set the -finput-charset command-line option if your source files are not UTF-8 or UTF-16.