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.

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.
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:
But what if the station broadcasts in another format, like Spanish Oldies, well then I'd insert:
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.
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.
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:
or if I need a place for my rendering code
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.
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
children:(NSArray*)startChildren
type:(NSString*)startType
name:(NSString*)aName;
@end
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; @end
or if I need a place for my rendering code
@interface DocumentNode(Rendering)
-(BOOL) renderIntoContext:(CGContextRef)quartzContext
withDocumentVisitContext:(DocumentVisitContext*)visitContext;
@end
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.
[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 USA, FM Towers USA, TV 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 USA, TV 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.]
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 USA, FM Towers USA, TV 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 USA, TV 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.
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.]
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.)
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.
- (NSString *)title
{
NSString* result = result = [NSString stringWithFormat:@"%@ %.1f", self.callSign, self.frequency.floatValue];
return result;
}
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.]
Subscribe to:
Posts (Atom)



