Quick tip about localizing currency on iOS
NSMutableCharacterSet* tempSet = [NSCharacterSet whitespaceCharacterSet];
You should in fact use:
NSMutableCharacterSet* tempSet = [[NSCharacterSet whitespaceCharacterSet] mutableCopy];
I apologize for the confusion.Let's say you have a text field in your iOS app and you want to take currency values in said field. NSNumberFormatter is your friend and can happily turn a string like "$42.23" into the floating point number 42.23. It will also turn the floating point number 42.23 back in "$42.23". Even better with the German locale active it will turn 42.23 into "$42,23 €" and vice-versa (note the comma as well as the euro symbol). Sweet! However, here's a minor glitch. Sweden's currency "symbol" is in fact a string – "kr". While your formatter will turn the float 42.23 into "42,23 kr" it cannot turn "42,23 kr" back into the floating point value. What to do? What I decided to do was strip whitespace and currency symbols from the string before trying to convert the string into a float. Like so:
NSCharacterSet* costTrimmingCharacters = nil;
//OK, some settings have currency symbols that can't survive a 2-way trip. For example, Sweden's currency "symbol" is "kr"
//So what we're going to do is trim whitespace and currency symbols from the string. Also then we don't have to use the currencyFormatter and can
//simply use the decimalFormatter (since it will strip $ from US locales, for example.)
NSMutableCharacterSet* tempSet = [[NSCharacterSet whitespaceCharacterSet] mutableCopy];
[tempSet addCharactersInString:[[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCurrencySymbol]];
costTrimmingCharacters = [tempSet copy];
//Note in a real app you should store costTrimmingCharacters somewhere and only build it the first time you need it.
NSNumberFormatter* currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setLocale:[NSLocale autoupdatingCurrentLocale];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString* aggravatingString = [NSString stringFromString:@"42,23 kr"]
NSString* goodString = [aggravatingString stringByTrimmingCharactersInSet:costTrimmingCharacters];
NSNumber* goodValue = [currencyFormatter numberFromString:goodString]
Full disclosure: I didn't test that exact snippet, it's frankensteined from a few pieces of code out of RoadTrip that would have just obscured the point. So there may be a syntax error somewhere due to a typo but the idea should be clear. Last two little suggestions:
- I use a related character set in the field delegate's shouldChangeCharactersInRange: replacementString: method so that I don't even accept illegal characters and that way you can't even enter "kr" unless you're in the Sweden locale.
- In the delegate's textFieldDidEndEditing: method once I've converted the string into a float I go right ahead and convert it back into a string and assign it back into the field. That means if they entered 42.23 they'll see a nice $42.23 or 42,23 € or whatever their locale specifies.
Cleaning up a D&D Character File
A couple of months ago Wizards of the Coast "upgraded" the Character Builder program from the downloadable .NET application for Windows to a Silverlight program that can run on a Mac. In theory I support this. However, one crazy thing happened: the new program doesn't send text to a printer and instead sends big images. This means if you print to a PDF file two things happen: the file size is obscene (12 or more Mb for a four page file), and the text is blurry as all get out.
After some struggling with this I had an epiphany: if WotC wants to give me images go ahead and work with that, process the images, and get a smaller, sharper file. After some messing about I came up with a process that works well for me. If you have a Mac and you want to play along here's an Automator app. You'll also need a scriptable image editor - I use Acorn from Flying Meat software. (You might ask why not Pixelmator. The answer is Pixelmator seems crashy when run from script. I have a version of this that uses Pixelmator but I have to run it 5-6 times to get a successful output.) Here's what you do:
- Run the Character Builder and hit the Print button.
- When the print dialog opens use the PDF button in the lower left and choose "Save PDF to folder as TIFF". Pick someplace (I use the Desktop) and let it run. You now have a TIFF file for each page in the character file. These are fat and they are blurry but we'll fix that next.
- Select all of the pages and drop them on the Automator App.
- The Automator app uses Applescript to tell Acorn to open all of the TIFF files, run an Unsharp Mask on them, and save them again.
- The Automator app then creates a new PDF from the Images. This will be named Character.pdf and it will be on your Desktop. You can now delete the TIFF files and enjoy a readable PDF that can put on an iPad (for example.)
To be clear, this is still a work-around. The Character Builder ought to output text and then you could just use the print to PDF button normally. This workaround isn't great - there's still some definite halo effects on the text and the files are still pretty fat. My sorcerer (Gurdrian) was a 471 Kb PDF file with the old builder and my current version is 6.1Meg - over an order of magnitude larger, while looking worse. This is sucky, but it's less sucky than the 15 Mb version simply printing from the app to a PDF create
Anyway, if this helps somebody out there, here's my Automator app. No warranty, etc, blah, blah but it does the trick for me. If you try it and have an issue drop me a line and I'll see what I do to help.