James Turner

James Turner, contributing editor for oreilly.com, is a freelance journalist who has written for publications as diverse as the Christian Science Monitor, Processor, Linuxworld Magazine, Developer.com and WIRED Magazine. In addition to his shorter writing, he has also written two books on Java Web Development (MySQL & JSP Web Applications" and "Struts: Kick Start"). He is the former Senior Editor of LinuxWorld Magazine and Senior Contributing Editor for Linux Today. He has also spent more than 25 years as a software engineer and system administrator, and currently works as a Senior Software Engineer for a company in the Boston area. His past employers have included the MIT Artificial Intelligence Laboratory, Xerox AI Systems, Solbourne Computer, Interleaf, the Christian Science Monitor and contracting positions at BBN and Fidelity Investments. He is a committer on the Apache Jakarta Struts project and served as the Struts 1.1B3 release manager. He lives in a 200 year old Colonial farmhouse in Derry, NH along with his wife and son. He is an open water diver and instrument-rated private pilot, as well as an avid science fiction fan.

Upward Mobility: Give Your iOS Table Cells Some Class

You're not stuck with the stock options when creating tables

UITableView is the meat and potatoes of many iOS UIs, but if you restrict yourself to the off-the-shelf table cell styles, you’re missing out on a lot of opportunities for customization. By using a combination of variable cell heights and a custom UITableViewCell class, you can make UIs that look nothing like a standard table.

To see how you can make this happen in your applications, let’s start with the world’s most boring table example, a list of my favorite foods.

simpletable

The implementation for this is the stock table view code you’ll see in any iOS tutorial:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView 
                        cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *myFavoriteFoods = 
                   @[@"Pizza", @"Sushi", @"Steak", @"Chinese", @"Pasta"];
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = 
      [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:CellIdentifier];
    }
    // Configure the cell.
    cell.textLabel.text = myFavoriteFoods[indexPath.row];
    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView 
                         numberOfRowsInSection:(NSInteger)section {
    return 5;
}

So, what can we do to take this design and make it our own? We can start by designing our own class that extends UITableViewCell, and that has its own XIB file, which we’ll call FavoriteFoodCell. There’s not much to it:

@interface FavoriteFoodCell : UITableViewCell
@property (strong, nonatomic) IBOutlet UILabel *foodName;
@property (strong, nonatomic) IBOutlet UIImageView *foodImage;
@end

Next, create a new Interface Builder XIB file of type View. Set the class of the View to FavoriteFoodCell (not the FileOwner; keep that as a generic UIViewController.) We’ll add a label and an image view, so that the cell looks like this:

tablecell_in_ib

 
Read more…

Comment |

A Commencement Speech for Graduating 2013 CS Majors

Passion isn't just for romance novels.

Graduates, parents, guests, members of the faculty of <%= college.collegeName %>. I am honored today to have the opportunity to speak with you, as you move out of the cloistered environment of higher education, and into “the real world.” Except for those of you moving on to postgraduate degrees, of course. You will get to enjoy a life uncluttered by 401Ks and team building exercises for a few more blessed years.

But, for the rest of you, today marks your first step into a journey that will last the rest of your life, unless you’re able to cash in on your equity in some startup, in which case I’m sure you’ll be hearing from the
<%= college.collegeName %> alumni office before the check settles from your brokerage.

In my 35 years of experience in the software field, I’ve met a lot of developers, young and old. And the one thing that separated the truly successful ones from the crowd is passion. Now passion is an overused and abused term these days. Too often people take it to mean a passion for being successful, for achieving a personal goal in their life. When I talk about passion, I mean love. I’ve been in love with computers since I was 14 years old, and I’d be playing with them even if I didn’t get paid for it. If software engineering is merely a means to an end, you’re not going to be happy in the long term working in this field, because much of it is God-awful boring unless you have a passion for it.

Being passionate about software is critical to being successful, because the field is a constantly moving target. What will net you $130K today will be done by junior programmers in five years, and unless you’re constantly adding new tools to your belt, you’re going to find yourself priced out of the market. Many of the best projects I’ve ever worked on came to me because I had already gained the skill-set on my own. Play around with new technologies, contribute to open source projects, and you may find yourself with an opportunity to apply those skills on the job, and get them into your resume. You are rarely going to get an opportunity to have your current employer pay for you to learn things, so learn them on your own and be in a position to leverage the skills when a new project comes along. But if you have a passion for technology, you’ll already be doing it, and enjoying it without needing me to tell you to. That’s why passionate people have a leg up.

People in their 20s tend to jump into small, fledgeling companies, and that’s one of the best things you can do. A junior developer at Fidelity or Akamai is going to work on one thing for long periods of time, while at a start-up you’ll get a chance to jump all over the place, learning many different aspects of the field. But don’t fall into the trap of trading long hours and happiness for the gold ring of equity. You are never going to be in better shape, less constrained by responsibilities, or have more energy than you will right now. Burning 80-hour weeks grinding code is a terrible waste of that gift. Most companies crash and burn, and that equity they gave you will be just toilet paper. It won’t pay for the time you sacrificed eating take-out pizza in front of a glowing tube rather than enjoying the best years of your life.

If you’re passionate, you’ll do the job you’re required to do, and more, but don’t let your employer abuse your enthusiasm. One of my tenets of life has always been that “a lack of planning on your part does not constitute an emergency on my part.” There will be times in your life when you have to step in and fix genuine, unforeseen emergencies, and burn the midnight oil. But if you’re being asked to do it regularly, just because your company didn’t allocate enough resources to see the job through, you’re being played for a patsy.

Consider the benefits of loyalty to your employer. More than just about any other industry, software suffers from a nomadic workforce, where spending five years at a single company is rare. Remember that in a good work environment, you make friends as well as money, and as much as you may say you will, you never keep in touch with them when you move on. But don’t be afraid to jump ship if you are truly unhappy where you are, either.
Read more…

Comments: 4 |

Upward Mobility: Special Effects Wizardry

Dress up your UIViews with a few simple tricks

Most developers aren’t great UI designers (although, as with everything, there are exceptions). But there are a few quick tricks that can dress up an app, even if you don’t eat and breathe Photoshop. Let’s look at a simple iPad single-view app with two views, each of which contains a label and a text box.

iOS Simulator Screen shot May 20, 2013 7.05.42 AM

This is about as Plain Jane as you can get in an application; the only concession to visual appeal that has been made is to use a grey background with white UIViews bounding the labels and text boxes. One easy tweak we can use is to make the UIView corners rounded instead of square, which will lend a bit of flare to the design.

This is actually harder than it should be. To set rounded corners, you need to dig down into the CALayer underneath the view:

#import <QuartzCore/QuartzCore.h>
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.topView.layer.cornerRadius = 5;
    self.topView.layer.borderWidth = 1;
    self.topView.layer.masksToBounds = YES;
    self.bottomView.layer.cornerRadius = 5;
    self.bottomView.layer.borderWidth = 1;
    self.bottomView.layer.masksToBounds = YES;
}
@end

You need to set masksToBounds, because otherwise the corners will not be transparent, and the background color of the view will block whatever is beneath it in the parent view. The resulting view is subtly more classy. You can get more rounding by adjusting the cornerRadius value.

Screen Shot 2013-05-20 at 7.17.42 AM

 

So far, so good. But that solid grey background is kind of blah, so we should dress it up a bit. An easy way to make a background pop is to use a gradient fill, a technique that the aforementioned Photoshop jockeys know and love.
Read more…

Comment |

Upward Mobility: Dump Those iOS Delegates

Blocks are the way to go

Because so much of iOS programming involves the delegate pattern (the UITableViewDelegate being a prime example), it’s natural that when programmers are developing their own classes that need to be able to asynchronously call back to a client class, they would use the delegate pattern as well. The problem with delegates is that they are fairly inflexible. For example, let’s consider the following (totally inappropriate) use of a delegate:

@protocol MultiplierDelegate <NSObject>
-(void) handleResult:(float) result;
@end
@interface Multiplier : NSObject
-(void) multiply:(float) v1 and:(float) v2
        delegate:(NSObject<MultiplierDelegate> *) delegate;
@end
#import "Multiplier.h"
@implementation Multiplier
(void) multiply:(float) v1 and:(float) v2
       delegate:(NSObject<MultiplierDelegate> *) delegate {
       [delegate handleResult:v1 * v2];
}
@end

The problem lies when you need to call this method twice from the same class.

#import "Multiplier.h"
@interface MultiplierCallee : NSObject<MultiplierDelegate>
@end
@implementation MultiplierCallee
-(void) example {
    Multiplier *mult = [Multiplier new];
         [mult multiply:3.2 and:23.3 delegate:self];
}
-(void) handleResult:(float)result {
   NSLog(@"Result is %f", result);
}
@end

So far, so good, but what happens if you want to have a second method in the same class call multiply? You can only have a single delegate method, so you have to start jumping through hoops to let the delegate method know where to put the resulting value.

The modern solution to this is to use blocks. People tend to shy away from them, because the syntax is a bit arcane and un-Objective-C, but they are incredibly powerful, and Apple has signaled that they are the future, by starting to use them heavily in areas such as animation.
Read more…

Comment |

Upward Mobility: Unit Testing Core Data

There's no reason to leave your database-centric code untested

One of the more common issues that arises in creating OCUnit tests in iOS is how to test code that uses Core Data. There are several challenges, but with a little foresight, you can be sailing right along.

The first issue that most people encounter is getting access to the managed object context. If, like most people, you’ve followed the code snippets that Apple provides, or followed a tutorial on the web, you hung it off the AppDelegate, and use

[[UIApplication sharedApplication] delegate]

to get a handle on the context when you need it. Alternatively, some people pass the context all the way down the view container chain, making it a property on each controller. I find this incredibly painful, and since most applications only have a single database instance open at once, there’s no reason not to keep the context around globally.

In any event, the problem with having your Core Data specific classes get the context from the sharedApplication is that when you run OCUnit tests, sharedApplication returns nil, and there’s no way to mock it. But, this is easily solved by creating a helper class that you use to access the context.
Read more…

Comment |

Upward Mobility: Should There Be Only One?

Admittedly, the idea of Ballmer, Cook and Schmidt all battling it out Highlander-style is appealing...

As long as most people can remember, the smartphone space has been a contested one. Before the iPhone became temporarily ubiquitous, RIM and Palm were fighting it out to own the market, and today you have a plethora of platforms to choose from, including Android, iOS, Windows, and Blackberry. And because many mobile OS vendors license their products to third-party manufacturers, some mobile operating systems have little market share wars of their own, such as HTC fighting it out with Samsung and Motorola for the Android customer base.

I’ve talked before, in the context of languages, about the damage that the paradox of choice can bring to societies. Having more product choices may not make us any happier, or even lead to better products, but only create the vague uncertainty that whichever product choice we make, it wasn’t the correct one.

For obvious reasons, a monopoly doesn’t usually work out that well either, at least in mature markets with stable standards. Very few will argue that Microsoft’s most innovative years occurred during the period that they sat “fat, dumb and happy” with 90%+ desktop market share. But I would argue that there comes a time when some choices should be left to die a dignified death, and that both Windows and Blackberry mobile products are at that point.
Read more…

Comments: 2 |

Agile in name only

Agile isn't agile if you end up going over a waterfall at the end.

In politics, the term RINO is used to refer to a candidate who is “Republican in Name Only,” i.e., claiming the mantle of the party, but not conforming to the platform or belief system. In software development, there’s a similar phenomenon: companies that claim to embrace agile development principles, but really don’t understand agile. They’re Agile in Name Only (AINO).

I’ve written before about “waterfall with a crunchy agile shell,” the problem that if you are trying to control all three of the variables (time, features, resources), you can’t really do agile. Agile acknowledges the uncertainty in development estimates, and requires the team to stay “ready to ship,” so that when the decision is made to pull the trigger on a release, all the work done to date can be easily consolidated and shipped. But focusing on keeping shippable units in shippable shape only makes sense if you also embrace the idea of frequent releases, and putting only in the release what fits in the bucket.

In contrast, a company that’s agile in name only will cling to a distant release date and a laundry list of features, but still insist on short sprints and closing stories. At this point, the benefit of short sprints isn’t for the developers or the team, it’s for management, because it lets them focus on their burn-down charts, and chart the progress toward that eventual release that may be a year away.
Read more…

Comment |

Upward Mobility: Automating iOS builds with Jenkins

If Jenkins is good enough for Apple to use, why not give it a try yourself?

One of the pleasant surprises I learned last year at WWDC is that Apple uses Jenkins to automate their iOS app builds. Since we were already using Jenkins to do the same thing at the Day Job, it was a nice confirmation that we had taken the right approach.

However, until recently, getting Jenkins to fire off an Xcode build, bundle it into an IPA, and sign it correctly was a real pain. Thankfully, in 2012, a Jenkins plugin for Xcode integration was released. It can be installed directly from the Jenkins plugin management page, and once installed, gives you a new build step called Xcode that you can add to a build.

Read more…

Comment |
The overhead of insecure infrastructure

The overhead of insecure infrastructure

If we don't demand more secure development infrastructure, we get to do it ourselves.

The news is constantly full of companies and organizations falling victim to exploits. Software developers spend a great deal of our time defending against them. But why should they have to bother at all?

Comments: 18 |
Developer Week in Review: Oracle’s big bet fails to pay off

Developer Week in Review: Oracle’s big bet fails to pay off

Google dodges a bullet, a new Perl in town, and GCC loses an OS.

Oracle fails to convince a jury that Google owes them big bucks, the annual refresh of Perl has arrived, and FreeBSD says goodbye to an increasingly restrictive GCC license.

Comment |