The Frontier Group Spotfire Perth User Group

Posted in Inside TFG

The Frontier Group are developing a local community around data analytics using TIBCO Spotfire.

We’re keeping this group technically focussed though we welcome users of all levels, including those new to data analytics and Spotfire.

Though we already have strong support from TIBCO’s local team in Perth, this meetup will not be vendor-driven in an effort to establish a vibrant community of users.

Please feel free to register at Spotfire Perth where the dates and details of future Spotfire sessions will be posted along with any comments or questions members may have.

 

The Frontier Group Spotfire Demonstration Session

Posted in Inside TFG

Tibco Spotfire – Fastest to Actionable Insight

The Frontier Group will begin to hold regular morning tea sessions at the Empire café at 182 St Georges Terrace at 10am for a quick technical tour of some useful functions in Spotfire followed by questions and answers that will help users make the most of the more advanced Spotfire features.

The first session is commencing Monday August 26th at 10:00am and is designed to be informal, educational and interactive.

For more information about Tibco Spotfire in-memory analytics software please see the web page .

Registration for this session on August 26th can be completed through our event page.

We hope you can join us.

Regards, Lynne O’Neill – Event Coordinator at The Frontier Group.

 

TIBCO and The Frontier Group

Posted in Agile Development, Industry Trends, Inside TFG

Last month The Frontier Group joined the TIBCO Partner Network program and in doing so formalised an agreement that has been under development for over nine months.

This formal partnership sees us join a prestigious group of IT consulting, integration and software development companies who specialise in delivering and extending TIBCO software solutions for large enterprise customers. Collectively we have already begun solving unique problems across a variety of markets and industries with a focus on health, communication, banking and finance, government, transport and retail.

We expect to make our first project-completion announcements around oil and gas exploration, iron ore production and resource transport during Q3 2013.

The agility, focus and creativity our web application and mobile development customers have enjoyed for over a decade position us well to disrupt the stale enterprise software arena. Through this partnership with TIBCO we will deliver modern, accessible and secure applications to customers who have typically had to settle for less.

We’re very proud of this new alignment and look forward to making future announcements shortly.

Writing a good README

Posted in Inside TFG, Tips and Tricks

What’s the problem?

As a developer, you’ll work on hundreds of different projects in your career. The biggest pain in the ass when changing projects is having to get started in a new development environment. If you’re moving to a different Rails project you have to install new Rubies and bundle – plus you might need to install Redis, Solr or jam your public key on a server somewhere. Even worse, after bundling you notice this is a Rails 2.3 project not a Rails 3.2 and you haven’t worked with Rails 2.3 for years and can’t remember how to start a server.

Then you have to work out who is in charge of this damn project and bug them to find out why your PostgreSQL is complaining about some “PostGIS” thing you’ve never heard of. Once you get that sorted you run the specs to see what shape the app is in and half your tests fail because you’re missing some `config/some_random_config.yml` file. You talk to the guy in charge of the project and he tells you to scp it from the staging environment. “But dude, how do I even get to the staging environment? What server is it on?”. Turns out it’s on an Amazon server and you need a special permissions file to be able to access it.

Imagine this process happens 12 months after anybody has ever worked on the project and the last girl to hack on the codebase has long since left the company. Your company has just lost months of her gaining knowledge that you now have to re-acquire. Knowledge that should have been documented somewhere so it wasn’t lost.

What’s the solution?

Although I did reveal the solution in the title (because I’m a bad writer, sorry) – the answer to the question is to write and maintain a comprehensive README file.

How do I write a good README?

Writing a good README is easy. You just need to know what information is required for developers to use and understand the application. Here’s some Rails-centric information I include in the READMEs I write for The Frontier Group:

README: General Information

The “General Information” section should give a new developer an idea of what the project is about and who is involved with it.

Information you might want to include is:

  • The name of the project
  • The name and contact details of the client and any 3rd party vendors
  • The names of the developers on the project
  • A brief description of the project, you should include the answer to the age-old question “What problem is this project solving?”
  • An outline of the technologies in the project. e.g.: Framework (Rails/iOS/Android/Gameboy Colour), programming language, database, ORM.
  • Links to any related projects (e.g.: Is this a Rails API that has corresponding iOS and Android clients?)
  • Links to online tools related to the application (e.g.: Links to the Basecamp project, a link to the dropbox where all the wireframes are stored, a link to the Pivotal Tracker project)

README: Getting Started

The “Getting Started” section outlines the process of getting the app installed and usable for a developer. I define ‘usable’ in this context as able to login to the application and access all of the functionality available.

Information you might want to include is:

  • A detailed spin-up process. This should include:
    • Instructions on installing any software the application is dependent on: e.g.: wkhtmltopdf, PostgreSQL, XQuartz.
    • Instructions on running the app. For rails apps you’ll want to include the rake db:create db:migrate db:seed process here, as well as instructions on starting a server (e.g. are we using pow, or just the default `rails s`)
  • A list of credentials that can be used to log in with each user type in the system and ideally the URL that a developer can log in from.
  • Any information about subdomains in the app (e.g.: api.myapp.dev/)

When writing instructions pretend you’re writing them for someone who knows next to nothing about developing in the framework/language your application uses.

README: Testing

All you need to include in the “Testing” section is the commands to run any of the test suites you have (e.g.: RSpec, Jasmine, Cucumber, Spinach) and any setup you need to do before-hand (e.g.: rake db:test:prepare). This section will be small but vital.

README: Staging and Production environments

The staging and production environment sections (one section per environment) should provide any information a developer might need to know about these environments.

Information you might want to include is:

  • Which server is the application on? Is it on Amazon Sydney? A server in the office? A data-centre down the road?
  • How can a developer connect to the server? Do they need particular permissions? Who do they need to talk to to get those permissions?
  • Where on the server is the application located
  • What is the deploy process for this server
  • Are there any other services on the box related to the app a developer will need to know about? Any cron jobs? Some Resque workers?

Maintaining the README

Worst case scenario, you don’t maintain a README. You’ll burn in developer hell, sorry.

Slightly better than that, your changes to the README will be reactive – you’ve had to work out how to install some required software and you’ve put the details of doing that in the README for future developers.

If you’re having to make reactive changes, you’re probably spending 30 minutes that another developer already had to spend working out a solution to the same problem. This equates to 30 completely wasted minutes that could have been spent implementing a feature for your client.

In an ideal world, maintaining the README is proactive and becomes part of your development life-cycle. As an example, your development life-cycle could look like this:

  1. Plan feature
  2. Write tests
  3. Implement functionality
  4. Update README if required
  5. Get code reviewed and ensure all your tests pass
  6. Merge your feature

What am I getting by writing a good README?

With a comprehensive, well-written README any developer should be able to hop on to your project and begin hacking away within 10 minutes. If you consider that over the course of developing an app you’ll likely see multiple developers set up the app multiple times, you’ll cumulatively save hours of developer time with just minutes of work.

Importantly: If you can set yourself up with this fantastic habit early, other developers will love working with you. Documentation is what separates us from the animals, ladies and gentlemen.

I recommend you invest 30 minutes of your week updating the READMEs of the projects you’re working on. You may not see any benefits straight away, but in 12-18 months time whoever has to maintain that code will be thankful you did it. Spoiler alert – that person will probably be you.

Let’s Talk About RubyMotion

Posted in Code, Inside TFG, iPhone, RubyMotion

We’ve just launched Take5 Feedback and its mobile app. This is the fourth mobile app that The Frontier Group has launched, that I’ve worked on.

Previously, we had been using a combination of PhoneGap and SpineJS. This helped us get into the iOS market while still using tools we were familiar with as web developers. After releasing a few apps using PhoneGap and SpineJS, we found that we were consistently spending time during app development fixing things like scrolling, tap events propagating to other views and transition animations. This coupled with the less-than-fantastic debugging tools made us feel that perhaps we needed to re-evaluate our technology choices.

This time we decided to kick it up a notch by moving to RubyMotion. (Bam!).

For those who haven’t heard about RubyMotion, it’s a library that lets you write native iOS apps in Ruby which is then compiled down into Objective-C. As most of us at The Frontier Group are Ruby developers, this felt like a technology well worth exploring. After working with it for a few months, I think it’s the way to go for us moving forward. Now, let’s talk a little about RubyMotion.

Off the bat, one of the big advantages of RubyMotion is that you’re writing native apps in Ruby and not in Objective-C. I’ve found that Objective-C is not an intuitive language and certainly nowhere near as readable as Ruby (especially when method chaining looks like array declaration shudders). One thing RubyMotion has ported over from Objective-C that I do like is the named parameter which makes method declaration/invocation much more readable. For example, let’s say I have a method that generates a receipt and takes a the date of the purchase and the amount in cents as parameters.

In regular Ruby it would be declared something like this:

def generate_receipt date, amount
  # Do something...
end

Now this method could conceivably be called like this:

square = generate_receipt('3/3/2013', 100)

In RubyMotion, however, using named parameters the same declaration/invocation looks like this:

def generateReceiptForDate date, andAmount: amount
  # Do something...
end
square = generateReceiptForDate('3/3/2013', andAmount: amount)

As you can see, it gives the parameters passed in more meaning during the method invocation. Now most Rubyists won’t call methods with “magic numbers/strings” and you can achieve the same thing in < Ruby 2.0 by accepting a hash but I think this is a nice little addition.

Next I’d like to discuss generating and organizing views. MVC in iOS is a little different from MVC in Ruby on Rails, in that views are a little more tightly coupled to the controller. View elements are ultimately defined and positioned in the controller. Those elements will rely on methods which should be defined in the controller as they deal with event handling and navigation. Let’s take a simple example. I want a screen to have a table and when I tap a row I want to navigate to another screen.

class ExampleController < UIViewController

  REUSE_IDENTIFIER = 'example'

  TABLE_FRAME = CGRectMake(0,0,300,400)
  TABLE_ROW_HEIGHT = 30

  def viewDidLoad
    @data = [1,2,3,4]
    table = UITableView.alloc.initWithFrame(TABLE_FRAME)
    table.delegate = self
    table.dataSource = self
    table.rowHeight = TABLE_ROW_HEIGHT
    self.addSubview table
  end

  def tableView(tableView, cellForRowAtIndexPath: indexPath)
    cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier)
    cell ||= UITableCell.alloc.initWithStyle(UITableViewCellStyleDefault,
    reuseIdentifier: REUSE_IDENTIFIER)
    cell.textLabel.text = @data[indexPath.row]
    cell
  end

  def tableView(tableView, didSelectRowAtIndexPath:indexPath)
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    self.navigationController.pushViewController(AnotherController.new, animated: true)
  end

  def tableView(tableView, numberOfRowsInSection: section)
    @data.count
  end
end

As you can see we’ve got a mix of view level logic (positioning the table on the screen and defining what a row will look like) and controller level logic (setting the data source and the navigational behavior). This makes views and controllers coupled a little tighter than you might be used to. This can lead to extremely fat controllers when you have many elements on the screen each with its own position, look, feel and event handlers. A pattern I found that has worked for me is to have a subclass of a UIView that is responsible for drawing all the elements on a given screen. Let look at an example.

Let’s start by creating our own UIView where we define our table and its look and feel.

class ExampleView < UIView

  TABLE_FRAME = CGRectMake(0,0,300,400)
  TABLE_ROW_HEIGHT = 30

  attr_accessible :table

  def initWithFrame frame
    super
    setupTable
    self
  end

  private

  def setupTable
    @table = UITableView.alloc.initWithFrame(TABLE_FRAME)
    @table.rowHeight = TABLE_ROW_HEIGHT
    self.addSubview @table
  end

end

class ExampleController < UIViewController

  REUSE_IDENTIFIER = 'example'

  def viewDidLoad
    @data = [1,2,3,4]
    self.view = ExampleView.alloc.initWithFrame(view.frame)
    self.view.table.delegate = self
    self.view.table.dataSource = self
  end

  def tableView(tableView, cellForRowAtIndexPath: indexPath)
    cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier)
    cell ||= UITableCell.alloc.initWithStyle(UITableViewCellStyleDefault,
    reuseIdentifier: REUSE_IDENTIFIER)
    cell.textLabel.text = @data[indexPath.row]
    cell
  end

  def tableView(tableView, didSelectRowAtIndexPath:indexPath)
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    self.navigationController.pushViewController(AnotherController.new, animated: true)
  end

  def tableView(tableView, numberOfRowsInSection: section)
    @data.count
  end

end

Ok so now the responsibility for drawing the table (and any other element) is localized to the ExampleView class and the data manipulation and navigation logic is in the controller which is looking better. We can neaten this up further by making the view responsible for assigning delegates.

Let’s start by creating a new parent view that stores an object which will be the delegate for all elements within the view. In this example the delegate is the ExampleController.

class UIViewWithDelegate < UIView

  attr_accessor :controllerDelegate

  def initWithFrame(frame, andDelegate: delegate)
    self.initWithFrame(frame)
    self.controllerDelegate = delegate
    self
  end

end

Now that we have this class our ExampleView class can inherit from it, allowing the ExampleView to set the delegates for any elements inside it.

class ExampleView < UIViewWithDelegate

  TABLE_FRAME = CGRectMake(0,0,300,400)
  TABLE_ROW_HEIGHT = 30

  attr_accessible :table

  def initWithFrame(frame, andDelegate: delegate)
    super
    setupTable
    self
  end

  private

  def setupTable
    table = UITableView.alloc.initWithFrame(TABLE_FRAME)
    table.delegate = self.controllerDelegate
    table.dataSource = self.controllerDelegate
    self.addSubview table
  end

end

class ExampleController < UIViewController

  REUSE_IDENTIFIER = 'example'

  def viewDidLoad
    @data = [1,2,3,4]
    self.view = ExampleView.alloc.initWithFrame(view.frame)
  end

  def tableView(tableView, cellForRowAtIndexPath: indexPath)
    cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier)
    cell ||= UITableCell.alloc.initWithStyle(UITableViewCellStyleDefault,
    reuseIdentifier: REUSE_IDENTIFIER)
    cell.textLabel.text = @data[indexPath.row]
    cell
  end

  def tableView(tableView, didSelectRowAtIndexPath:indexPath)
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    self.navigationController.pushViewController(AnotherController.new, animated: true)
  end

  def tableView(tableView, numberOfRowsInSection: section)
    @data.count
  end

end

This has separated the view and controller logic out a little more and our controller is a little thinner. This becomes more useful as the number of elements on your screen increases. The one drawback I found was that my views were ending up with walls of constants defining positions, fonts, etc. Creating subclasses for individual elements that include the position/look/feel, would solve the problem, however you’ll end up with a lot of singleton classes.

Now a little on automated testing. Automated testing is generally a big part of any of the applications we develop. This time however, I found the experience to be so much more costly than testing in a Rails world. When I started developing the app I was aiming for the level of automated coverage we have in our Rails environments. As I attempted to achieve this, I kept hitting road blocks with either the testing framework not behaving as expected, or the mocking libraries placing a significant impact on the code being tested. After some discussion, we decided that due to the simplicity of this app we could achieve an acceptable level of quality and coverage by manual user testing. From this experience though we now know areas that can be improved and are currently developing our skills and tools to ensure that as our apps increase in complexity, we are able to ensure our code quality.

I could write so much more about RubyMotion and the different technical challenges I faced during the development process, but I really just wanted to give my overall impressions. I think it’s a good choice for any Rubyist wanting to venture in iOS development. In combination with the Apple developer docs, which are fantastic, it lets you learn the iOS framework while programming in a language that you’re comfortable with. It’s a well maintained library with the RubyMotion team making constant improvements. My only real criticisms are with the testing and debugging tools not feeling as flexible and as powerful as I’m used to in the Rails environment, but like I’ve said, these tools are being continually developed and improved, and have no doubt these tools will get better with time.

Search Posts

Featured Posts

Categories

Archives

View more archives