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.]

Monday, December 10, 2012

How to Ask for A Feature

A while ago, I complained about a rude request for a feature in How Not to Ask For A Feature. The flip side of this is this recent three star review for TV Towers USA.
Translators?
Not a bad app, very accurate and stable.

If I had one BIG complaint, this does not find TV translators and LP~LD (low power) stations.
 The reviewer was quite right this is a big problem. My only excuse for not adding translators is that I live in New England and translator stations are rare, but in the mountainous West, they are all over the place. So the next versions of TV Towers USA and Signal GH will include translator stations.

 And while I was mucking around in the FCC query pages, I noticed the feature of the FCC website where you can get contour plots in KML for most (some are missing) TV broadcast antennas. So that'll be in the next version too. The app will be greatly improved.

So thanks, Rnb4travel for the constructive criticism.

[Update January 29, 2013: after TV Towers USA 1.2 and 1.3 versions added translators, contour maps and searching, Rnb4travel posted a new 5 star review: “GREAT Improvements! Excellent app” so it all worked out.]

Monday, September 24, 2012

On Vectored Drawing In iOS Interfaces

As someone who spent spent seven years of his life writing a vectored drawing app, I have a deep rooted dislike of the bitmap. Bitmaps are bulky, bitmaps are inflexible. Bitmaps are a general pain. And yet oftentimes, it seems like many iPhone apps are drawn out entirely out of Photoshop.

Take this simple artwork from my iPhone app Signal GH. It formed the background of the graph forming the top portion of the app. I had drawn it in Photoshop Elements in less than 20 minutes.

And formed as in past tense, as I ripped it out this weekend as part of getting the app ready for the new 4 inch displays. Why, let's count the reasons.

  1. In this particular interface, the graph was the flexible element that made use of extra space when available and gave up space when needed. So, I would have needed a separate version for the iPhone 5/new iPod touch.
  2. I had not been handling the shrinking of the interface when a phone call comes in and the big green band comes down. Yet another flexible size needed.
  3. I needed artwork for Retina and non-retina, iPhone and iPad. With the addition of the retina iPhone, that's 5 different variants. 
  4. Should I decide to localize the app, the axis labels "signal quality" and "time" would require new versions per localization so 5n where n is the number of localizations. 
  5. It took up space. Not much but some. I take pride in that of the hundreds of apps on my phone, my apps, TV Towers USA and Signal GH are the second and third smallest behind an old flashlight app. 
So out went the UIImageView backdrop and in came a custom view with 3 subviews for the left axis, bottom axis and the graph itself, all lain out in the custom view's layoutSubviews handler. Here's the code for drawing the left axis:
@implementation LeftAxis
-(void)drawRect:(CGRect)rect
{
    CGFloat axisHeight = GetAxisHeight();
    CGFloat axisWidth = GetAxisWidth();
    CGRect myBounds = self.bounds;
    UIColor* strokeColor = [UIColor colorWithWhite:kGrayLevel alpha:1.0];
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetLineJoin(context, kCGLineJoinMiter);
    
    CGFloat myWidth = myBounds.size.width;
CGFloat myHeight = myBounds.size.height;
CGContextMoveToPoint(context,myWidth, myHeight-(axisHeight-axisWidth)); CGContextAddLineToPoint(context, myWidth-kShaftWidth, myHeight-(axisHeight-axisWidth)); CGContextAddLineToPoint(context, myWidth-kShaftWidth, myHeight-axisHeight+kShaftWidth); CGContextAddLineToPoint(context, 0.0, myHeight-axisHeight+kShaftWidth); CGContextAddLineToPoint(context, 0.0, myHeight-axisHeight); CGContextAddLineToPoint(context, myWidth-kShaftWidth, myHeight-axisHeight); CGContextAddLineToPoint(context, myWidth-kShaftWidth, kArrowHeadLength); CGContextAddLineToPoint(context, myWidth-kArrowHeadWidth, kArrowHeadLength); CGContextAddLineToPoint(context, myWidth, 0); CGContextClosePath(context); CGContextSetFillColorWithColor(context, strokeColor.CGColor); CGContextFillPath(context); UIFont* textFont = [UIFont systemFontOfSize:kAxisFontSize]; NSString* signalQualityString = 
NSLocalizedString(@"signal quality", @"signal quality label on left axis");
     CGSize textSize = [signalQualityString sizeWithFont:textFont];
    
    CGPoint drawPoint = CGPointMake(myWidth-kShaftWidth-textSize.height,
                                    kArrowHeadLength+kArrowHeadWidth+textSize.width);

    CGContextTranslateCTM(context, drawPoint.x, drawPoint.y);
    CGContextRotateCTM(context, -1.0*M_PI_2);
    [strokeColor set];
    [signalQualityString drawAtPoint:CGPointZero withFont:textFont];
    CGContextRestoreGState(context);
}
@end

Notice that I draw the entire y-axis, including the protrusion of the x-axis in one continuous path using a single filled polygon. You might be tempted to draw the line segments as individual stroked lines and only fill the arrowhead, but experience tells me that as long as the color is the same throughout, there will be fewer problems if I just fill one contiguous path. For example, you won't get anti-alias artifacts between adjacent elements. Also note that the text is localized and positioned by its measured size and not a magic number. 

The net win here is that I don't have to keep multiple artwork up to date, my app is smaller, I can localize. The operating system can bring down the call bar without distortion, and I'm drawing at the intended resolution of the screen. 

Monday, July 02, 2012

Goodbye to Mobile Me

Well, I just spent an hour moving all the images for this blog from Apple's abandoned Mobile Me hosting to my new genhelp.com domain. Still probably not going to be blogging much going forward.

Monday, May 28, 2012

On Leaving ChemDraw

After nearly 7 years on the job, I've left CambridgeSoft/PerkinElmer. It wasn't done lightly, I'll miss my codebase. I hope Mac users appreciate the near-perfection of their PDFs or how you can call any command from AppleScript or the text clipboard comes out with subscripts intact, or any of a thousand little details I slipped in. All the way while fighting against time as Apple deprecated the technologies it was based upon.

But the job just got less and less of a deal over time: from working home 2 days a week, to having to commute to the office every day, from having flexible hours to having to show up for a scrum meeting every morning. From having stock options+salary to only having salary.

So, I waited for an iOS job to pop up where I live, and grabbed it. It's a fine thing to be a (good) iOS developer. There's always another job to be had.

Tuesday, April 17, 2012

Magenta Apple TV

Just a heads up. Sometimes the auto HDMI setting of the Apple TV (this is the case with both the 2nd and 3rd generation models) doesn't work right. I have a 7 year old Ölevi 720p IPS LCD, which I'm normally quite pleased with picture-wise, but it doesn't like the Apple TV's auto setting, which apparently defaults to YCbCr. Using either the RGB High or RGB Low settings results in a good picture.

Monday, March 19, 2012

new iPad takes 6 hours to charge

I purchased the 32GB model of the Verizon LTE iPad, and while it is a great box (see my review on Amazon), it does have its problems, the most glaring of which is that it takes 6 hours to charge from 0% to 100%.



Obviously, if Apple doubled the capacity of the battery while keeping the USB charging constant at 2.1A/5V, then something had to give and that thing was charging time. Oh, how I miss Firewire.

Thursday, October 13, 2011

iOS 5 Killed (Temporarily) my AT&T Tethering

It came back when AT&T tech support told me to go to Settings : General : Rest and hit the Reset Network Settings button. Which dropped my call to AT&T and caused my phone to sort of reboot, but when it came back up, there was my tethering option in the Settings : General : Network pane.

Sunday, July 31, 2011

Why Some Internet Plugins Stopped Working With Safari 5.1

When I was a junior developer working his first pro job in 1995, we didn't have Safari we had Netscape, and if we wanted to make the browser do something it couldn't do, like play a video or render a PDF, we wrote Netscape plugins against the NPAPI. I wouldn't say we were happy because the API was complex and fragile, but it was what we had. Come forward 16 years, and I'm dealing with NPAPI plugins again. It's only been in the last few years that interested parties have been actively improving to move the API to something that fits in better with a modern OS X browser environment.

Step one was a couple years ago, and involved removing the classic QuickDraw based drawing flavored plugin, replacing it with rendering into a browser provided Quartz context. This also tightened up the rules of when a plugin could draw--in response to a drawing event only--no more drawing while in a mouse tracking loop.

Second step was changing the event model, from one loosely modeled around the pre-Carbon event loop to one loosely modeled around the messages received by a Cocoa view. When Safari dropped support for the old event model between 5.0.1 and 5.1, a bunch of Internet Plugins just stopped loading.

Third step involves the use of Core Animation layers as a drawing environment instead of the Quartz context. Currently an optional drawing mode, the CALayer based model is much more powerful and convenient then the alternative, and I suspect will become the primary flavor of NPAPI plugins on "OS X". They might even allow for the sharing of code between iPhone apps, Mac applications and browser plugins if developers are careful to wrap them carefully—CALayers are the underlying drawing environment of both UIViews (iOS) and NSViews (OS X).

As Safari 5.1 is the default browser on 10.7, and it was recently pushed out to 10.6 users, there are probably a fair number of users searching for updates and tardy developers getting their mouse tracking code finalized. Including me.

Wednesday, June 15, 2011

Neato xv-11 Robot Vacuum

I have never been a regular vacuumer. I have a moderately priced vacuum I bought 20 years ago while in graduate school, and I've probably gone through all of 8 bags. However, I'm a home owner now, with kids, kids who bring in bits of sand, drop crumbs everywhere, methodically chop bits of paper into confetti, and generally make a mess. And a wife who's busy starting her own business. My floors need vacuuming.

I perked up my ears on hearing the new editor of Engadget say his favorite product review of all time was the Neato xv-11 robot vacuum cleaner. I had, of course, heard of the iRobot Roomba—and drive by the iRobot headquarters in Bedford, Massachusetts 5 days a week—but had never heard of the Neato. Reading through the Amazon reviews gave me a picture of a more robust product than the Roomba, with more cleaning per charge and a square face capable of doing corners. So I bought one.

I like it quite a bit, but it cannot operate in the chaotic child-infested environment of my home without supervision. The kids are likely to drop a brush fouling yoyo string or a pile of clothes right in front of its charging station so if I set it to operate on a schedule, I'm likely come home and find it stopped after half a room with something jammed in its brush or it stuck behind a moved space heater. Scheduled cleanings are for people who's houses are always neat.

I've found that the robot and I work best as a team. I'll take it down in the basement, start it going in one end and I'll start picking up in front of it, quickly getting much farther in front of it so that I can clean up the basement in 10 minutes while it takes 45 minutes to vacuum. I'll still have to come rescue it a few times as it will sometimes wedge itself under a piece of furniture or get its drive wheels lifted up, but this takes a few seconds and barely cuts into the labor savings of me vacuuming as thoroughly. It will leave a few things on the floor, it isn't a human that will go back and forth and back and forth over a clingy bit of paper until it finally does get sucked in, but frequent vacuuming quickly leads to pretty floors. I just wish it could climb stairs.

Noise is like a distant jet turbine, not as loud as my old traditional vacuum but enough to distract you from any productive work.

One major problem is that for whatever reason, the Neato does not keep its clock time, like a blinking VCR it can't be relied upon to keep a schedule.

The Neato differs from the Roomba in its approach. The Roomba uses a random walk algorithm to achieve coverage in a room. The Neato finds a path around the circumference of a room and then vacuums it in a grid; I believe this is more efficient and allows it to cover more area on a charge. The Roomba also has beacon lights you are supposed to setup to aid in navigation, the Neato uses an internal laser range finder to map rooms. Whatever it is doing, it almost always knows how to find its way back to where it started, and it has an amazing ability to follow curved surfaces, like the circular base of my recliner.

My wife is most happy with the fact it will clean under beds, picking up years of dust bunnies the first time and keeping it tidy going forward. I'm most happy emptying it's reservoir, seeing all that dust and dirt that was messing up my floors, getting my feet dirty, and potentially getting into my lungs, and sending it along to the landfill.

Saturday, June 04, 2011

Fear, Uncertainty and .Net

[Update: Mary Jo Foley has posted a blog entry saying that her sources are saying that .Net will be available for immersive Windows 8 development. If true, it'd be nice if Microsoft would actually come out and say that.]

Microsoft demoed the tablet application framework for Windows 8 development Thursday. Going forward, traditional apps written in C++, .Net and other legacy technologies will be available to tablet users but utterly painful to use while away from one's keyboard and mouse. You could see a bit of that in the conference video where the presenter fumbles several times trying to snap Excel's document window into place. Old apps are going to be dreaded while in tablet mode. People will need new applications, and combined with the new application store, some developer is going to make a bundle on a touchable version of Notepad.

Flashy new apps were presented written in HTML 5 and Javascript. The interface might look like the Window's Phone 7 Metro UI, but this is not the Silverlight based technology beloved by C# coders. Pure web technologies with no plugins have been embraced by Microsoft, and this is strange and unexpected to me as an observer.

Why is this strange?

One. Microsoft developers are going to go through Denial, Anger, Bargaining, Depression and Acceptance, but mainly anger if this is true. .Net programmers believe they have the best tools, language and framework—as odd as Cocoa programmers might find that belief—they really do. They also tend to have a distain for dynamic languages like Javascript, especially Javascript with it's odd object model, and not quite C syntax. And they've spent the last years mastering the C# language and the massively large .Net frameworks. Any platform company gets its strength from its developer community and this just seems gratuitously hurtful. Finally, they expected to be part of a gold rush to fill both a new Microsoft Windows application store, and custom development orders for the new platform.

Two. It is my impression that Javascript is not an appropriate language for large app design—although I could be convinced otherwise. It's possible that the Javascript part was what was working, and it would be appropriate for lightweight widget like applications like weather apps, twitter feeds, etc. At a later date, Microsoft could add support for other frameworks. This would be the same path as Apple took with the iPhone—web development first followed by native development.

Three. It is conversely and perversely possible that is .Net itself that doesn't scale well in performance at least, and wasn't up to the task of being scaled up from a little phone screen to 30 inch monitors, at least in how Microsoft's OS team would have used it. Presumably, if Microsoft could have released a version of Office built off the .Net framework, they would have. I've had some tangential experience with .Net and complicated renderings, and it hasn't been good, but I'd always assumed things would work out given time to optimize.

Fourth. It is unlike Microsoft, to want their developers to use easily portable technologies. To the extent Windows 8 Javascript and HTML5 isn't littered with calls to Microsoft extensions and framework, will be an indication of a surprising lack of strength on Microsoft's part to convince developers to make unhedged bets on Windows.

As I said perplexing.

And frustrating for anyone seeking to use a base of code across a range of platforms. At one time, a story was building up that you could write a chunk of code in C#, and execute it on the Mac and Linux via Mono, on Java platforms via a code translator, on Android via either Xamarin's .Net framework or a Java translator, on iOS via Xamarin, on Windows Phone 7 via Silverlight, and Windows 8 tablet via either SIlverlight or extensions to .Net. Maybe it wouldn't run well, and wouldn't compete with natively developed apps, but the story was there for project managers to believe. And now that story is sounding iffy.

This might just be a miscommunication. It seems insane for Microsoft to take such an odd route. Maybe when the whole story comes out, JavaScript+HTML5 is just a presentation layer and the bulk of an app will be written in .Net., maybe they just don't have the .Net code ready to demo. But whatever it is, Microsoft owes it to its developers to let them know now, because they can't afford to wait to choose technologies.

Thursday, May 19, 2011

Hint, You Want Your App to be Hard To Program

I come up with many ideas for iPad apps. I have almost zero time to write them, but I do come up with ideas every couple weeks. And when I take my vacation time, I'll write one. How to choose.

Well here's an idea. Choose the hardest one you can write in the time allowed, assuming you think it will sell. Hard means people will be agreeable to paying $5 for an app. Hard means you won't have cut rate competition the next week. Hard means you can be proud of showing what you are capable of.

iOS is filled with programming tasks that should be hard but aren't. Want to play a H.264 MP4 movie, it's like 5 lines of code. Want to play streaming broadcast MPEG2 off your HDHomerun, well that's hard (and probably involves getting an expensive license from Dolby for the sound amongst other IP fees) to do without hardware decoding. Nobody will pay you for the former, there are people who will pay for the latter. Then again, the latter might also be impossible on even an A5.

So I have my own hard idea, which I'm not sharing, and I'll be spending the summer writing it. I'll let you know how it turns out.

Wednesday, March 09, 2011

Setup of iPhone 4 Hotspot

I called AT&T as soon as I saw that iOS 4.3 had gone live. When I called, they had no information about setting it up and didn't seem to be ready for any influx of setup requests. But, eventually I was handed off to a technician and that person was able to find out the setup information.

So over the phone, they were able to convert me from my legacy unlimited plan to the monthly 4 gigabyte plan with hotspot. I received a text message saying the data plan had changed, and the hotspot button in the network section of the general settings pane allowed me to access the hotspot settings. I turned it on, changed the password, and saw that it worked fine with my MacBook Pro. I'm using it right now.

Pretty cool.

When I plugged the syncing cable into my MacBook Pro's USB port, I got a notification of a new network connection. For whatever reason, I had to restart the Mac System Preferences application to get the "iPhone USB" connection in the Network settings panel to connect. I will delete this connection, as I wouldn't want to accidentally spend data when WiFi is available.

The CNET Online Speed Test gave me 1288 kbps which is about what you'd expect for mid-day in Cambridge on AT&T.

A Facetime chat over the Internet to my iPod Touch from my MacBook Pro was surprisingly good. My wife in Nashua only looked a little pixelated and the audio was as good as it ever is.

I'm looking forward to dropping my iPad service, which will save me $15 a month off my old $30+$30 plans, and also allow my kids to use their iPod Touch in the car, and occasional use of my MacBook. I've never come close to using 2GB on either my phone or my iPad, so there is no real downside in terms of cost.


So a great service to finally have on iPhone.

Wednesday, December 29, 2010

On Keeping Politics Out of Non-Political Blogs

This is a blog about technology and programming, that is its mission, and why readers find it*. They do not come for my political opinions. As far as my readers are concerned, I don't have them. It would be betrayal of the trust between me, and whomever visits my blog to insert snarky little bits of politics. I certainly feel betrayed and imposed upon when an otherwise fine blog or podcast feels the need to sneak in something political; do it too often and that podcast is out of my iPhone, i.e., Grammar Girl. Same with blogs, i.e., Roughly Drafted.

This comes up because of the last several minutes of the Engadget Podcast of Christmas 2010. Now the Engadget Podcast is my favorite podcast, I will actually re-listen to some episodes. It can be very funny, although the Engadget Bingo thing is lame, and it's about gadgets, so what's not to love? Well, when Joshua Topolsky and Nilay Patel decide that doing their actual job of putting on a gadget podcast and making amusing pop culture references is too unimportant and start verbally abusing Paul Miller, who disagrees with them, but more to the point, would rather talk about gadgets.

If Joshua or Nilay would like to build up an audience for a political podcast, that would be swell**. But taking their pre-existing audience, who's only shared interest is the love of devices, and subjecting them to their views is a breach of the compact that comes from their podcast being listed in the Gadgets section of iTunes.

Is this post an imposition on my readers? Well a bit. In it's defense, it is a meta-post about political content, not that content itself. And I have few frequent readers to offend.


* I'm not claiming I have regular readers, or many readers. I have people Googling specific technical problems and never coming back. If I'm lucky, this post will be read by a couple friends of mine, as it serves no practical purpose other than me venting.

** I wouldn't actually listen to such a podcast, because for whatever reason I have no interest in podcasts or TV shows about politics, although I read a large number of political blogs.

Tuesday, December 21, 2010

On The Need for MonoMac

I continue to listen to the Dot Net Rocks podcast even though I've yet to write a line of C#. It is a well done and even handed podcast, and one of these days I shall write a post about how the hosts demonstrate weekly how one can advocate a technology while maintaining credibility. But this post is about MonoMac, which I haven't used but someone at my company is, and I go to the meetings. If this means I'm writing without enough facts, then this might be a blog.

[Update: I've been informed that what I've written below is not possible in MonoMac. Apparently, the MonoMac developer community cannot imagine the concept that C# isn't the solution for every programming situation. I am not a publicly profane person, but I'm tempted here. But please keep on reading about an alternate universe where programmers don't fall in love with a language at the expense of reason.]


Tireless advocate for all things Mono, Miguel de Icaza was on the show this week and he got me thinking about why anyone would use MonoMac. And I do think many people will use MonoMac, but (I hope) not for the reasons Mr. de Icaza gave on the podcast.

To summarize de Icaza's pitch for using MonoMac. If you love C# and managed code, then you can use your favorite language to write Mac applications. You'll have to do at least some work outside your beloved Visual Studio, and you'll have to use completely unfamiliar APIs but at least it'll be in C#. And you'll get to use the whole Cocoa API, plus various other OS X technologies like Core Audio, Core Animation, etc., but they'll be wrapped in C# shims. Oh, and you'll get a strongly typed language instead of the horrors of dealing with the chaos of loose typing.

As someone who's spent his professional life writing cross-platform code, this is a really bad and limiting sales pitch. It is pitched at people who just don't want to learn another language for whatever reason, but would be willing to learn the entire OS X API, except trapped in a language for which it's calling syntax becomes cumbersome.

First, of all, you have to realize that the Objective-C language is small. It is not C++, which even a professional coder might never learn in its entirety. It is a elegant little language which adds object oriented extensions to C. The fact that you spend most of your time using those extensions doesn't make them any more verbose. It has had some further extensions in recent years, but it is still reasonably compact.

Also realize that the OS X APIs are huge, composed of literally thousands of messages, methods, structures, enumerations and constants in dozens of frameworks. I've been programming on OS X for a decade, and Apple adds APIs at a rate faster than I can learn them.

So, MonoMac saves you the trouble of learning a small language, while expecting you to master a large API which has been transmogrified to make sense to C# programmers. And the vast majority of the documentation and forum postings for that API assume it is in another language. That's not much of a pitch.

I used to work on a karyotyping application when I was living in suburban Chicago. It was Mac/PC and was written in C++. 90% of our code was shared between the platforms. We used standard application frameworks, at the time PowerPlant and MFC which relieved us of maintaing code every application uses, and gave us a lightweight entry into native appearances and behaviors. Almost all the document data structure and rendering code was cross-platform. So 10% of the code was dealing with the user facing part of the application or calling into native operating system services and the rest was vanilla C++ dealing with an abstract environment.

Consider a typical Model-View-Controller design. If one has a shared language like C# running in Mono, then we can factor our code such that all or almost all of the Model code is in shared vanilla C#, some or even most of the Controller code can be written in C#, although I'd prefer that Objective-C be used for Controllers on the Mac, and the bulk of the View code is no code at all, but what you get from the framework by using standard widgets, windows and other classes using the provided GUI tools. Basically, you want the framework to handle everything outside your document frame in your window. Depending on the application, you can have very high code reuse, or less if you need high performance access to operating system services, such as the example de Icaza gave of using the Audio Units API for sound processing. Regardless, this should be abstracted away and created with factories to make it callable from vanilla code.

So you'd end up with 4 kinds of code:
Vanilla C# that doesn't do much beyond manipulate vanilla objects and simple types, and implement various abstract interfaces or protocols.
Windows specific C# that makes use of Windows frameworks
MonoMac specific C# that makes use of native Mac services
Objective-C for Mac specific GUI code and isn't as awkward as C# would be.

For a lot of applications the first kind can be the bulk of code.


This takes discipline but it results in a more maintainable, focused code base.

I think that's a better pitch.

Not that I'm advocating it, I haven't tried to see if my decade old experiences with cross-platform design are transferable to the Mono runtime environment. Nor do I think Mono has proven itself enough for risking a project on it. I was floored that such a well known project only has 200 or so active users.

And I like Objective-C, it's a lot of fun.

Wednesday, November 03, 2010

Logitech Still Sells the Z-5500

I just yesterday replaced the decade old Logitech Z-5500 Digital speaker system in my TV room. It had spent several years on my desk when I had an apartment, and then spent the last 5 years giving surround sound to my house. It gave me reliability and a nice set of inputs. As a gadget guy, I'm just shocked that something as archaic is still being actively sold. Go look at its specification page and it touts its “Analog stereo-mini (on side panel of control center) for portable CD, MP3,or MiniDisc® players”. Now that's a blast from the past, the MiniDisc and portable CD player.

I replaced the Z-5500 with a Denon AVR 591 which is a real receiver with modern HDMI ports, modern audio codecs and an auto calibration system. Still, I am going to miss the conveniently small control module of the Z-5500.

Thursday, September 30, 2010

New version of Signal GH

Just got a note from Apple saying that a new version of my Signal GH iOS app to monitor over the air TV signal quality with HDHomeruns was approved. Which is good. I make little money on the product, but I like tweaking it.

It has two major features: an iPad layout and a map of broadcast towers in the United States (sorry Canada).
Both of these features were a lot of fun. The size of an iPad screen is luxurious and freeing. In this case, I just scaled everything up, as I think the tabbed interface works for this particular application. It might have been more iPadish if I'd put the settings in a popup control, but I felt people would be spending a good amount of time in setup, and would get nervous spending too much time in a spring loaded widget. Other iPad apps I've written have gone whole hog for using popups for accessing functionality.

The map was a joy to create. MapKit is a great example of a framework that Apple just gets right. Getting my TV towers from a Core Data database to the screen could not have been easier due to the flexible use of protocols and categories. However, the standard drop pin wouldn't work because TV stations tend to share a single tower. So I went with a custom flower petal annotation giving me room for 7 major networks and a generic logo.

Compass support was nearly as easy, although I did have to use my own custom annotation for that, when it would be nice just to set a flag and have it added. On the other hand, I felt the standard radar wave animation for the user's current location was too distracting and brought attention to the wrong detail, so I replaced it with a more static graphic merged with the compass.

Thanks to my sister, Sarah Howes, for doing the research needed for populating my TV station database.

Wednesday, September 15, 2010

Finally! Apple Embraces A Standard for Metadata in PDFs

I draw your attention to the header file CGPDFContext.h in the iOS 4 SDK:

void CGPDFContextAddDocumentMetadata
(CGContextRef context, CFDataRef metadata) CG_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_0);


The iOS 4 SDK has been out for several months but I hadn't noticed this change until today. Not that I have any use for it today on iOS, it's on the Mac where it is crucially needed.

Starting with Mac OS X 10.7, developers will be able to embed arbitrary XML data in the PDFs they can generate with Apple's APIs. [Update: I guess there is no actual requirement of XML based on just the API. I'd recommend standardizing on XML though.] They have decided to use the method advocated by Adobe in which a metadata stream object with a compressed XML payload is inserted into a PDF (Apple does the compression for you, you just have to provide a block of XML data). This is a good way of doing it, but more importantly, it is a simple and standard way of doing it. I would have preferred having an additional vendor tag where I could mark the metadata with a "com.genhelp.mydrawingapp" identifier, but that is not crucial; I can get that data from the XML.

Why is this Important?

As I've explained several times before, on the Mac we used to have this feature which I will call Round Trip Editing, wherein a user could make a drawing in one application, copy and paste the drawing into another application, and then later copy and paste back into the original application, and still be able to edit the drawing. Generations of Mac users relied on this feature to go from applications like ChemDraw into PowerPoint and back again.

This feature has been lost as applications transition from using the archaic PICT clipboard flavor to the modern and beautiful PDF clipboard flavor. There was no direct way to embed large data in Apple generated PDFs, and thus developers were left on their own to munge the format if they dared. And, with no standard or expectation of data embedding, applications did not bother to preserve the original PDF resulting in data loss.

Getting round trip editing working again has required 3 steps. Apple has had to provide an API for data embedding. Content generating applications have to be modified to use that API. Office applications have to be modified to return original PDFs to the clipboard when selecting a single image. With Mac OS X 10.7, step one will be here; about 4 OS versions tardy.


BTW Here is how to call it:

CFDataRef MakeAPDF(CFDataRef someXML)
{

CGRect mediaRect = CGRectMake(0, 0, 400, 600);
// use your own rect instead

CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0);
CGDataConsumerRef PDFDataConsumer = CGDataConsumerCreateWithCFData(result);

// mark the PDF as coming from your program
CFMutableDictionaryRef auxInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
CFDictionaryAddValue(auxInfo, kCGPDFContextCreator, CFSTR("Your Programs Name"));
CFDictionaryRef auxillaryInformation = CFDictionaryCreateCopy(kCFAllocatorDefault, auxInfo);
CFRelease(auxInfo);

// create a context to draw into
CGContextRef graphicContext = CGPDFContextCreate(PDFDataConsumer, &mediaRect, auxillaryInformation);
CFRelease(auxillaryInformation);
CGDataConsumerRelease(PDFDataConsumer);

// actually make the call to embed your XML
CGPDFContextAddDocumentMetadata(graphicContext, metaData);

CGContextBeginPage(graphicContext, &mediaRect);
// do your drawing, like this grey rectangle
CGContextSetGrayFillColor(graphicContext, 0.5, 0.5);
CGContextAddRect(graphicContext, mediaRect);
CGContextFillPath(graphicContext);
// end your drawing

CGContextEndPage(graphicContext);
CGContextFlush(graphicContext);
CGPDFContextClose(graphicContext);
return result;

}

And here's how to get the data back. Check that the XML is yours instead of some other program's.
CFDataRef ExtractMetaDataFromPDFData(CFDataRef pdf)
{

CFDataRef result = 0;

CFRetain(pdf);
const UInt8 * pdfData = CFDataGetBytePtr(pdf);
CFIndex pdfDataLength = CFDataGetLength(pdf);
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(kCFAllocatorDefault, pdfData, pdfDataLength, NULL);
CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithProvider(dataProvider);
CGDataProviderRelease(dataProvider);

if(pdfDocument)
{
CGPDFDictionaryRef docDict = CGPDFDocumentGetCatalog(pdfDocument);
CGPDFStreamRef metastream = 0;
if(CGPDFDictionaryGetStream(docDict,"Metadata", &metastream))
{
CGPDFDataFormat format = CGPDFDataFormatRaw;
CFDataRef streamData = CGPDFStreamCopyData(metastream, &format);
if(streamData)
{
if(format == CGPDFDataFormatRaw)
{
result = streamData;
CFRetain(result);
}
}
}
CGPDFDocumentRelease(pdfDocument);
}
CFRelease(pdf);

return result; // check to see if this is your XML
//remember to release result when done

}

Monday, August 23, 2010

The Three Numbers in Computer Programming

When I was working at a small company in Illinois, Vysis, my team had an architect named Ian Poole who taught me many things, and one of them was the simple fact that there are only three numbers in software design: zero, one and every. By this he meant, you can support the case where there are zero copies of an entity, one copy of an entity or an arbitrary number.

I ran into this problem when revamping my iPhone app,  Signal GH, to monitor antenna signal strength from an HDHomerun. I had mistakenly written it to handle two tuners in a single device. The code was littered to references to the "yellow" tuner and the "cyan" tuner, as that was the colors of their graphs. Well, Silicon Dust came out with a version with a single tuner, which sort of shot me in the foot. And then I bought that device which gave me three tuners on my network. I had a painful time backing out my bad design choice in favor of a more arbitrary number (I did limit it to keeping track of 8 tuners, but that number is kept in only one place and could be changed in a few minutes.)

The new version will be out shortly, fighting off one last bug.

Thursday, July 08, 2010

Wednesday, July 07, 2010

iPhone 4 improves on audio output isolation

I often hook up my iPhone to my car stereo and listen to podcasts while driving. I tend to drive with one earphone in place so I can click to pause or answer phone calls. In the past, whenever I turned off my car's stereo, I could still hear a indistinct and annoying noise coming through my headphones even though the sound was supposed to be going out the line level output in the phone's dock connector. Now, with the iPhone 4, it's quiet. Just another little improvement.

Tuesday, June 01, 2010

On Fixing the Personal Computer's Original Sin

A conversation with an old friend the other day brought up the limited file handling ability of the iPad. Apple really doesn't want you to deal with files as such on the iPad. When the original iPod came out, there was a lot of criticism about not allowing the user to maintain their own MP3 file trees and drag and drop onto the device as competing products allowed; and Apple kept it that way. These are two examples of rectifying one of the original sins of the computer: forcing users to deal in an ad hoc manner with individual documents as files.

Oh, you might say that it is freedom itself to be responsible for filing away today's expense report as a spreadsheet inside of a folder with 500 not quite identical others, or knowing where each of 10 versions of Margaritaville is located, and which is your favorite. To the contrary, it is just another example of the user being trapped by a lack of imagination on the software architect's part into doing something the computer should be much better at doing.

Or you might say that the individual file is a natural unit of information, like the Boolean bit; and that is not true, the computer file was invented by a man (unless it was invented by Grace Hopper, which I doubt); and computers could have evolved with some other mechanism; perhaps mimicking the human brain which I don't believe uses files.

If I were a bench chemist, and every day I drew some new variant of a steroid, where would I want my drawings, in individual proprietary documents, or in a database giving my work structure and context? Pretty obviously in a database. It creeps up on us, the slow flood of documents; the more organized among us can keep it together through ever deepening trees of folders and files, but eventually individual files in folders becomes unmanageable. I've been using a computer for 25 years, I look forward to at least another 40 years of use. There is no way I will be able to productively keep track of all my creations over that time in a tree structure. As it is, anything older than 5 years might as well be non-existent.

So the operating system vendors introduce search, and we get by like our computers are mini-Googles; as long as we can remember some key phrase we can find it; except when words fail us, or the document can't be parsed by the indexer.

And the cloud beckons. Anyone who thinks the cloud is just a well sorted FTP site, doesn't understand. The iPad is right now at one of those points where Apple can see but cannot provide, or even enunciate the ultimate solution, but does not want users to get into the habit of using individual files for their document needs; so we get the hacky solutions that will be cast aside the moment anything remotely elegant is provided. And I don't know what this solution is either. People have been trying to improve upon the file based system for years; the Newton didn't have files, BeOS had some sort of database file system. OpenDoc tried to get all documents to live together in harmony, etc. And none of these were a market success. Files will not die easily; and you will still have to export to a file for a good long time.

Baring a solution, the point of this entry was just to ask people to keep an open mind about files or the lack of them. Files are not the thing you want; you want to create, edit and view media and documents, and how they are stored in secondary to how quickly you get to them, and how safely they are stored.

Monday, May 24, 2010

Flash's History of Neglect on the Mac - An Example

I turn your attention to this apparently genuine June 18, 2008 forum comment by Tinic Uro, which I will quote:
We have identified the bottleneck in the Flash Player for OSX. Like in the other plugins the culprit is text rendering, in this case rendering using device text. This benchmark spends >50% in a single OSX function: ATSUGetUnjustifiedBounds. You can verify this yourself using Shark. I am working on a change which will cache the results returned by that API to where this call should completely disappear from the performance profile.

If everything turns out well I hope to see that change in future release. Some new numbers on my Mac Pro (note that these represent numbers which can change at any time if we decide to do things differently):

Before the change: ~8.5fps
After the change: ~28fps in Safari (~26fps in Firefox)

This speaks volumes about how little platform specific TLC Adobe historically put into the Mac plugin. A performance bottleneck as glaringly obvious as this should never have been seen by a user, much less bedeviled users and Flash developers for years before someone bothered to run Shark, or now days the CPU Sampler Instrument. Adobe must never have tried to optimize on the Mac at all; if I found a common use case where I was spending half my time measuring the same block of text over and over again, I'd joyously jump on the opportunity to make my user's lives easier because I could fix that in an hour. Apparently, Adobe couldn't be bothered to do the right thing until years later, and countless hours were lost by Flash developers trying to coax the Plugin into looking just as smooth on the Mac as it did on Windows.

And now that Apple is the big dog in the mobile application space, it's payback time for all the years of neglect and shoddiness. And with the eyes of the world upon it, Adobe is having to do the actual heavy lifting of getting decent performance and battery life out of a handful of Android phones just to prove Apple wrong. At least something good might come of this.

In the meantime, I've installed Click to Flash on my Mac and gotten iPad like silky smooth performance out of Safari. it is amazing what all those little ads cluttering up the dozens of open pages I tend to accumulate were doing to my poor MacBook.

Friday, May 07, 2010

Will the Next 13" MacBook Pro have an Optical Drive?

I've been following the news about the new MacBook 13" still having a Core 2 Duo when its bigger brothers have i5 and i7s. Apparently this was because there was not room to fit the added NVidia chipset needed to allow GPU switching. If this chipset problem persists, I'm going to bet that Apple removes the optical drive from the 13" MacBook Pro, giving room for the chipset and a bigger battery, and further I'll speculate that they begin selling a little NAS computer that includes: a shareable optical drive, a centralized iTunes server, a Time Machine server, and AppleTV functionality. This mashup of 4 separate products: Time Capsule, AppleTV, MacBook Air optical drive, and the iTunes library functionality makes a lot of sense, and would be billed as an energy efficient and environmentally friendly way to reduce redundancy. And somehow, this will tie into their cloud strategy which will be coming online shortly. And it would probably have enough GPU powered oomph for on the fly re-compression of video for use on iPhones and iPads.

Wednesday, March 24, 2010

Bye Bye Pentium 4 Server

No sooner had I assembled a mini home theater PC for the TV room, but Amazon Vine offered me a Zotac MAG HD-ND01-U which is basically the same thing in a more appliance oriented packaging.

The guts of my original HTPC will now be moving into the house's new Linux/MythTV server: add a large hard drive, a cheap DVD drive and a larger case. This is going to save me a lot of electricity. A Pentium 4 is a pretty poor choice for a lightweight server, and is now draining over $10 of power a month; the new Atom based server should draw less than a third as much energy and maybe less, as I'm hoping the more modern design will have better idle characteristics. I'll save quite a bit of money in the long run in mothballing my old Dell. And the new Atom/Ion motherboard should be fine for serving the occasional file and recording TV shows.

2.0 GHz Pentium 4 + hard drive + external hard drive = 110 W (or so) at idle
Atom N330 + laptop drive + sleeping hard drive = 25 W idle

If I pay a dollar for ever 10W per month then I'm saving around $8 a month or $96 a year, so the added $180 I'm spending will be paid for in 2 years (or in 4 years if I had had to buy a motherboard and RAM). And I'll have a quiet server that isn't annoying me constantly with its fan.

[Update: It's so pleasantly quiet in my laundry room today. Just have to migrate the svn server on the little NAS to the new server and it's going to be so peaceful in the basement.]

Tuesday, March 09, 2010

Holding onto Legacy PCI Cards is Limiting

After the happiness of putting together an NVidia Ion HTPC for the TV room, I've been looking at replacing the Linux server in the laundry room. It's a typical noisy, energy hog of a Pentium 4 Dell, non-gigabit ethernet, with multiple hard drives either inside it or in an external case. I'd like to replace it with a low power, quiet, modern model. I could collapse my MythTV backend, SVN server, and file server, into one box and save on the order of $15/month in electricity. So, I'd like to move to something like:
  • Dual core Intel Atom N300 processor
  • Ion chipset
  • Small SSD boot drive
  • Large (1.5 or 2.0TB) Green Drive
  • 2 GB RAM
  • mini-ITX form factor

The fly in this ointment is that I have a ATSC tuner on a PCI card in the current box (a very reliable PCHDTV 3000), and getting a mini-ITX Ion with a PCI slot is limiting. As far as I can tell, it is limited to one motherboard: the ASUS AT3N7A-I. And anytime I see customer reviews that include such tidbits as "noisy fan" or "uses more energy than other Ion motherboards" I start wishing for other options.

And the other option is to go with another network tuner. I already have one HDHomerun which along with my PCI tuner gives me the capacity to record three simultaneous shows on the rare days when that's a good thing. Replacing the PCI version with another HDHomerun would open up a larger world of Ion or Atom motherboards with more modern card slots. I even see that Silicon Dust has recently released an economy single tuner model which can be had from newegg for $81.97 shipped. And this will keep the new server cooler and quieter, as well as having another tuner Windows Media Center on my wife's computer can access. Win, win, win.

Tuesday, February 23, 2010

Could Apple Transition to Using iPhone Apps as Safari Plugins?

I've been knee deep in trying to keep an old style NPAPI (Netscape) plugin working under Snow Leopard, and believe me it is not easy. And one of the reasons it is not easy is that Apple has used the 64-bit transition to lock down what an NPAPI plugin can do and when it can do it. No longer are we allowed to do things like bring up our own windows, draw whenever we feel like it, create our own timers, track our own mice and generally do things the easy way; we have to live in the browser and follow the browser's rules.
I refer you to the Web Plugin Programming Topics Guide
Beginning in Mac OS X v10.6, on 64-bit-capable computers, Netscape-style plug-ins execute in an out-of-process fashion. This means that each Netscape-style plug-in gets its own process separate from the application process. This design applies to all Netscape-style plug-ins. It does not apply to WebKit plug-ins, nor at present to WebKit-based applications when running in 32-bit mode.)


It goes on to enumerate a large number of new restrictions on how plugins are supposed to operate in their new out of process home. At this point, it becomes pretty hard to justify using a NPAPI style plugin for any but the simplest plugin for Safari; it is just too strangling. So the mind turns to WebKit plugins which are basically Cocoa NSViews with a few limitations and added message handlers. As the quote above says they are not (at present) limited in such a way as Netscape plugins; in this way Apple is nudging people to use WebKit plugins if for no other reason that they allow you to do things that the NPAPI plugin do not.

And here we come to the idea for this posting, it seems as though Apple is interested in locking down and rationalizing Safari plugins. It is also reasonable that at sometime in the future, they will allow plugins for Safari on the iPad. It is also almost a given that those plugins will not be NPAPI style plugins, but will instead be UIView or UIViewController derivatives. And at that point, the question becomes, wouldn't the UIView style plugin with its simpler and more modern object design make a cleaner foundation for plugins for Safari on the Mac? Apple already has an iPhone simulator on the Mac. Of course, there would have to be some extension allowing mouse hovering events.

    Advantages
  • Code sharing between Mac and iPad
  • Plugins are closer in scope to iPhone Apps then full blown Mac apps.
  • At this point most Objective-C programmers are iPhone developers so developer pool would be larger
  • Expand iPhone apps to the Mac
  • iPhone Apps are used to being sandboxed

Anyway, just a thought.

Thursday, February 18, 2010

Inexpensive Ion HTPC

As I want to improve my free MythTV remote, and I needed to "eat my own dog food", I decided to build a HTPC box for the TV room to run the MythTV frontend. I'd been interested for a while in a small, low power PC based around the Nvidia Ion chipset. A little research indicated the board to get was the Zotac IONITX-A-U as it:
  • Came in a compact, mini-ITX form.
  • Has the 64-bit capable dual core Atom 330N processor
  • Has multiple output ports including VGA, HDMI for video and SPDIF coax and TOSLink optical for audio, amongst others.
  • Gigabit Ethernet
  • External power supply to keep the heat out of the case.

The most important feature was quiet, with the related property of energy efficiency. There are many cheap PCs out there, but few can play 1080i MPEG2 videos while draining 31 Watts.



I put in 2GB of RAM which allowed me to configure the BIOS to set aside half a gig for video memory. I removed the included wireless card, as I have Gigabit ethernet in my TV cabinet, and there's no reason to waste whatever minimal energy would be used by the card. Threw in a 60 GB laptop drive I had from a few MacBooks ago, and put it in a small case. The hardest part of installing MythBuntu 9.1 64-bit, was scrounging up an external optical drive. So, all in all a very easy thing to put together.

It works fairly well. I've put my children's DVD collection on a network share and use MythVideo to watch that and recorded TV shows. Since this was my first real standalone MythTV frontend, I had to rejigger my video setup such that both the backend and frontend used both the same relative paths to videos and movie posters (both Linux boxes have paths of the form /mnt/MyNAS/MyVideos and /mnt/MyNAS/MyPosters). Once this was all setup, it's extremely convenient having a kid's movie a few touches away. I had read complaints about the fan needing to be run at a lower speed, but I really can't hear it from the couch.

    Energy usage measured via Kill-A-Watt
  • Idle Running MythTV Frontend: 25W
  • Playing DVD Image: 26W
  • Playing 720p MPEG2 (recording of 24 on Fox): 28W
  • Playing 1080i MPEG2 (Big Bang Theory on CBS): 31W
I have got to figure out how to get the box to put itself to sleep when I'm not using it.

My old LCD TV is impossible to get the VGA just right (no surprise that) so I have a two inch black bar on the right of the display, but I'll be moving to use the DVI port as soon as Monoprice gets me an HDMI switch.

It's interesting as a Mac guy seeing this little DIY assembly. On the one hand, it's pretty inexpensive and I wouldn't want to waste a Mac on single purpose computing. On the other hand, it's pretty darn cheap. Here's a photo comparing a older generation Mac Mini with my system.


The Mini is definitely a superior computer in terms of build quality. The M350 case is nice enough, but it is still ill fitting sheet metal, and the ports still wiggle and flex when you try to push a connector in. In comparison, the Mini is just rock solid, and smaller while still having a faster processor and an optical drive. And it's a darn sight more attractive. On the other hand, the Zotac has a ton of extra ports, including a variety of internal SATA and USB connectors. Different needs.

Cost:
  • Motherboard: $185
  • RAM: $45
  • Case (with Shipping): $50
  • Hard Drive: Free
  • --------------
  • Total: $280

Monday, February 01, 2010

A Cell Phone Game for Children

I was playing hide and seek with my 2 and 3 year olds, and came up with this variation.

Requirements
2 Cell phones, one of which with a speaker phone mode.
Instructions
1) Call the phone with the speaker phone mode, answer and put it in speaker mode.
2)Have someone hide the phone in another room.
3)Let the child try and find it by yelling into his phone.

Tuesday, December 22, 2009

Get the PSD Files From Your Graphic Artists

If you hired a coder to write an iPhone app, you would expect the source code along with a delivered binary. Similarly, if you hire a graphic artist, you want their source files along with a finished bitmap file. In my experience, most graphic artists use Photoshop, which means they do their editing with PSD (Photo Shop Document) files, and will export out a TIFF, PNG or JPEG as needed. You never want to edit and re-compress a PNG or JPEG and you rarely want to edit a TIFF. Which means, if you want to re-use a graphic for another purpose, you need those PSD files, or whatever file formats are native to their editing software.

An Example:

Let's say I had contracted with a third party to design my beautiful company logo.

Great.

Now two years later I need a version without the fake glassy front. If I have the original, this takes the time it takes for me to launch PhotoShop Elements, uncheck a box next to the "glassy button" layer, and export the result to web.

If I only have the PNG file, I'm basically out of luck if I can't get ahold of the artist and will have to have someone else redraw the logo from scratch.

And not only should the PSD files be in your possession, they should be in your source control system, along with all the other critical changeable items you've spent so much time and money creating.

I've been in a situation where I have literally 100 toolbar icons in PNG form and I have no easy way to make a bigger size because the outsource artist has consistently neglected to deliver the original files. Frustrating.

Also, once you have the PSD files, have a look and see if they are well organized with ample use of layers, and layer naming. Maybe, there is no way to turn off the glass button by hitting the hide layer checkbox, maybe there is only one layer, and the artist is incompetent. Maybe that's why you had to ask.

Tuesday, December 15, 2009

MythBuntu 9.10 Quickly Dying Due to missing PCHDTV firmware

So, I have been pretty unhappy with my MythTV for the last week, as something was seriously wrong with it. It would work for a while and then performance would collapse to the point I couldn't even SSH into it. Apparently, there was a massive memory leak, and the swap became exhausted resulting in the kernel doing nothing but try to find a few extra bytes.

This was after I pushed the button to upgrade to 9.10. And if there is anything I less want to do is spend more time tweaking Linux.

Anyway, I took a few minutes this morning to look through /var/log/messages and found it was jam packed with:
...
Dec 14 06:53:40 MythTV kernel: [25073.152929] or51132: No firmware uploaded(timeout or file not found?)
Dec 14 06:53:40 MythTV kernel: [25073.653032] or51132: Waiting for firmware upload(dvb-fe-or51132-vsb.fw)...
Dec 14 06:53:40 MythTV kernel: [25073.653042] cx8800 0000:02:0c.0: firmware: requesting dvb-fe-or51132-vsb.fw
Dec 14 06:53:41 MythTV kernel: [25073.902202] or51132: No firmware uploaded(timeout or file not found?)
Dec 14 06:53:41 MythTV firmware.sh[23812]: Cannot find firmware file 'dvb-fe-or51132-vsb.fw'
Dec 14 06:53:41 MythTV kernel: [25074.401098] or51132: Waiting for firmware upload(dvb-fe-or51132-vsb.fw)...
Dec 14 06:53:41 MythTV kernel: [25074.401109] cx8800 0000:02:0c.0: firmware: requesting dvb-fe-or51132-vsb.fw
Dec 14 06:53:41 MythTV firmware.sh[23823]: Cannot find firmware file 'dvb-fe-or51132-vsb.fw'
Dec 14 06:53:41 MythTV kernel: [25074.780264] or51132: No firmware uploaded(timeout or file not found?)
Dec 14 06:53:42 MythTV kernel: [25075.281031] or51132: Waiting for firmware upload(dvb-fe-or51132-vsb.fw)...
Dec 14 06:53:42 MythTV kernel: [25075.281042] cx8800 0000:02:0c.0: firmware: requesting dvb-fe-or51132-vsb.fw
Dec 14 06:53:42 MythTV firmware.sh[23839]: Cannot find firmware file 'dvb-fe-or51132-vsb.fw'
Dec 14 06:53:42 MythTV kernel: [25075.503654] or51132: No firmware uploaded(timeout or file not found?)
Dec 14 06:53:43 MythTV kernel: [25076.001099] or51132: Waiting for firmware upload(dvb-fe-or51132-vsb.fw)...
Dec 14 06:53:43 MythTV kernel: [25076.001110] cx8800 0000:02:0c.0: firmware: requesting dvb-fe-or51132-vsb.fw
Dec 14 06:53:43 MythTV kernel: [25076.266695] or51132: No firmware uploaded(timeout or file not found?)
Dec 14 06:53:43 MythTV firmware.sh[23850]: Cannot find firmware file 'dvb-fe-or51132-vsb.fw'
...

Googling "Cannot find firmware file" dvb gave me this forum post which very helpfully gave the proper command line solution:
sudo apt-get install linux-firmware-nonfree
Now my MythTV can go 20 minutes without grinding to a halt.

Now, as to whether a missing firmware to a tuner card should bring a linux distribution to a halt is another thing entirely.

Saturday, December 05, 2009

MythBuntu upgrade and mythcommflag killing my MythTV

So, I pushed the button and upgraded the MythBuntu box in the basement, and bad things happened. Oh, the new MythTV interface is lovely. But the box became utterly non-responsive. Turns out that the server had spun up 4 instances of the commercial flagging process and each was taking one quarter of the CPU. And I don't even care if my commercials get flagged or not. Anyway, went into mythtv-setup and turned off commercial flagging, and things got a whole lot better.

How Not to Ask For A Feature

"best RDP" reviews my Signal GH iPhone app for HDHomerun

Title: "piece of junk"
Body:"This thing is worthless until they add QAM cable scanning capabilities."


First of all, the "they" is me, Glenn Howes—father of two, husband, software engineer, PhD Chemist, and occasional iPhone developer. I have made a grand total of $392.05 on this app, yet still found the time to release 2 updates to it when it made absolutely no monetary sense to do so. My work is not junk, it is of the highest engineering quality I could make it. I've spent hours tracking down bugs, ran static analysis of the code, put the executable through performance instruments for memory allocations and performance, and optimized the launch time. I did this when I had other paying projects waiting my time because I like this little app and I want it to be as perfect as I can make it.

It just lacks a feature you desire, a feature which is neither promised nor implied by the product description in iTunes. If you had e-mailed me requesting this feature, I would have seriously considered including it even though an app, who's primary function is monitoring antenna signal quality is not going to be very interesting looking at digital cable traffic. Now, I'm not inclined to add this feature, and you have only your bad social skills to blame.

Wednesday, November 18, 2009

My Unibody MacBook had Been Grinding to a Halt

I'm used to my Macs being reliable; of going months between forced restarts. And yet, two weeks ago, I found myself restarting my unibody MacBook a couple times an hour. Apps would just lock up with the spinning disk cursor, and I'd go to another app and it would soon lock up to. I associated this with something fairly disk intensive, like doing a Spotlight search, and I found that if I avoided Spotlight things would be OK most days. I tried rebuilding the Spotlight database, reinstalling 10.6.0, upgrading to 10.6.2, etc., with no help.

Finally, under the working theory something was wrong with my 500 GB Western Digital Scorpio Blue drive, I ordered and installed a new 640 GB Western Digital Scorpio Blue drive. And this worked. I don't know if it was the hardware or the completely clean install or the act of reinserting the drive, but it worked and my Mac is back to its normal reliable self. And I've got more disk space than I know what to do with. I learned my lesson a few years back about waiting for a hard drive to fail; I no longer give them a second chance at catastrophe.

This might be the last mechanical hard drive I ever buy for a laptop. SSD capacities are overtaking mechanical, and I would certainly pay $300 for a 512 GB SSD of reasonable read and write throughput. Maybe this time next year.

Monday, November 16, 2009

When the Books are Free - Amazon Vine

A few months ago, I noticed an invitation to join Amazon Vine program on my Amazon front page. I clicked on it, realized it wasn't a scam and signed up. And now I get 4 free things a month; from a limited catalog of newly released products. Mostly books are available, but I've also received software and iPod accessories. All I have to do is review three fourths of what I get and I stay in good standing.


It is awesome getting free stuff. The Phillips iPod dock/CD Player/Radio in the kitchen is sweet. But that is the exception, only the quickest get gadgets, and most of the time I have a choice between books and nothing. And getting a free book is hardly a bargain: It takes hundreds of dollars of my time to read, and I don't have the universe of books to pick from, I have whatever is in the newsletter, so I have to be picky and choose only titles which are of use—a book on business law for my wife's business—or of interest—a book on how to draw dinosaurs and aliens.


One nice thing is the motivation to read; to keep up my 75% review rate. It isn't often I read 3 books in 2 months. I just wish they offered more books about software engineering and fewer about adolescent vampires (or whatever constitutes juvenile fiction).


Amazon gets value from me. Under the theory I'll get offered items similar to things I buy or review, I bought a laptop hard drive from Amazon rather than Newegg; and I've been making sure to review anything that moves to push up my ranking. Just passed into the top 3000 woo hoo..


As to whether I'm unbiased about products I'm given to hold on to (I can't resell them), I think I'm OK. I certainly have a happy feeling about being given something nice, but on the other hand, a mediocre book is such a pain to trudge through, and a junky alarm clock just takes up space. So far, I've given out a variety of star ratings, pretty much in line with things I've purchased with my own dimes; maybe a bit lower as at least when I buy something on my own I have some expectation it will be of high quality.


Anyway, when you see the "Vine Voice" badge on a review on Amazon, you'll know it's somebody like me; just an ordinary consumer who likes to write reviews and lucked into getting free stuff.

Tuesday, November 10, 2009

When Apple Doesn't Follow It's Patterns: UIScrollView

A comment in UIScrollView.h
// override points. default is to call touch methods on the content subview. if -touchesShouldCancelInContentView: returns NO in order to start dragging after we have started tracking the content view, we don't drag and continue to feed events to the content subview. if -touchesShouldBegin:withEvent:inContentView: returns NO, we don't send events even if we don't drag

So basically, if you want to modify the behavior of how a UIScrollView drags, you need to create a subclass. Fine, that's basic polymorphism, but it isn't the way most UI behaviors are changed in Cocoa on the iPhone. Typically, behaviors are changed by the use of delegate objects, and there already is a UIScrollViewDelegate interface defined. It's not clear to me why touchesShouldBegin:withEvent:inContentView and touchesShouldCancelInContentView were not just added to the delegate.


Why is this important? Well first of all, one of the joys of Cocoa programming on the iPhone is that the object model tends to be more consistent then desktop Cocoa. Everything fits together, and you know where to look for the hook which allows you to customize your app's behavior.


Secondly, I think Apple was right to choose the delegate model over object subclassing. It's less fragile, in that you are less likely to rely on the original object's behavior being constant. And some Cocoa objects are basically impossible to subclass; for instance UIButton cannot be subclassed because it isn't a "real" object. And from a coding point of view, the delegate solves both the problem of changing behavior and intercommunicating between objects.


So, when you see a comment like the above, it sticks out like a sore thumb in what is normally a disciplined and consistent API.

Monday, November 02, 2009

New Version of Signal GH

Apple has sent me a notice that version 1.1.3 of Signal GH—my iPhone app to get the signal quality of OTA TV broadcasts with an HDHomerun—is available for download. There's nothing flashy about this release, just a variety of bug fixes, including some pretty vexing ones.

Monday, October 05, 2009

iPhone as Baby's First Computer

My son, Wil, wanted to paint on my unibody Macbook this evening. He turned four in September and this was the first time he'd wanted to drive Dad's computer. In the past, "we've" painted by him telling me to "draw an alien fighting a dinosaur." So, I setup Pixelmator in full screen mode, started him up with a blue brush, and let him go to town while I watched The Amazing Race next to him on the couch. And he basically figured it out, with occasional hints from me. He figured out how to switch tools without input from me, and was playing with radial gradients with an arbitrary selection mask in no time. I did notice he was drawing everything with his tiny thumb, which allowed him to put his weight behind mouse clicks on the MacBook's zero button trackpad; I think he would master a traditional trackpad, but the MacBook's trackpad allowed him to better transfer skills he learned from his first computer: my iPod Touch.


He's been using the iPhone interface since he was still 2, and I can still remember my astonishment that he'd mastered the drag to unlock maneuver without any help from me. One of many things, he figured out himself. Thankfully, he has yet to pick up typing my password so he has not been buying apps, although he will make daily trips to the app store looking for new games and will ask me to read the user reviews. He watches YouTube videos and my own collection of videos, plays games, paints, and looks through photos, and has been doing so this entire time. His 2 year old sister does the same, except she has no interest yet in all but the simplest children's games.


In the few times they've ventured to touch my MacBook, they expect that something will happen when they touch the screen. Direct manipulation is so obvious and engrained in how they deal with computers. I've worried if I could even teach them to use a mouse, which seems so foreign and backwards as an input device. But after today's session, I'm not worried. Wil can figure things out; the MacBook trackpad is close enough to what he knows. And he enjoyed learning. I could see how happy he was to learn that pressing the command and z keys would undo drawings.


Friday, September 04, 2009

Garbled Fonts in Xcode 3.2 Console with Snow Leopard

When I upgraded to Xcode 3.2 along with Snow Leopard, the output to the console was filled with apparently random garbage, and lots of white space. This also happened in Safari when a page used a fixed space font. I don't know exactly what was going on, but I think that at some point I had set both of these font sets to some version of either Monoco or Courier, and when I installed Snow Leopard, the particular font I had used went away which confused the applications in question.

Anyway, I went to the Debugger preference tab in Xcode (not the Fonts & Colors tab) and changed all the various console fonts to be some variant of Menlo. Similarly, in Safari, I set the Fixed Width Font to Menlo-13, and all was right with my world.

[Update: this also affected the AppleScript Editor, and the font was Courier]

{Update 2: Further investigation using the Font Book application found two conflicting copies of Courier /System/Library/Fonts/Courier.dfont with a modification date of July 2009 and /Library/Fonts/Courier TU with a modification date in June 1996. Removing the older font and restarting my apps has fixed the problem.]

Saturday, July 25, 2009

The Truthiness of Things I Said on DotNetRocks

When I recorded a recent episode of DotNetRocks I recorded my side of the conversation so that the sound engineers would have a cleaner copy of what I said then what went through the phone lines. And I've listened to what I said several times, and every time I do, I find a mistake I made; things I should and did know but in the course of talking quickly for an hour off the cuff didn't get quite get right.

  • Said that Adobe had taken over development of Java for OS X when I should have said they took over the Java SWT.
  • Should have kept my opinion of Java GUIs to myself since I haven't used SWT
  • Confused NSSortDescriptor with NSPredicate when it came to extracting Core Data
  • I strongly implied that Cocoa was for GUI work when of course, it's great for most aspects of application development including threading and networking
  • Completely garbled the relationship properties of Core Data objects
  • Turns out that the C++ paths dialog in Visual Studio is actually resizable. It's just really easy to miss the drag target.


Also, I say "You Know", "Like", and "Uh" way too often; and I was completely unaware that I did so.

Tuesday, July 21, 2009

"I'm A Mac Programmer; and a Mac User. And We are Arrogant People"

“I’m a Mac programmer, and a Mac user, and we are arrogant people. And we love beauty.”

I've never been a guest on a podcast before, so my hour talking to the guys on DotNetRocks was one of the more interesting things I've done all year. And it is amazing what came out of my mouth, including the above quote.

This was in context of my describing the cloudy future of cross-platform development and how I was uninterested in any development strategy that didn't involve using Cocoa for the GUI on the Mac. I don't know that I've ever used the word arrogant to describe something positive before, perhaps a better word would have been demanding, but then again maybe it was the right word.

I'll put up a note when they post the show in the coming weeks.

Saturday, July 18, 2009

On Xcode 3.1 versus Visual Studio 2008

Recently, the DotNetRocks Podcast had an episode where the guest spent an hour slamming Xcode, Objective-C, and the Cocoa frameworks, and how awful iPhone development was in comparison to Visual Studio, C# and .Net. The guest went so far as to diagnose anyone enjoying the iPhone toolchain with Stockholm syndrome.

I wrote the hosts a scathing e-mail, pointing out that I had used a lot of frameworks, and a lot of IDEs—including regular use of Visual Studio for the last 7 years—and that the iPhone coding experience, with the exception of the annoyance of code signing, was second to none in fun. Apparently, the folks at dotnetrocks have a policy for dealing with over the top ranters, they invite them on the show. I'll be recording an episode Monday.

This blog post is part of the process of organizing my thoughts for that show. If I go on and say I like Xcode 3.1 better than Visual Studio 2008, the question will immediately become why. And the reasons behind that are either absolute i.e., that some aspect of Xcode allows me to do a better job than Visual Studio just by having a better thought out design, or personal in that Xcode is embedded in a Mac, and I love my Mac. This post cannot hope to be inclusive and I'll focus on things I don't like about Visual Studio that are done well on Xcode 3.1.

Project Properties

I recently needed to turn off the "/GL" flag in the release build of a C++ project on Windows (because a google of an arcane linker error code said that flag was involved.) So, I had to find that flag in the project properties. And, of course, in Visual Studio, if you don't know where a property is kept, you have to click through all the categories and subcategories until you find it. In this case, despite being about linking it was under Configuration Properties:C/C++:Optimization:Whole Program Optimization
BTW, all these web ready PNGs are just the way OS X takes screen shots. If only I knew how to make Windows XP take partial screen shots directly into PNG.

On Xcode on the other hand, all the properties are visible at once:And what's that at the top of the page? A search field, you mean I can just paste in the parameter and it will find it? Yes, yes I can.

And what's this thing in the corner "Based on", you mean if I have a project (a solution in Visual Studio speak) with a bunch of sub-projects (a project in Visual Studio speak) that I can create a set of configuration files that are shared amongst some of them and overrided as needed and not have to go to every single project and change its settings when I want to add a path?

And speaking of paths, doesn't this include path dialog dialog look a bit small? Oh, you can resize it like nearly every other window in Xcode Why? Because Xcode was written in Cocoa where resizing views and windows is easy.
Hey it looks like the Visual Studio include path dialog is resizable too. But only horizontally not vertically, I guess people only need two paths. [Update: turns out it was just really hard to resize, at least for me. The traction corner was not the proper target.]

Profiling

As anyone who's ever coded with me knows, I believe in the power of profiling. It is something I do as part of my personal development process. Both Xcode and Visual Studio have profiling tools. Xcode's tools go by the name of Instruments and they are prominently available in the Run menu.Here is the Object Allocations Instrument where I can ferret out performance problems indicated by too many object allocations or having objects hang around too long. For instance, earlier in the year, I ran into a problem where I was adding a timer to my run loop every tenth of a second, this was not technically a leak and would not have been solved via garbage collection but did show up in the allocations instrument as a worrisome growing number of CFTimerRefs. Notice that you can analyze and experiment on a running copy; you do not have to deal with after the fact reports.

And you can find the stack trace of every allocation.

As for Visual Studios profiling tools, well I know they are there, as I have used them in the past to find some performance problems and leaks in C++, but I can't even find them right now; that's how ill layed out Visual Studio is that something as critical to the development process as profiling is hard to find. Regardless, as I recall, the tools included were of the old fashioned variety where you ran the app, quit and the profiler would crank away for a minute or two and give you a report which you could browse through and dig into call sequences to find out for instance what fraction of the time was spent in a given method and its children. Useful, but really bare bones. And this article on Microsoft's site indicates the situation is similar when doing .Net development.

Static Analysis

It is a good idea to run your code through a static analyzer every now and again to pick up the little bits of idiocy we all suffer through. In .Net, the popular analyzer is FxCop and while I haven't personally used it, I have had our outsource team run analysises and the results have been quite useful especially when dealing with the code of junior engineers. You can get a free static analyzer for Mac and iPhone development too: Clang and I have used it and it's great at making sure your code is following the rules. Please run it before every release.

Layout

It probably is redundant, that I, a Mac user since high school, prefer the appearance and layout of Xcode to Visual Studio. It's also pretty much a given that where I see large mouse targets and esthetically pleasing use of space, a Visual Studio aficionado will see wasted space and a lack of important buttons. (BTW, if you are a PC user new to the Mac, use your left thumb to hold down the command key not your pinkie like you would if it were the CTRL key. Yes habits are hard to break, that does not mean the Mac's primary meta key is in a stupid place, far from it.)

My biggest peeve about Visual Studio is how easy is to undock an embedded subwindow while doing something else. Honestly how often does one rearrange their project panes? And then I have to figure out where to drag the window back to given this onscreen display:

My second peeve would be the amazingly small tool icons. Monitors are large and getting higher resolution. Icons 4x as big as these would be more appropriate for today.

Number 1 Favorite Features I'd Like to Find in Visual Studio

The open quickly dialog (command-shift-D) in Xcode used to be functional, but a bit lame compared to the one that had been in Metrowerks CodeWarrior, now it's one of the greatest things ever. Just open it up and start typing and as like as not, you will find the file you are looking for in a dynamically filled search list. And it is amazingly fast.
I say like to find, because Visual Studio is so filled with impossible to discover features, it might just have it already.
[Update: Philippe writes to say
Also, a neat trick in Visual Studio that mimics "Open Quickly" is this:

1. Set the focus to the Search field in the toolbar

2. Type ">of " followed by the filename (e.g. ">of MyF")
]

Getting Better All The Time

Long time Mac coders will recall that when Xcode first came out it was much worse (at the very least as a C++ IDE) than the product it killed: Metrowerks CodeWarrior which was a refined, lightning fast IDE beloved by most. But over the years, Xcode has gotten better by fits and starts. And since the iPhone took off, it's been getting better by leaps and bounds. Code completion, which used to be useless is now indispensable. The linker has gotten much faster and memory savy. The new llvm compiler which replaces gcc is fast, stable, and thankfully even tougher on iffy code. I've actually started using in-editor debugging to look up variable values, and like I said before the Open Quickly dialog is fantastic.

To Sum Up

I like Xcode. It is an Apple product, with all the good that entails: esthetics, selective choice of features, performance, ease of use. From a base of high quality, it continues to improve. I suspect it will soon integrate such technologies as Clang or openCL and become even better. PC programmers moving over to iPhone development should give it a chance and try to grok how and why it is the way it is.
[Update: content updated since first post]

Saturday, June 27, 2009

The lagging edge

I was taking my daily glance through MacSurfer when I was struck by a press release from WaveMetrics announcing a new version of Igor, the data graphing program. That brought back memories, Igor was my absolute favorite graphing program back when I was in Chemistry grad school in the early 1990s and it could always be depended upon to make the slickest output of the myriad Mac or Windows programs used at what was then called the Center for X-Ray Lithography. I have not seen it since graduating in 1995, and it is good to see it is still alive.

But what really caught my eye, that it is now in 2009 that Igor has moved to Quartz rendering from QuickDraw. According to Wikipedia Quartz was first demonstrated at the 1999 WWDC and has been the recommended mode of rendering on OS X since its introduction. Such is the inertia in the software business that an application as graphically intensive as Igor, a program which would benefit hugely from the modern features one gets for little effort with Quartz, takes 10 years to make the transition.

I wonder if the proximal cause of this laggard transition is the impending doom of Snow Leopard, where QuickDraw using 32-bit apps are distinct second class citizens. A "Pro" graphing app, might well benefit from 64-bit status, and to do that every single QuickDraw call must be expunged. Apple had spent enough time on carrots in making Quartz a beautifully clean API generally superior to QuickDraw in every way, and is now bringing down the stick of enforced obsolescence to bring the last stragglers into the fold.

I will be doing this transition over the course of the summer, myself. I'm down to 800 or so deprecated symbol warnings, so I've a ways to go before the day job application sees 64-bit nirvana.

Tuesday, June 09, 2009

Star Trek Lessons for Safari

A little noted part of Monday's WWDC keynote was the final feature set for Safari 4. Safari now has searching of browsing history. This reminds me of this exchange in the first season of Star Trek: The Next Generation:

Cmdr Riker: "Data, I need help in locating some library-computer information. All I have is a vague memory of reading somewhere about someone taking a shower in his or her clothing."
Lt. Cmdr Data: "Ah. The body Geordi discovered."
Cmdr Riker: "And I believe it may have happened before."
Lt. Cmdr Data: "To 'someone,' 'somewhere.'"
Cmdr Riker: "Should be easy for someone written up in biomechanical texts."
Lt. Cmdr Data: "About that... did the doctor believe I was boasting?"
Cmdr Riker: "Probably. This may take some time?"
Lt. Cmdr Data: "At least several hours. But what I said was a statement of fact."


It would take Data several hours to search all of Star Fleets records for instances of people showering in their clothes. Such records are quite voluminous. Searching for "shower clothes" gets 23,200,000 hits on Google now, it must be many times more in Data's day.


However, the proper data set to search is every bit of text that Riker had ever read, a much smaller set. As every viewer knows, Star Fleet personnel rarely read paper books, those tend to be kept in glass display cases; they read Kindles. And it wouldn't take much programming to keep track of every page that was ever displayed on a Kindle, or displayed in the browser on your computer.


If I remember seeing a bit of information I now need, like the name of the product manager for Keynote (yes I happen to want to know this), it would be quicker looking in web pages I've seen than it would be googling against all of man's knowledge. I doubt I read as many as 100 pages a day. My browser history says I visited 120 URLs on Monday, and that was a heavy day. Humankind as a whole must be writing 10s of millions of English text pages a day, and has been doing so for quite some time.


But to be truly useful, this data set has to be maintained over one's entire life, and include computers, smart phones, Kindles, and every other gadget that tells us something. So, history search is in Safari, but that's only a start.

Tuesday, May 26, 2009

The Wonders of the iPhone Star Rating

So, I have my free MythTV remote in the iPhone App Store and it only has a 2 star average rating.



Not exactly a Gaussian distribution.

I think that there are a class of iPhone users who download every free app they can get their hands on, whatever it's description of use, and then later tidy up, delete the app and give it a 1 star rating. For free apps, you should only go by the ratings of people who bothered to write a review.

Of course, reviewers can be pretty picky. Here are some nearly representative 1 star reviews for RRgh:

“Trop compliqué, pas ergonomique, trop cher.. bref! tout faux. A déconseiller fortement." (Google translates this as "Too complicated, not ergonomic, too expensive .. short! all wrong. A highly recommended.” 1 Star


“I love this because of it's ease of use. All who done know time consuming getting myth to work the way you it is so this application come is a fresh breath of air. I use myth on my 64bit Suse 11.0 box an it took me less than 3 minutes to set up my box to work with the app. I want to note that mymote has not worked for me yet which is disappointing because I think the interface looks better. Just remember that your default port is 6546 and your ip of your myth box. After that just enable it in the setup/utilities -- setup -- general option.” 1 Star


“A virtually flawless app I use it all the time, no more looking for the remote, it's always in my pocket! My only suggestion is to add the ability to schedule recordings if possible
Thank you
Dave” 1 Star


I will freely admit that out of 10 reviewed 1 star ratings, 7 didn't like the app, mainly because they didn't know MythTV. Fair enough, MythTV is not for the casual computer user, or someone who gets paid by the hour. My major point, if I had a point, is you should read the reviews of free apps, their star rating is not generally helpful.

Monday, April 27, 2009

On the Motivation for Updating a Free iPhone App

When I sat down to learn iPhone development, I settled on writing a remote control for MythTV as a first product. And thus Remote Remote GH for MythTV or RRgh came into existence. As MythTV users are pretty adamant about not paying for software, I decided not to charge for it, and considered it only a teaching exercise. And that worked out pretty well. I learned a lot and other people have paid me a good hourly wage for writing custom apps with the experience thus gained.


But now I have an app with 76,307 downloads and no revenue. What do I owe the users? Most of them, I'm pretty sure, just downloaded it because it was free, and promptly deleted it—and typically gave me a one star rating, ugh—when it didn't do anything useful without a MythTV frontend. But there are people out there who use it, and I'd like to give them a little goodwill. How to justify it?


1) Advertising for other products.
I can put a splash screen that announces my paying apps. Right now that would be mainly Signal GH, which a great number of MythTV users will find useful, and which I sold a grand total of $10.50 of product just this last week. But I've ideas for other products in the pipeline.


2) Further Learning.
After reading Clean Code I've been scouring my code for ways to improve its readability. The code for RRgh was written when I was just getting a handle on using Objective C 2.0's properties extension, and is a good target for cleaning. And cleaning code is sort of fun in a mechanical washing the dishes sort of way.


3) Just to be Nice.
Hey, I like having users, and it makes me happy thinking they are happy. There were some rough edges around RRgh and I think my users would be happy for me to sand them down.


So I sat down and started cleaning. As I said, my major problem was with inexperienced usage of properties. I went through and made sure I was creating, accessing and disposing all the properties in the app properly.

And then I went after the interface. I had had this idea of having a defiantly plain interface using just standard OS widgets. Turns out people didn't appreciate what I was going for. So, following popular demand, I opened up Photoshop Elements and started drawing a black on black interface for my remote controls. The idea being something that wouldn't be too distracting in a darkened home theatre room, and which would look reasonably tasteful. I used a variety of button shapes to keep things consistently themed, but not oppressively so. Plus I took the opportunity to improve the spacing and sizing of the various controls, in particular, I felt it important to make the Play/Pause button easier to hit by making it a double size.


I also went through the reviews people had submitted. Someone had wanted a record button on the LiveTV remote, etc. Perfectly reasonable and easily done.

Before and After:





Then I took the Object Allocation Instrument to the running code in the hopes of finding code that was leaking. Turns out the system image picker (UIImagePickerController) is hard to dispose, so I ended up just reusing one. Result: the app doesn't crash after setting the logo for a dozen or so networks.


In total, I gave my users about 10 hours of my time sanding down rough edges, and made RRgh a noticeably nicer product. I hope they find it useful.

Sunday, April 12, 2009

On the cost of USB versus Analog Headsets

I have children. Children love to destroy audio headsets, whether it be tearing out the ear padding, chewing up the wind guard, or taking a scissors to the cord, they will get the job done. And headsets can be expensive, especially if they have a USB connection. Searching for Logitech headsets on newegg.com, in 3.5 mm and USB varieties (and tossing out the most and least expensive in both categories) we can clearly see that analog headsets cost about $16 while USB headsets cost about $36 on average. This USB premium is something that has to be paid every time a headset is replaced.


However, there are USB devices with 3.5 mm headphone and microphone jacks which allow the user to use analog headsets. They cost about $20 (no surprise). As children are unlikely to destroy those, you just have to buy the one, and afterwards just buy a cheaper analog set to replace the one Junior split in two.