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.