Sunday, February 20, 2011

Stay Productive with Growl Notifications

Being a productive programmer... you would never browse Twitter, Facebook, Digg, or Hacker News while working. You are focused and on task!

Unless, perhaps your full app build or other common task require a few minutes or more of processing? In order to not waste precious time, I often develop with 2 machines... Or.. I will waste precious time and catch up on my tweets. One link leads to another, next thing you know... there goes ten or fifteen minutes while waiting on a 2-3 minute build.

Solution: Add a Growl Notification to Your Build


Growl notifications are a non-intrusive way to let you know your build is complete. Setting this up for a Mac is really easy. I just copy the sample AppleScript, change the notification text, and modify my build to execute the script. I don't need to make this work on Windows, but I imagine that would be pretty easy to do via another method.

Growl was already installed on my system, but you may need to install it yourself.

Apple Script Copied from Growl.info



http://growl.info/documentation/applescript-support.php



tell application "GrowlHelperApp"
-- Make a list of all the notification types
-- that this script will ever send:
set the allNotificationsList to ¬
{"Test Notification" , "Another Test Notification"}

-- Make a list of the notifications
-- that will be enabled by default.
-- Those not enabled by default can be enabled later
-- in the 'Applications' tab of the growl prefpane.
set the enabledNotificationsList to ¬
{"Test Notification"}

-- Register our script with growl.
-- You can optionally (as here) set a default icon
-- for this script's notifications.
register as application "Growl AppleScript Sample" ¬
all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application "Script Editor"

-- Send a Notification...
notify with name "Test Notification" ¬
title "Build Complete" ¬
description "NFJS Build Complete" ¬
application name "Growl AppleScript Sample"

notify with name "Another Test Notification" ¬
title "Another Test Notification :) " ¬
description "Alas — you won't see me until you enable me..." ¬
application name "Growl AppleScript Sample"

end tell




Execute the Script from Your Build



I'm using a gant based build, so executing the script is pretty simple.




"osascript bin/build_notify.scpt".execute()




Congrats, now you'll be privy to fewer breaking stories about the next iPhone and such; but you will get more done!

Friday, January 28, 2011

Objective-C Core Data EntityManager

If you plan to create an iPhone, iPad, or Cocoa application that requires data storage, you are going to need to use the Core Data framework. Core Data is a great framework. It saves you the pain of writing redundant data access code.. SQL, etc. Also, I really like the graphical tool used to create entity models.

However, I find the Core Data API to be overly complicated and exceedingly verbose. When compared to other modern ORM APIs, it takes a lot of work to do simple entity management tasks.

Example: Fetch a Collection of Books using Core Data



- (void) testCoreDataQuery {

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];


NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];

fetchRequest.entity = [NSEntityDescription entityForName: @"Book"
inManagedObjectContext: managedObjectContext];


NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc]
initWithKey: @"title" ascending: YES] autorelease];
[fetchRequest setSortDescriptors: [NSArray arrayWithObject: sortDescriptor]];



NSFetchedResultsController *fetchResultsController =
[[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil
cacheName:nil] autorelease];


NSError *error = nil;
if(![fetchResultsController performFetch:&error]) {
NSLog(@"FETCH ERROR: %@",[error userInfo]);
}

NSArray *entities = [fetchResultsController fetchedObjects];

NSLog(@"found %d books",entities.count);

}





That is a lot of code to write to perform what should be a really simple operation. This example doesn't even include any sort or selection criteria.

Introducing BEEntityManager

To simplify interaction with Core Data, I created a simple Entity Manager API which is inspired by the Java Persistence API. I'm guessing there are other APIs like this available, but I haven't bothered to look. Let me know if you know of any.

Example: Fetch a Collection Using BEEntityManager



- (void) testBEEntityManagerQuery {

BEEntityManager *entityManager = [[[BEEntityManager alloc] init] autorelease];

NSArray *books = [entityManager query: @"Book" criteria: @"author = 'F. Scott Fitzgerald'" sort: @"title" ascending: YES ];

NSLog(@"found %d books",books.count);


}





This is a much easier and more maintainable way to interact with a data store. To each their own though.. it's not for everyone... some people like pain.

BEEntityManager API Features

The entity manager includes simple methods for your common data store operations.

query
get
create
createOrUpdate
save
delete

It also simplifies accessing and managing instances of NSManagedObjectContext. This is helpful in apps of any significant size.

You can download BEEntityManager from github. To see examples of how to use the API, take a look at the BEEntityManagerTest class. If you find it useful, please let me know.

Wednesday, December 1, 2010

Rich Web Experience iOS Workshop

Yesterday, I enjoyed hosting another iOS Workshop with Matthew McCullough. This was at the Rich Web Experience. With about 70 developers in attendance, we had a great turn out again.

This workshop was an all day session. Our attendees were experienced Java developers, so we started with a lecture on Objective-C. This was a hands-on coding workshop, so we had everyone writing code throughout the day.

In the morning, our focus was on the fundamentals of Objective-C syntax and getting comfortable with XCode. In the afternoon, we jumped into using Interface Builder and created an iPad application. This application covered the use of application templates, with a focus on a tab based controller app.

The next steps included: adding a Map to a view, creating a view with a table and label, exploring other ui components, creating an enhanced table view, and finally we used a UIPopoverController and a UIWebView to present a content detail view.

That is the short story, we covered a lot of iOS fundamentals in a single day. The workshop went really smoothly thanks to the help we received from: Tim Berglund, Pratik Patel, and Johnny Wey. During the workshop, they roamed the room and helped out those who were stuck. This allowed Matthew and I to focus on the larger group. This was a great help! So far, the feedback has been very positive. Hope to do it again in 2011!

Saturday, October 23, 2010

Identifying Untested Code with Cobertura

With the No Fluff Just Stuff code base, I'm currently at 87% code coverage. Life at this level of coverage is pretty good. I'm rarely surprised by bugs as a result of untested code. Most untested code is pretty inconsequential stuff; such as, legacy (pre-groovy era code) that was originally written only to handle checked exceptions.

That said.. I'm always trying to increase coverage. My code base is just shy of 20,000 lines of code. To increase coverage by %1, I have to add 200 lines of coverage. Uncovered lines are sprinkled throughout the codebase and rarely in blocks larger than 1-3 lines. Writing a unit test to cover 1-3 lines typically involves writing 5-10+ lines of unit test code. So at this point, a %1 increase in test coverage is a lot of work and is something to celebrate.

The html reports generated by cobertura are great, but I find that they don't point me directly to the class with the most untested lines of code. So using the xml report, I wrote a simple gant (groovy) target to generate a report which orders classes by lines of uncovered code.

It is a simple script that took me about 30 minutes to write, but should help me attack my uncovered code a little more efficiently.

This script is on github: http://gist.github.com/642533. clone url: git://gist.github.com/642533.git

Sample output:

Thursday, August 19, 2010

Summer in Michigan and Seattle + Orca Video

Wow, it really has been a great summer. I spent most of it in my home town, Marquette in Michigan's Upper Peninsula. Marquette is a great little city on Lake Superior. The weather is fair, beaches are beautiful, and it has world class mountain biking trails that are easily accessed from anywhere in town.

I bought a Jeep Wrangler and did a lot of camping and exploring in the deep woods of the UP. You can checkout the photos on flickr.

I also spent 3 weeks in Seattle with my girlfriend Amy. She participated in a teaching program there, so I tagged along... telecommuting is a great thing :) On the weekends, we made 2 trips to Olympic National Park and one trip to San Juan Island.

On San Juan Island, we went sea kayaking with Sea Quest Expeditions. The guides from Sea Quest are great and we were really lucky to come across several pods of Orca whales. Check out my little video..


Wednesday, August 18, 2010

Objective-C Refcard @ DZone.com


Objective-C for the iPhone and iPad
My first DZone Refcard Objective-C for the iPhone and iPad is now available. I collaborated with Matthew McCullough on this project.

In 5.5 pages, this refcard describes and has code examples of the Objective-C language and tools. There are a few additional topics that I would like to have covered, but I believe we hit the key points. I would love to hear your feedback; please leave comments here or send me an email: benellingson .at. yahoo.

The folks at DZone and our several reviewers were a big help!

Thursday, June 17, 2010

Über Conf iPad Workshop

Matthew McCullough and I had a great time hosting the Über Conf iPad Workshop! 90+ developers attended the main 4 hour workshop on Monday. The Tuesday and Wednesday night sessions were also well attended.



Monday's workshop included:

  • overview of the iPhone OS development landscape

  • Objective-C language lecture and comparison to Java

  • hands-on coding of simple Objective-C command line apps

  • tour of Interface Builder

  • connecting controls and event handlers to controller classes

  • hands-on coding of a simple iPad app



I spent the majority of the Tuesday night 90-minute session live coding. Live coding can be a challenge, especially if you don't do it often. Fortunately, the session went smoothly. I had a lot of fun with it.

In this hands-on coding session we walked through the creation of a web service application that deserialized JSON data and displayed the content in a UITableView. This application used Über Conf conference speaker data.

Steps followed:

  • created a iPad app using a blank window app template

  • added a UIViewController to the app delegate, MainWindow.xib and connected the two

  • Created a SpeakerListController class and .xib file

  • explored the mechanisms of UITableViewController to populate a TableView with some simple static data
  • .
  • copied the TouchJSON api into our project

  • deserialized speaker records from JSON into an NSArray rowData

  • populated the UITableView with the speaker names



Using UITableViews is a key iPad / iPhone skill, so I am pleased that we were able to help attendees code along through these steps.

We continued the session for another 90-minutes on Wednesday night. We picked up again coding on the web service application. We walked through the steps to create a speaker detail view and display the view using a UIPopoverController. UIPopoverController is an iPad specific control for displaying content within a smaller popover view.

Then we went on to demo the Über Conf conference application. During this demo, we discussed the Core Data framework and demoed the process for generating our domain entity classes.

Finally, we finished up the session by walking through the process to create and install a developer provisioning profile; and to deploy the application to a participants iPad.

We had a great time with this workshop. We hope to host it again at the Rich Web Experience in December.

It was great to have an opportunity to work with Matthew McCullough. I learned a lot! Also, thanks to Tim Berglund and Fred Jean for helping throughout the workshop. And thanks to all those who came!