Wednesday, November 27, 2013

Writing an iOS Kids App-Frog Draw

I recorded an episode of The Tablet Show this week where I talked about what I've learned about writing an app for the Kids section of the App Store, the kid's shape drawing app, Frog Draw.

The Parental Gate

Apple rejected my app three times. The first was because of sloppy layout issues on my part, but the last two were because of the Parental Gate. Basically, apps in the kids section have to ask for parental permission every time the kid wants to buy something or interact with the wider Internet. I somehow missed this, so the second rejection was because I'd missed this requirement. So, no gate on purchasing my beautiful stickers, and no gate on sending artwork via e-mail; bam another 5 days in the review queue. 

So I looked around at what that actually meant, and found these examples at Dreambot Studios. Amazingly, Apple didn't provide a standard API for providing a secure gate. I'd have expected there would have been an API that provided a localized challenge string, and a cryptographically secure method of validating a response. Instead, developers have to roll there own method to differentiate between a 12 year old and an adult. I chose a math problem I didn't think my precocious 8 year old could solve:

Frog Draw's Parental Gate


Apple provides a mercifully short set of guidelines for iOS app submissions and here is the entire relevant guideline for the need for a parental gate:
 24.3 Apps primarily intended for use by kids under 13 must get parental permission or use a parental gate before allowing the user to link out of the app or engage in commerce
So given this directive, I thought it would be easiest on the parent to provide a convenient one stop location for all the parental controls, so that the  parent could allow or disallow purchases, allow for making a quick trip to the App Store to rate the app, and turn on various means of sharing the drawings. All of these were off by default.
My Rejected Parental Controls Pane
I even put some Emoji characters in there so that non-English speakers could tell what they were agreeing to. And I submitted it to Apple and it was (I wish I could say promptly, but it was another 5 days) rejected. Why? Because while the guidelines make no mention of this, Apple has a rule that you cannot permanently enable a gated feature. Their rule is that the parent has to agree to its use each and every time.

I was pretty upset about this, but I kept calm and appealed the ruling to the review board, and was promptly told my appeal was rejected; this was indeed how the review team interprets rule 24.3. Two things, one I don't like arbitrary rules ruining my beautiful app with user hostile behaviors; I want to empower my users to have fun and draw some silly images.  And two, as a parent, I am not feeling empowered. As a parent, I would likely want to disallow in-App purchases even though Frog Draw only sells non-consumable clipart/stickers—I still remember spending $35 on Smurfberries—and allow e-mails. I don't care either way about rating the app. And turn off everything else.  But it's Apple's playground, so I did it their way.

Can Kids Apps be non-Skeuomorphic? 

As an adult with something approaching design taste, I am happy with iOS 7's lack of chrome and general removal of fake analog reality. I wish buttons had just a little bit of chrome, but otherwise, I'm a happy iOS user. But do children need something more? I guess I'll find out.
Here's my iPhone layout while displaying its color toolbox:
Frog Draw with Color Buttons
You'll notice that I am using recognizable buttons, but with light chrome. Also that the artwork projects into the status bar; this is under the user's control. Want to see what time it is? Draw something light under the clock. I'm using a light highlighting to show which tab is active, and in general I'm following the rule that controls should not be visually distracting. The important part should be the art. 
Frog Draw with Stickers

I hope this applies to kids too, and they don't require Fisher-Price controls and fuzzy bunny cartoons wasting space and distracting them; or more importantly for downloads that parents don't have a pre-existing view of what kids apps look like.

In my first version of this interface, I thought it would be cool to have iOS 7 style squircles behind my shapes. But testing with my kids revealed that children are already hard coded to tap on that shape (instead of what I want them to do, drag a copy off). So I removed the squircles which led me to change the color of my toolbox, which led me to change the color of my toolbox tab bar, which lead me to change my highlighting color which led to my final design, which I love.

An Early Design that had Issues. I missed Halloween.

The design choice I made which I'm most unsure of is the icon. On the one hand, modern iOS icons are geometrically simple, clean lined, abstract pieces of art. On the other hand it's hard to make a happy smiling abstract frog, it'll look too much like a duck. If my app doesn't sell, I'll blame the icon.

[Update: I've changed my mind on the icon. I'll dial back the cold inaccessible look and add some humanity to the 1.1 version's icon.


Kids and Gestures

I've already covered the importance of gestures in a modern interface but a few words about kids. Kids are more adept than we old folks at picking up gestures. They get the visual cues, they know what worked in other apps and they don't have a lifetime of mousing to unlearn. In fact, my daughter asked me the other  day, "what is a mouse?" when she was trying to figure out a Flash game on PBSKids (we use Magic Trackpads with our Macs). Kids pick up gestures if you give them enough clues or a visual explanation of what will happen when you do what. My major concern is communication with the user about the non-discoverable gestures like my 2 finger up down swipe to change the order of shapes. Thus, the importance of having a decent on boarding screen for the first time the app gets run. As I have the ability to animate the whole creation process of a Frog Draw document, my on boarding window has an animation of some gestures, and I hope this is enough, but I'll likely revisit this.

Make a Quality App

There is nothing about writing for kids that means you can cut corners. My son knows what a good app looks like and how it acts. Last night, he was making sure I knew I should have a longer tutorial/level  up section just like his best games have. At release of 1.0, I have a good app. I've profiled it to look for speed bottlenecks, I've rejected my own submissions to Apple more times than I'd like to count when something came up which would result in a child having a bad experience. The last month of development has humbled, but I think the end product is worthy. 

I don't know if people value this, but I do. The packaged up App is only 4MB. It would have been under 3MB, but at the last minute I had to add 64-bit support or Apple's face recognition functions wouldn't have worked on A7 based iOS devices. This was all possible because pretty much every pixel in the interface is drawn either in code or by rendering lightweight SVG, and not with bulky bitmap images. I hope potential customers don't see the small download size and think there's something missing, I value efficient use of a user's limited space. Being bulky will get an app booted off my iPad if I don't use it daily.

Frog Draw 1.0 Free in the App Store, no Ads, no consumable in-app purchases, just some child-friendly vector clip art. Thanks. [Update: now the app is $.99 and there are no in-app purchases. I'm trying different ways to make money. Still no ads.]

Sunday, November 24, 2013

Change of Distribution Policy for Signal GH

Today I saw this review for Signal GH my HDHomerun utility: Don't buy if you're in Europe 1 Star Bought this without detecting that it is USA only. I wasted my money. Should have said on the App Store. Ripped off. Now obviously, this user didn't write me to try and resolve his problem. And I don't know if he didn't notice there was a setting for using the European TV standard, or if he did and it didn't work, or if he was upset that US users got the benefit of a map of broadcasters, but the fact of the matter is I don't know that Signal GH works in the UK or not; I just assumed it would. So, I am stopping distribution in Europe (excepting Denmark where I've been distributing for years without complaint). If someone in the UK or any other European country would like to try it out, let me know and I'll turn distribution back on temporarily. And users of the App Store should know they can contact Apple support shortly after purchase for refunds. [Update: Apparently the version I just put on the App Store 1.4.1 is broken for people who haven't done an initial scan and this is probably the problem the U.K. user saw. I've removed it from distribution and will be posting a 1.4.2 update presently]. [Update 2: I've submitted a 1.4.2 update to the App Store, and I apologize for the bad impression I've given to new users over last week. It was my error in not testing a clean install.]

Sunday, November 03, 2013

Touch GUI and Replacing Buttons With Gestures

I've been thinking a lot about gestures lately. I submitted a kids drawing app, Frog Draw, to the App Store this week, and while I'm proud of it, it certainly ended up different than the plan in my head when I first sat down in Xcode and started coding it. Much of this, comes because of a gradual realization that gestures are better than buttons. Here for instance was my first thought for a interface for modifying objects:
The idea behind this was that the user would tap an onscreen object, a square perhaps, and this item would appear to give options in button form, including a rotation button which would follow the finger in a circle as he twirled the whole edit ring and object around. I had it all worked out that the buttons would rotate with the ring's rotation. I was quite proud of the geometric perfection of its layout; it was a perfect hexagon inside a perfect ring. And then I actually tried to use it.
The ring was in the way of things, preventing me from selecting other objects. And what if the object was up in a corner, obscuring a button, which required redundant buttons such as the doubled X delete buttons in the above. No, this would never do.

So I went with gestures. Translating via dragging a finger and pinch and scale gestures could be easily enough done, but what was the gesture to delete something? At first, and for much of the development cycle, I went with an analogous gesture to the Mail app's delete swipe, a quick leftward flick.
But that turned out to be too unreliable, as it was hard to both distinguish between a normal leftward translation and a delete, so half the time, I just ended up moving the object a bit to the left, or worse, an unintended deletion. Yes, I have unlimited undo, but still. In the end, I just accepted a drag of both the finger and the object into the toolbox area as a delete. Easy to do and easy to understand.

Which brings up another idea, the unimportance of direct manipulation. In the real world, if you wanted to drag a card around on a table top you'd put your finger down on the card and move it around, the finger always obscuring some of the card. In the digital world of the touch screen the programmer has a choice. If I have a selected object, why do I have to have my finger over it, preventing me from seeing where exactly I want it to go. Oh, I could bring up a loupe view to show what's under my finger, and perhaps magnify it, but won't that take up even more precious screen space? So, I decided that I could pinch, rotate and translate anywhere in my document view and it would change the selected object.
As I was testing my app, it became more and more obvious I needed an easy way to change the front to back order of objects. Many times, I'd draw a mask (maybe a frog's face) and want to put a photographic face behind it, peering through a hole. In the old days of desktop apps, this would be a menu item or a button or both, but not in mobile where space is precious. For a long time, I was intending to have a table of all the objects in a document layer, and the user would manipulate z-order by dragging one object cell to a different position (and I still might do this) but it seemed like this was a good opportunity for another gesture, and the easiest that came to mind was a 2 finger up or down drag.
This worked out quite well, as I could bring an object up or down several levels in a single swipe. I even used the same mechanism to re-order layers if no object was selected. What I'm giving up here is discoverability, few users will discover this behavior on their own. I put a diagram in the initial onboarding dialog, but time will tell if that's enough.
Not that the button is dead, I had thoughts of dragging color swatches onto objects, but that was just too much to ask of the user in terms of consistency, so I just have simple buttons to apply colors or other style settings to the selected object. Look for Frog Draw in the App Store next week.

Thursday, September 19, 2013

Typing iOS Icons in SVG

I know many people when faced with the task of making an icon will fire up Photoshop and start pushing pixels. But lately, when graphics are needed, I've been jumping into my text editor, BBEdit, and creating an SVG document from scratch. Like this one for—appropriately—my new iOS app about learning and playing with SVG paths called SVG Paths:



Sorry about what my code formatter is doing to the rect element in the above.

I can then open the result in iDraw, scale the drawing down to the appropriate size for an iOS icon and save it out as a PNG.  For smaller icon sizes, 29 pixels? really?, I might tweak it a bit to emphasize just one sub-element. The advantage for me is I get exactly what I expect with mathematically pure shapes. And it's a lot simpler than the times I've programmed graphics in raw Postscript. It wouldn't necessarily be a good way to make an elaborately textured icon, but with the flat simplicity mantra of iOS 7 the stark clean lines of SVG are a good fit.

Oh, and here's an animated GIF my new app can generate of me drawing the icon:

Wednesday, September 18, 2013

Solid Signal Blog Likes TV Towers USA

I heard about Solid Signal Blog on the HTGuys podcast, and sent them a copy of my TV Towers USA app, and they gave it a very positive review. I bought both my home's antenna and pre-amp from Solid Signal and they work great so it's mutual.

Tuesday, September 17, 2013

Why I Raised My Apple TV Rating from 4 to 5 Stars on Amazon

I take product reviewing seriously, and my Top 500 Reviewer badge on Amazon (#200 as of this morning but steadily getting worse) means more to me than it should. I'm the kind of reviewer who will go back and reevaluate a product over time, often for the worse, but sometimes, gratifyingly for the better. And so, as I revised my review of the third generation Apple TV this morning to include the fact Amazon's Instant Video app now supported Airplay streaming, I came to the realization that the Apple TV was now a 5 star product. It had somewhat snuck up on me due to continual, gradual feature improvements by Apple.

I owned the original, big, hot, Apple TV and that was definitely not a 5 star product. Limited, energy inefficient, a means to watch rented TV shows (remember that) and a few other things. When the 2nd generation came out I gave my original to my brother and my 2nd and 3rd generation Apple TVs have been happily getting updates ever since as they benefit from being an iOS device with all of the work Apple puts into improving and adding features to iOS devices and the iOS ecosystem.

Starting with:

  • Energy efficiency. I have a 30W Intel Atom home theatre PC which overheats and doesn't give as smooth an interface as a 1 W Apple TV.
  • Consistent Interface. Apple TV apps/channels all look about the same. You don't have to learn anything switching from Netflix to YouTube.
  • Connectivity. I love that the Apple TV comes with Gigabit Ethernet in addition to Wi-fi. 
  • TOSLink. Not everyone has a HDMI capable receiver, but if you've got a 5.1 speaker setup Apple has you covered with optical sound if needed.
  • Basic content like Netflix, YouTube, iTunes purchases.
  • Free TV shows, a couple times a week, I go and see what's new in the list of free TV shows. I've ended up buying several shows I like this way, like the series of Mickey Mouse short films.
And then Apple started adding features:

  • Bluetooth Keyboard support. I don't even know where my Apple TV remote is. It's so nice being able to type in searches and passwords from a real keyboard. Any Bluetooth keyboard will do, from a cheap iHome to an actual Apple Bluetooth keyboard.
  • iOS remote App. For when you can't find the keyboard or are too lazy to find it. 
  • Airplay. Here's something I do frequently. I listen to podcasts in the shower on my Airport Express connected shower speaker; I get out of the shower and switch the podcast to the speakers in my basement Apple TV. 
  • Airplay Video: I use mirroring from my MacBook to get content unavailable on the Apple TV itself, such as MPEG2 streams I recorded off my antenna. When OS X Mavericks comes out this will be even better as the Apple TV will come up as 2nd separate non-mirrored monitor.
  • PhotoStream. Yes. My wife takes a picture on her phone and it magically appears on the Apple TV's screen saver.
  • More content: Separate apps for the NBA, trailers, Japanese anime, MLB, Flickr... Plus services I don't have access to without a cable plan like HBO, or things I wouldn't pay for like Hulu. 
  • 3rd party app support. As I said, the support for Amazon Prime videos via Airplay pushed me over the edge from 4 to 5 stars. 
  • 720p and then 1080p video. There isn't a huge difference between the two if your TV has a good scaler, but it blows away the video quality from before Apple started streaming HD. I had to upgrade my Internet connection to use it, but it's been worth it. Compare with the horrible "digital downloads" that you redeem in iTunes from many Blu-rays.

So, it snuck up on me. This little Apple hobby has become a great product.

Thursday, August 15, 2013

Apple Devices and Chinese Power Outlets

This summer, 2013, I spent June traveling in China with my wife, children and an assortment of Apple devices. This blog item is about power outlets.

The first thing you might be concerned about is plugging into a wall outlet at the end of the day. For instance, here is what confronted me at a typical Chinese hotel room's desk.

Chinese power is 220V 50Hz AC out the wall, unlike the 120V 60Hz AC I'm used to in the United States. Fortunately, Apple ships its devices with universal power supplies capable of adapting to the voltages of the world. All you have to do is choose the appropriate 'duck head' adapter.
You can just plug an American style duck head into the wall and have it work, it fits OK into this style combination port you see all over the place.
However, I strongly preferred the European duck head due to its stability. The American adaptor had a tendency to pop out, especially the heavy charger for my MacBook Pro. The European head also came in handy as we had a long layover in Zurich and took the opportunity to top off. (By the way, Swiss Air is a well run airline staffed by helpful people.)
So all my Apple equipment charged very well and stayed in place. 
You might ask where one gets different duck heads, well Apple sells a World Travel Adapter Kit although it's on the pricey side for what you get, but it's conveniently in one place. The included power supply is for iPhones, but you can use the duck heads with the power supplies which come with MacBooks, iPhones, iPads, or iPods.

Apple isn't the only company whose products will just work. Here's the power supply for a Kindle Fire which clearly states it will work at between 100 and 240V and between 50 or 60Hz. However, no cool adapters.
My Oral-B electric toothbrush had no such comforting label on its charger, so I risked putting it into the 'shavers only' 115V outlet found in most hotel bathrooms. It didn't burn up, but presumably running it at 50Hz was not optimal and might harm it in the long run.
So, you may want to purchase a power converter before starting your journey for some non-Apple gadgets. 

I hope you were aided by this blog entry and that you have an enjoyable and educational journey in China. It's a lot to take in.

Monday, August 05, 2013

AppleTV without Remote, Setting up WiFi

I took my AppleTV to visit relatives, but the TV was far from an Ethernet port, and I didn't have the physical remote. So how to setup Wi-Fi? I dragged the TV next to the router so the AppleTV could be plugged into Ethernet, then I discovered you can't setup an AppleTV for WiFi while it's plugged into Ethernet, but if I unplug the from the network my iPhone's remote app can't control the device long enough to enter a WiFi password.
I could have setup a Bluetooth keyboard, but I hadn't brought one either.
I wondered if I could simulate a Bluetooth keyboard with my phone, but apparently you can't do that in iOS so there is no such app. Then I wondered about simulating a keyboard with my Mac, and there is indeed a keyboard simulator available in the Mac App Store: Type2Phone. Reading the setup documentation is required, but in a few minutes I was sending keystrokes to my AppleTV, and I was able to setup my AppleTV for WiFi.

Thursday, May 09, 2013

Building an iOS Framework - Recommendation

I'd just like to recommend this excellent tutorial by Jeff Verkoeyen on creating a framework/resource bundle for distribution of libraries.

Friday, May 03, 2013

How Many Spanish Radio Stations Are There In The United States?

With immigration reform in the news, I was interested while testing my AM Towers USA iPhone app how many AM radio stations serve the Spanish market in Minneapolis. So I took a few minutes to use my apps to generate some images of Spanish format (Spanish, Spanish Talk, Mexican, Latino, Salsa...) radio formats in the USA. FCC data, mixed with formats reported on Wikipedia indicate there are 289 FM stations serving up Spanish market programming in the United States+Puerto Rico.
And 268 AM stations.
These were generated using my AM Towers USA and FM Towers USA apps running in the iPad simulator, but I did tweak the code temporarily to allow so many stations to be displayed at once.

Saturday, March 30, 2013

Extracting Radio Format Information from Wikipedia

I have two radio station apps in the App Store, AM Towers USA which is free, and FM Towers USA which is not. They try to map all the active radio stations in the United States. The information comes from two places, the FCC and Wikipedia.
If my apps are missing a radio station, it's likely because I couldn't find a format for them on Wikipedia. Assuming the station has a Wikipedia page, which the vast majority do, then either the format is missing from the page's radio infobox or it's badly formatted. As a public service, I've reformatted dozens of these boxes like this one for a small station in Arkansas.
{{Infobox radio station
| name                 = KDQN
| image                = 
| city                 = [[De Queen, Arkansas|De Queen]], [[Arkansas]]
| area                 = 
| slogan               =
| branding             = 
| frequency            = 1390 [[kHz]]
| repeater             = 
| airdate              = 
| language             = Spanish
| power                = 500 [[watt]]s day
| class                = D
| facility_id          = 30600
| coordinates          = {{coord|34|1|57|N|94|19|43|W|region:US-AR_type:landmark|display=inline,title}}
| callsign_meaning     = 
| former_callsigns     = 
| owner                = Jay W. Bunyard & Anne W. Bunyard
| licensee             = 
| sister_stations      = 
| webcast              = 
| website              = 
| affiliations         = 

It's missing a format field, so AM Towers didn't pick it up, but the text of the article says it broadcasts a Spanish Music format. Now, I don't know what specific kind of Spanish music this station broadcasts, so I can't in good faith edit this entry, but let's assume it's Spanish Contemporary. I'd insert a field, like so:
| format = [[Spanish Contemporary]]
The [[ ]] brackets are important as they will cause a link to be shown to the Wikipedia page on that radio format, or in this case to the page on the various regional styles of Mexican music.
But what if the station broadcasts in another format, like Spanish Oldies, well then I'd insert:
| format = [[Spanish Contemporary]]/[[Spanish Oldies]]

There isn't any consistency as to what people use to separate a list of formats. Some use semicolons, others slashes, or spaces or HTML breaks. I wish they were consistent, it'd make my job easier.
Then I make sure that all the [ are balanced by ], and that all the { are balanced by }. A stray } can ruin an otherwise parseable infobox.

Thursday, March 14, 2013

Objective-C Categories and Keeping Functionality Separate

Ever since spending months on a never finished project to tear the rendering code out of a large commercial application and into a QuickLook plugin, I've been hypersensitive to dependencies in my code. All of my code is on a need to know basis from the other objects in the project. There are a variety of techniques in Objective-C to aid you in decoupling your code, but the one I'm writing about today is the category.

Let's say I'm writing a document framework, something I'll be using in many apps, each with different needs. Some apps will need editing, most apps will need importing from documents, some will need writing to documents, most will need onscreen rendering, some will need conversion to export formats.

Naively, I could just add all that needed functionality into each of my class's source files. But the Objective-C category allows me to segregate my code by functional topic.

@interface DocumentNode : NSObject
@property(strong, nonatomic, readonly) NSString* type;
@property(strong, nonatomic, readonly) NSDictionary* attributes;
@property(strong, nonatomic, readonly) NSArray* children;
@property(strong, nonatomic, retain) NSObject* cache;
@property(strong, nonatomic, readonly) NSString* name; // an attribute

-(id) initWithAttributes:(NSDictionary*)startAttributes 

and then if I need to have a method to edit the node because I'm writing an editor and not just a viewer, I can create a separate file with an 'Editing' category:
@interface DocumentNode(Editing)
-(DocumentNode*) cloneWithAttributes:(NSDictionary*)newAttributes;
-(DocumentNode*) cloneWithNewChildren:(NSArray*)newChildren;

or if I need a place for my rendering code
@interface DocumentNode(Rendering)
-(BOOL) renderIntoContext:(CGContextRef)quartzContext  

Now, categories are limited in that you cannot add new member variables to your classes via categories like you could by subclassing your objects. You could use objc_setAssociatedObject to implement the storage for a property, but that would probably be too over the top for just keeping implementation separate. When faced with this design problem, I punted and put the property in the main implementation file, as in the following case where my undo ad redo stacks are unused unless the document needs editing functionality.
@interface GHDocument : NSObject
@property(nonatomic, strong) NSMutableArray* undoStack; // only used if Editing is included
@property(nonatomic, strong) NSMutableArray* redoStack;
In practice, once the code is factored in this way, it can be reused modularly. If I have a project that just acts as a viewer, I just don't include the 'DocumentNode+Editing.h' in my other source files, and I don't compile the 'DocumentNode+Editing.m' file by unchecking it's inclusion in Xcode. For small projects this might not matter much, but when you are building up a large codebase or want to reuse just a small bit in another project, you'll regret not factoring things for modularity from the very beginning.

Friday, February 01, 2013

A Proposed Tweak to The Location Services Arrow

FTC Announces App Guidance

The Verge's description of the guidance is fairly ridiculous, there is no way people would put up with constant notification that their location was being accessed. The OS already does so with the little arrow icon towards the end of the status bar.

Since the government, the FTC, can't think of any productive way to prevent the criminally minded from doing bad things, they want to punish users by giving them a string of mind numbing, experience ruining dialog boxes. Well, if it will satisfy their inner nanny, I propose that Apple add to the variations of the arrow, they already have one for background location services, how about one that developers can set when they get a location and send that location to a server? 

So if I am a weather app, and I need to send my location or a proxy of my location (for instance a region around my location) to a server, I set a property similar to UIApplication's networkActivityIndicatorVisible property, maybe, a geolocationNetworkActivityIndicatorVisible property.  Then the OS can do something like change the arrow icon to something distinct like (2 minutes of Photoshop Elements):
Do I think this is useful? No. All this notify the user stuff does not beat the "doing nothing is a high standard" bar, but it's less obnoxious than a modal alert dialog.

[Update: I guess I should point out that none of my personal apps send geo-location back to my servers, nor do they contain ads, so they don't leak geo data that way either. AM Towers USAFM Towers USATV Towers USA, and Signal GH all make calls to Map Kit, so either Google or Apple at least could know somebody is interested in broad geographical regions, while FM Towers USATV Towers USA, and Signal GH ask the FCC website for contour data when you tap on an antenna pin, so the FCC would know somebody was interested in a given broadcast station, which might be 1000 miles from the phone with the given IP address which made the query. I don't think either of these cases would merit notifying the user, but Apple would have to give guidance should they adopt something similar to my proposal.]

Sunday, January 27, 2013

Wherein I Categorize American Radio Formats

For my AM Towers USA, and FM Towers USA mapping apps, I had to compress well over a hundred radio formats into a handful of categories (it ended up being 11) so here's the raw source:

    NSArray* listOfCategories =
    @[@"Ethnic Formats", @"Cajun Music", @"Adult Urban Contemporary", @"Black Gospel",@"Classic Hip-hop", @"Contemporary Latino", @"Hawaiian Music", @"Hip Hop", @"Hispanic Rhythmic", @"Hispanic Urban", @"Holy Hip Hop", @"International language", @"Latin American music", @"Latin Pop", @"Latino", @"Mainstream Urban", @"Merengue Music", @"Mexican", @"Native Americans in the United States", @"Polka music", @"Polynesian culture", @"Reggae", @"Reggaeton", @"Salsa Music", @"Soul", @"South Asia", @"Spanish Language", @"Spanish Adult Hits", @"Spanish Contemporary", @"Spanish music", @"Spanish Norteno", @"Spanish Oldies", @"Spanish Religious", @"Spanish Top 40", @"Spanish Variety", @"Tejano", @"Urban Adult Hits", @"Urban Contemporary Gospel", @"Urban Gospel", @"Urban Oldies", @"Vietnamese", @"World Ethnic"],
    @[@"News Formats",@"News"@"All News Radio", @"News/Talk", @"Classical Music/News", @"Public Radio", @"Weather", @"Public Broadcasting", @"Sports", @"BBC World Service"],
    @[@"Talk Formats", @"Talk", @"News/Talk", @"Christian Talk and Teaching", @"Conservative Talk", @"Hot Talk", @"Progressive Talk", @"Public Affairs Programming", @"Radio Reading Service", @"Sports Talk", @"Talk/Personality", @"Comedy", @"Educational", @"English Language", @"ESPN Radio", @"Home Shopping", @"Non-commercial Educational"],
    @[@"High Brow", @"Beautiful Music", @"Classical Music", @"Classical music/News", @"European Classical Music", @"Jazz and Classical", @"Jazz"],
    @[@"Country Formats",@"Country"@"Classic Country", @"Classic Country Music", @"Contemporary Country", @"Progressive Country", @"Current Country",@"Hot Country", @"Real Country", @"Mainstream Country", @"Modern Country", @"New Country", @"Texas Country", @"Today‘s Best Country"],
    @[@"Religious Music Formats", @"Religious Music", @"Black Gospel", @"Bluegrass and Southern Gospel", @"Christian Adult Contemporary", @"Christian Alternative Rock", @"Christian Contemporary", @"Christian Music", @"Christian Rock", @"Contemporary Christian Music", @"Contemporary Inspirational", @"Gospel Music", @"Holy Hip Hop", @"Inspirational music", @"Southern Gospel", @"Urban Contemporary Gospel", @"Urban Gospel", @"Worship music"],
    @[@"Classic American", @"Americana", @"Big Band", @"Bluegrass", @"Blues", @"Cajun Music", @"80‘s Hits", @"1990s in Music", @"Active Rock", @"Album Oriented Rock", @"Bluegrass and Southern Gospel", @"Children‘s Radio", @"Chillout", @"Christian Rock", @"Christmas Music", @"Classic Hip-hop",@"Classic Hits Oldies", @"Classic Rock", @"College Rock", @"Easy Listening", @"Gospel Music", @"Indie Rock", @"Jazz", @"Lite Rock", @"Mainstream Rock", @"Modern Rock", @"Smooth Jazz", @"Pop", @"Punk Rock", @"R&B", @"Rhythmic Oldies", @"Rock", @"Soft Rock", @"Soul", @"Southern Gospel", @"Southern Rock", @"Top 40", @"Tropical", @"Variety Hits"],
    @[@"Contemporary Music Formats",@"Contemporary"@"Adult Album Alternative", @"Adult Alternative", @"Contemporary Hit Radio", @"Contemporary Hit Radio/Pop", @"Adult Contemporary",@"Hot Adult Contemporary", @"Bright Adult Contemporary music", @"Adult Hits", @"Adult Standards", @"Adult Top 40", @"Adult Urban Contemporary", @"Alternative Radio", @"Chillout", @"Christian Adult Contemporary", @"Christian Alternative Rock", @"Christian Contemporary", @"College Progressive", @"Contemporary Christian Music", @"Contemporary Inspirational", @"Contemporary Latino", @"Electronic Music", @"Hip Hop", @"Independent", @"Mainstream Top 40", @"Modern Adult Contemporary", @"Modern Rock", @"Smooth Jazz", @"Pop Contemporary", @"Rhythmic Adult Contemporary", @"Rhythmic Contemporary Hit Radio", @"Rhythmic Contemporary", @"Rhythmic Top 40", @"Smooth Adult Contemporary", @"Soft Adult Contemporary", @"Spanish Adult Hits", @"Spanish Contemporary", @"Top 40, Hot Adult Contemporary", @"Top 40", @"Urban Adult Hits"],
    @[@"Religious Formats",@"Religious"@"American Family Radio", @"Catholic", @"Christian", @"K-LOVE", @"Christian Talk and Teaching", @"Fundamentalist Christianity", @"Modern Worship", @"Religion", @"Religious Broadcasting", @"Spanish Religious"],
    @[@"Hard to Categorize", @"Campus Radio", @"Alternative/Free Format/Adult Contemporary", @"Children‘s Radio", @"Christmas Music", @"College", @"College/Oldies/Country/Hip-Hop/Rock and Roll", @"Commercial broadcasting", @"Community Radio", @"Dance music", @"Diversified", @"Eclecticism", @"Educational", @"Freeform", @"High School", @"Home Shopping", @"Indie Radio", @"Mass Appeal", @"Music", @"Non-commercial Educational", @"Non-commercial", @"Student", @"Stunting", @"Urban Adult Contemporary Oldies", @"User-generated Content", @"Variety Hits"],
    @[@"NPR Affiliates", @"NPR", @"National Public Radio", @"NPR news, classical music, jazz"]

Sunday, January 06, 2013

Using Unicode and Emoji In Your Interface

In my newly released iOS app, FM Towers USA—map of most of the FM radio stations in the United States—I had the problem of wanting to customize the popup indicator which appears when you select a pin on the map, but I didn't want to work too hard on it. All the MKAnnotation protocol in MapKit allows is returning strings for the title and subtitle.

I could spend a lot of time adding custom overlays and hit testing to how I deal with Map Kit, or I could just insert a few colorful Emoji characters into my strings.  (Unfortunately, I don't know how to get Blogger to encode the blue diamond character for view even on OS X or iOS.) 

- (NSString *)title
NSString* result = result = [NSString stringWithFormat:@"%@ 🔷 %.1f", self.callSign, self.frequency.floatValue];
return result;
You might notice that I even made use of the Emoji characters in the images I generated for my map pins. Thus the guitar emoji became the catch-all icon for music like rock, rockabilly, R&B, while the cow represented the various country genres—I wish their was an Emoji cowboy hat. Hey, it's free, quality colorful scalable artwork, I'd rather use it than draw it.

And sometimes, making use of the huge number of characters in standard Unicode can save a lot of time, let's say you need to display chemical formula like H₂SO₄ well,  you might think you'd need a complicated NSAttributedString to insert the subscript codes, but no, all you need is to use the subscripted number characters. Or maybe you want to say 4 1/2, but want to make it pretty, well let me introduce to you the vulgar half character with 4½. I don't know why it's vulgar, it's so beautiful and elegant and has a few cousins ¼ ¾ ⅓ ⅔ ⅕ ⅖ ⅗ ⅘ ⅜ ⅝ ⅞ ⅐ ⅑ ⅒, all of which you can just insert into your source code or localization files.

So, the next time you need an image lain out within a string, look under the Special Characters palette found at the end of Xcode's Edit menu. [Update: I've just realized that iOS 5 has many fewer, and much uglier Emoji style characters, so if you target that platform, please check out the results in the simulator.]