<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Fingertips</title>
    <atom:id>http://www.fngtps.com/index.rss</atom:id>
    <atom:link rel="self" type="application/rss+xml" href="http://www.fngtps.com/index.rss"/>
    <link>http://www.fngtps.com/index.rss</link>
    <description>Recent posts on ‘Fingertips’</description>
    <lastBuildDate>Fri, 11 Jan 2013 14:25:07 +0100</lastBuildDate>
    
      <item>
        <title>A quick note on dependencies in Ruby on Rails projects</title>
        <link>http://www.fngtps.com/2013/a-quick-note-on-minimal-dependencies-in-ruby-on-rails/</link>
        <description>
&lt;p&gt;In response to the latest &lt;a href=&quot;http://weblog.rubyonrails.org/2013/1/8/Rails-3-2-11-3-1-10-3-0-19-and-2-3-15-have-been-released/&quot;&gt;Ruby on Rails security announcement&lt;/a&gt; we upgraded all of our clients’ Rails projects in less than 36 hours. On average it took around 30 minutes to upgrade a project from checkout to deployment.&lt;/p&gt;

&lt;p&gt;On Twitter we mentioned our ‘minimal dependency policy’ in projects as being one of the reasons we could move so quickly. We got some questions about what that means exactly.&lt;/p&gt;

&lt;p&gt;First off it’s important to note that this policy is not something we’ve printed on a sign and hung on the wall. It’s just one of practices that’s part of the culture at Fingertips.&lt;/p&gt;

&lt;p&gt;It’s surprisingly easy to follow; when you work on a new feature and want to add a dependency you ask yourself if you really need it.&lt;/p&gt;

&lt;p&gt;Please note that in this context, a dependency can be an external library, a piece of code you copy from another project into `lib/`, or even requiring something from the standard library.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;p&gt;Second guess yourself. Do I really, really need this?&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Will this solve my problem? Does the library I want to use fit my problem really well or am I better off writing 20 lines of code myself? For example: pull in Devise or use HTTP basic authentication.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Should I use this particular library? Sometimes using another library allows you to drop one you were using for another feature. For example: use OpenSSL for both certificate signing and random token generation and drop Mongoid::Token.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Check if the new dependency has dependencies itself and weigh it against the benefit of using it. For example: use Net/HTTP for that one HTTP call instead of depending on HTTParty.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Minimal dependency is not just about the number of libraries you use, but also about the total amount of code you pull into your project. Less code means less bugs.&lt;/p&gt;

&lt;p&gt;It will also give you less trouble with interdependencies when you try to upgrade. For example: Rails needs Rack 1.4, but Resque requires Sinatra and Sinatra doesn’t run on anything newer than Rack 1.3.&lt;/p&gt;

&lt;p&gt;Finally, less dependencies makes long-term maintenance easier because there is less that can go wrong when it’s time to upgrade to a new major version of Rails. For example: if you depend on will_paginate in your Rails 2.3 project, you’ll need to use a newer version for Rails 3.2 which has a slightly different API.&lt;/p&gt;</description>
        <pubDate>Fri, 11 Jan 2013 11:46:24 +0100</pubDate>
        <atom:updated>Fri, 11 Jan 2013 14:25:07 +0100</atom:updated>
        <guid>http://www.fngtps.com/2013/a-quick-note-on-minimal-dependencies-in-ruby-on-rails</guid>
      </item>
    
      <item>
        <title>Boss guide to installing Ruby on Rails</title>
        <link>http://www.fngtps.com/2012/boss-guide-to-installing-ruby-on-rails/</link>
        <description>
&lt;p&gt;Every once in a while my boss asks me for help getting a Rails project running on his shiny new MacBook Pro. I’ve made him this guide to make sure he won’t waste my time again. It might come in handy for your boss too.&lt;/p&gt;

&lt;p&gt;Please note that we assume the machine is running a clean install of Mac OS X Mountain Lion (10.8).&lt;/p&gt;

&lt;h2&gt;Install Xcode&lt;/h2&gt;

&lt;p&gt;Launch the App Store and use it to install Xcode. Start Xcode and follow the directions to complete the installation. Then choose Preferences from the Xcode menu and click the Downloads tab. Install the Command Line Tools.&lt;/p&gt;

&lt;figure class=&quot;screenshot&quot;&gt;
  &lt;span class=&quot;img&quot;&gt;&lt;img src=&quot;downloads.png&quot; alt=&quot;The Download tab in Xcode’s Preferences.&quot;&gt;&lt;/span&gt;
  &lt;figcaption&gt;&lt;p&gt;The Download tab in Xcode's Preferences.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Grab something to drink and watch your favorite YouTube video. We’ll have to wait for this to download before we can continue.&lt;/p&gt;

&lt;h2&gt;Install Ruby&lt;/h2&gt;

&lt;p&gt;First, enter this command in the Terminal to make sure the default Xcode location is set:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo xcode-select --switch /Applications/Xcode.app&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’re going to use &lt;a href=&quot;https://github.com/sstephenson/rbenv&quot;&gt;rbenv&lt;/a&gt; to compile and manage Ruby versions. Even when you’re planning to use a single version of Ruby, this is still the easiest way to set it up. The rbenv instructions suggest we use &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt;, so we’ll get that first:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -e &quot;$(curl -fsSkL raw.github.com/mxcl/homebrew/go)&quot;
brew tap homebrew/dupes
brew install apple-gcc42&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;brew install git rbenv rbenv-gemset ruby-build
echo 'eval &quot;$(rbenv init -)&quot;' &gt;&gt; ~/.bash_profile&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now quit and then open your Terminal again to make sure your bash profile gets reloaded. For this example we’re going to install Ruby 1.9.3:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rbenv install -list
rbenv install 1.9.3-p194
rbenv rehash&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Get your Rails app running&lt;/h2&gt;

&lt;p&gt;It’s reasonable to assume your Rails app runs at least version 3 and that you’re using &lt;a href=&quot;http://gembundler.com&quot;&gt;Bundler&lt;/a&gt; for dependency management. The rbenv gemsets feature allows us to isolate a set of gems specifically for our project. We start by configuring the Ruby version and the name of the gemset for this application (replace “[project-name]” with the directory name of your Rails project):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd [project-name]
echo &quot;[project-name]&quot; &gt; .rbenv-gemsets
echo &quot;1.9.3-p194&quot; &gt; .rbenv-version&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now make sure everything worked and is in the right place:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;which gem&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This should return &lt;tt&gt;/Users/[your-username]/.rbenv/shims/gem&lt;/tt&gt;. We’re ready to install the dependencies for your Rails app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install bundler
rbenv rehash
hash -r
bundle install&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Troubleshooting compilation problems&lt;/h2&gt;

&lt;p&gt;Compilation might fail when one of the dependencies is using Quartz (i.e. ImageMagick) and the X11 directory isn’t in the library load path. The easiest way to fix this is with a symlink:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ln -s /opt/X11 /usr/X11&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Reader questions&lt;/h2&gt;

&lt;p&gt;Javier Vázquez from Zürich, Switserland &lt;a href=&quot;https://twitter.com/eskriba/status/251693251508203520&quot;&gt;would like us to explain how to install PostgreSQL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The easiest way is to install Postgres.app. You can download it from &lt;a href=&quot;http://postgresapp.com&quot;&gt;postgresapp.com&lt;/a&gt;. After that you configure it in &lt;tt&gt;config/database.yml&lt;/tt&gt; like so:&lt;/p&gt;

&lt;figure class=&quot;screenshot&quot;&gt;
  &lt;pre&gt;&lt;code&gt;
development:
  adapter: postgresql
  encoding: unicode
  database: [project-name]_development
  min_messages: warning
test:
  adapter: postgresql
  encoding: unicode
  database: [project-name]_test
  min_messages: warning
  &lt;/code&gt;&lt;/pre&gt;
  &lt;figcaption&gt;&lt;p&gt;Example database configuration.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt; Don't forget to replace [project-name] with your project name.&lt;/p&gt;</description>
        <pubDate>Fri, 28 Sep 2012 16:34:54 +0200</pubDate>
        <atom:updated>Fri, 28 Sep 2012 17:00:02 +0200</atom:updated>
        <guid>http://www.fngtps.com/2012/boss-guide-to-installing-ruby-on-rails</guid>
      </item>
    
      <item>
        <title>How to add Notification Center support to your website or app</title>
        <link>http://www.fngtps.com/2012/how-to-add-notification-center-notifications-to-your-web-app/</link>
        <description>
&lt;p&gt;Originally introduced last year in iOS 5, &lt;a href=&quot;http://www.apple.com/osx/whats-new/#notification-center&quot;&gt;Notification Center&lt;/a&gt; is one of the more useful new features in OS X Mountain Lion. What’s really nice is that the ability to show notification banners isn’t limited to native applications; both Safari and Chrome allow websites to show alerts in Notification Center as well.&lt;/p&gt;

&lt;p&gt;This is a quick and straightforward guide to adding Notification Center support to your website or web app.&lt;/p&gt;

&lt;h2&gt;Step 1: Request permission&lt;/h2&gt;

&lt;p&gt;Your web app can’t show notifications unless the user has explicitly granted it permission to do so. In Safari, permission is requested using a modal sheet dialog, while Chrome displays a banner at the top of the page.&lt;/p&gt;

&lt;figure class=&quot;screenshot border&quot;&gt;
  &lt;span class=&quot;img five&quot;&gt;&lt;img src=&quot;request.jpg&quot; alt=&quot;Safari and Chrome requesting permission for Notification Center.&quot;&gt;&lt;/span&gt;
  &lt;figcaption&gt;&lt;p&gt;Safari and Chrome requesting permission.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In Safari, users can manage notification permissions in the Notifications Preferences tab:&lt;/p&gt;

&lt;figure class=&quot;screenshot&quot;&gt;
  &lt;span class=&quot;img&quot;&gt;&lt;img src=&quot;manage-safari.jpg&quot; alt=&quot;The Notifications tab in Safari’s Preferences.&quot;&gt;&lt;/span&gt;
  &lt;figcaption&gt;&lt;p&gt;In Safari, the Notifications Preferences are easy to find.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In Chrome, users have to click “Show advanced settings…”, click the “Content Settings…” button under “Privacy”, scroll down to “Notifications” and then click the “Manage exceptions…” button:&lt;/p&gt; 

&lt;figure class=&quot;screenshot&quot;&gt;
  &lt;span class=&quot;img&quot;&gt;&lt;img src=&quot;manage-chrome.jpg&quot; alt=&quot;The notifications settings in Chrome.&quot;&gt;&lt;/span&gt;
  &lt;figcaption&gt;&lt;p&gt;In Chrome, not so much.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;There are a few security-related limitation you need to keep in mind when you’re implementing this process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can only request permission as the result of a direct user interaction such as clicking a link or a button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you’ve requested permission to show notifications and the user has either allowed or denied, there’s no way you can request permission again. The user can however change or remove the notification setting for your site in the browser preferences.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One other thing to keep in mind is that Safari does not first require permission when it’s showing a &lt;abbr&gt;HTML&lt;/abbr&gt; file opened from disk. So, make sure you’re testing on a local webserver during development.&lt;/p&gt;

&lt;p&gt;The first to do is detect whether notification support is available:&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;if ('webkitNotifications' in window) {
  // Notification support is available
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
  
&lt;p&gt;Then, call &lt;code&gt;webkitNotifications.checkPermission()&lt;/code&gt; to get your current permission status. The result will be &lt;code&gt;0&lt;/code&gt; when the user has already granted you permission to show notifications earlier, &lt;code&gt;1&lt;/code&gt; when you haven’t yet requested permission, and &lt;code&gt;2&lt;/code&gt; when the user has denied permission.&lt;/p&gt;

&lt;p&gt;Only when the permission check returns a &lt;code&gt;1&lt;/code&gt; should you show an interface element for the user to enable notifications. Call &lt;code&gt;webkitNotifications.requestPermission()&lt;/code&gt; when this interface element has been activated. Requesting permission is asynchronous, so you’ll need to include a callback to handle the result.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;$('#request button').on('click', function() {
    webkitNotifications.requestPermission(function() { 
      if (webkitNotifications.checkPermission() == 0) {
        // Your user granted you permission to show notifications
      }
    }) 
  })&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;h2&gt;Step 2: Show notifications&lt;/h2&gt;

&lt;p&gt;When you have permission (&lt;code&gt;webkitNotifications.checkPermission()&lt;/code&gt; should return &lt;code&gt;0&lt;/code&gt;), you can create a notification object with a title and a body:&lt;/p&gt;
  
&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;var notification = webkitNotifications.createNotification(null, 'Hi there', 'I’m notifying you about something that happened just now.');&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;You probably want to add a callback handler for when the user activates the notification (you can also set handlers for &lt;code&gt;display&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt;, and &lt;code&gt;error&lt;/code&gt; events):&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;notification.onclick = function() { 
  // Show the item you notified your user about
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;And finally, you can show the notification with:&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;notification.show()&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;figure class=&quot;double screenshot border&quot;&gt;
  &lt;div&gt;
    &lt;span class=&quot;img five&quot;&gt;&lt;img src=&quot;alert.jpg&quot; alt=&quot;A notification banner displayed by Charm.&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;img three&quot;&gt;&lt;img src=&quot;center.jpg&quot; alt=&quot;Alerts from Charm displayed in Notification Center.&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;figcaption&gt;&lt;p&gt;We’re currently consulting on &lt;a href=&quot;http://charmhq.com&quot;&gt;Charm&lt;/a&gt;. Adding support for Notification Center took a little over an hour total.&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;That’s pretty much all there is to it. For more information, see the original &lt;a href=&quot;http://www.chromium.org/developers/design-documents/desktop-notifications/api-specification&quot;&gt;Chromium draft specifications&lt;/a&gt;, but note that specifying your own icon image and the HTML notification type is not supported on Mountain Lion.&lt;/p&gt;

&lt;h2&gt;Demo&lt;/h2&gt;

&lt;p&gt;Here’s a simple but complete Notification Center demo:&lt;/P&gt;

&lt;figure style=&quot;padding: 20px; background: #f0f1f4&quot;&gt;
&lt;div id=&quot;unsupported&quot;&gt;Sorry, this demo only works in Safari or Chrome running on OS X Mountain Lion for now.&lt;/div&gt;

&lt;div id=&quot;request&quot; style=&quot;display: none&quot;&gt;
  &lt;p&gt;Would you like to enable desktop notifications?&lt;/p&gt;
  &lt;button&gt;Enable notifications&lt;/button&gt;
&lt;/div&gt;

&lt;div id=&quot;test&quot; style=&quot;display: none&quot;&gt;
  &lt;button&gt;Show me a notification&lt;/button&gt;
&lt;/div&gt;

&lt;div id=&quot;denied&quot; style=&quot;display: none&quot;&gt;Desktop notifications are blocked for this site. You can enable notifications for this site in your browser’s preferences.&lt;/div&gt;
&lt;/figure&gt;

&lt;script src=&quot;zepto.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
;(function() {
  if ('webkitNotifications' in window) {
    $('#unsupported').hide()
    
    function setupNotifications() {
      $('#test').show()
      $('#test button').on('click', function() {
        var notification = webkitNotifications.createNotification(null, 'Hi there', 'I’m notifying you about something that happened just now.')
        notification.onclick = function() { 
          alert('Here’s the thing I notified you about.')
        }
        notification.show()
      })
    }
    
    switch (webkitNotifications.checkPermission())
    {
      case 0:  // User granted permission to show notifications.
        setupNotifications()
        break
      case 1:  // Ask the user for permission.
        $('#request').show()
        $('#request button').on('click', function() {
          webkitNotifications.requestPermission(function() { 
            $('#request').hide()
            if (webkitNotifications.checkPermission() == 0) {
              setupNotifications()
            } else {
              $('#denied').show()
            }
          }) 
        })
        break
      case 2:  // User blocked notifications. There’s no way we can ask for permission again.
        $('#denied').show()
        break
    }
  }
})()
&lt;/script&gt;

&lt;p&gt;View the source of this page to see how the demo is implemented.&lt;/p&gt;</description>
        <pubDate>Fri, 27 Jul 2012 20:07:58 +0200</pubDate>
        <atom:updated>Sat, 28 Jul 2012 06:30:21 +0200</atom:updated>
        <guid>http://www.fngtps.com/2012/how-to-add-notification-center-notifications-to-your-web-app</guid>
      </item>
    
      <item>
        <title>Functional View and Controller testing with RubyMotion</title>
        <link>http://www.fngtps.com/2012/functional-view-and-controller-testing-with-rubymotion/</link>
        <description>
&lt;p&gt;Eloy Durán, our lead Mac OS X and iOS engineer, recently wrapped up a consulting project for &lt;a href=&quot;http://www.rubymotion.com/&quot;&gt;RubyMotion&lt;/a&gt;, a toolchain that lets you develop native iPhone and iPad applications using the Ruby programming language.&lt;/p&gt;

&lt;p&gt;As part of this project he designed and developed a &lt;a href=&quot;http://blog.rubymotion.com/post/26489000626/functional-view-and-controller-testing-with-rubymotion&quot;&gt;functional testing layer&lt;/a&gt; that allows RubyMotion developers to define integration test scenarios for their views and controller code using a very high-level domain specific language. &lt;/p&gt;

&lt;p&gt;To help RubyMotion developers get started with this new feature, we also produced the following video which introduces the new feature and shows RubyMotion developers how to use it.&lt;/p&gt;

&lt;figure class=&quot;wide&quot;&gt;
  &lt;iframe src=&quot;http://player.vimeo.com/video/45193144?title=0&amp;amp;byline=0&amp;amp;portrait=0&quot; width=&quot;700&quot; height=&quot;393&quot; frameborder=&quot;0&quot; webkitAllowFullScreen mozallowfullscreen allowFullScreen&gt;&lt;/iframe&gt; 
  &lt;figcaption&gt;&lt;p&gt;&lt;a href=&quot;http://vimeo.com/45193144&quot; title=&quot;Functional View and Controller testing with RubyMotion&quot;&gt;Download from Vimeo&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This is one of the advantages of &lt;a href=&quot;/services&quot;&gt;hiring us&lt;/a&gt;; not only do we offer outstanding design and high quality development work, we’re also able to produce compelling content to educate your existing customers about new features, and to help you promote your product to potential new customers.&lt;/p&gt;</description>
        <pubDate>Tue, 17 Jul 2012 13:55:37 +0200</pubDate>
        <atom:updated>Tue, 17 Jul 2012 22:36:54 +0200</atom:updated>
        <guid>http://www.fngtps.com/2012/functional-view-and-controller-testing-with-rubymotion</guid>
      </item>
    
      <item>
        <title>A conversation with Thomas Fuchs about working with us</title>
        <link>http://www.fngtps.com/2012/thomas-fuchs-on-working-with-us/</link>
        <description>
&lt;div class=&quot;intro&quot;&gt;
&lt;p&gt;On our &lt;a href=&quot;http://www.fngtps.com/services&quot;&gt;rather lengthy sales page&lt;/a&gt;, a few clients share what it’s like to work with us. These stories were done by &lt;a href=&quot;http://www.copylicious.com/&quot;&gt;Kelly Parkinson of Copylicious&lt;/a&gt;. We’d ask the client and she would schedule a phone call to talk about their experiences, have everything typed up, and then edit it down.&lt;/p&gt;

&lt;p&gt;The conversation she had with &lt;a href=&quot;http://mir.aculo.us/&quot;&gt;Thomas Fuchs&lt;/a&gt; was done over instant messaging. I recently came across the transcript and noticed that it contained a lot of interesting stuff that didn’t make it into the final story. Even though it’s almost a year old I’d like to share it here to, well, make it easier for you to decide whether or not you should hire us.&lt;/p&gt;

&lt;p&gt;Here’s the full interview:&lt;/p&gt;
&lt;/div&gt;

&lt;p class=&quot;question&quot;&gt;So you and Amy know a lot of developers. Why did you choose to work with Fingertips in particular?&lt;/p&gt;

&lt;p&gt;Well, besides that we know them personally, they’re really awesome. They have an almost anal attention to detail.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;I would think that everyone in that line of work would have an almost anal attention to detail. Is that not actually the case?&lt;/p&gt;

&lt;p&gt;No. Most design and most code is actually pretty bad.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;Is it that most people don’t know what they’re doing, or that they don’t put much thought into it?&lt;/p&gt;

&lt;p&gt;Most consultants are just in it for the money and don’t really like the work they’re doing.&lt;/p&gt;
&lt;p&gt;Fingertips is different, as you can tell by them making their own products and doing open source projects to scratch itches. I’d place them in the upper 1% percentile of development and design shops. Plus, they’re not pretentious or artsy-fartsy.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;Follow-up question: If you didn’t know each other, what signs would you look for, secret signs that “these guys get it?”&lt;/p&gt;

&lt;p&gt;So what I like most is that all of them can get to the technical nitty-gritty details and have insanely in-depth knowledge.&lt;/p&gt;

&lt;p&gt;They release a ton of open source software; that is actually highly polished (which is very rare for open source). It’s just stuff they needed for development and decided to share, but in a polished way.&lt;/p&gt;

&lt;p&gt;They write amazingly detailed and well-reasoned tests when writing code, even for the OSS stuff they do. And they share their knowledge with blog posts etc.&lt;/p&gt;

&lt;p&gt;Most companies don’t do any of these things, and Fingertips are just 3 people. I think this shows just how dedicated they are to create amazing software.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;So if you could put a value on tons of in-depth knowledge combined with being insanely anal about details, and you took the project they’ve helped you with, what range of numbers would you come up with? So, for example, if you didn’t have them, how much more would you have spent? How much more can you earn?&lt;/p&gt;

&lt;p&gt;That’s hard to say. The main thing is that I don’t need to explain stuff in the last detail and they still come up with a perfect solution. And then it turns out to be really robust as well, requiring little or no changes or bugfixes later. They’re also quite fast, which helps.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;Are you able to say what that project was?&lt;/p&gt;

&lt;p&gt;Sure, they implemented the &lt;a href=&quot;http://letsfreckle.com/blog/2011/06/new-freelancer-role/&quot;&gt;freelancer feature for freckle&lt;/a&gt;. This feature might look easy on the outside, but it required a complete overhaul of our permissions structure and new features in the API. So it basically touched all really important guts of the app.&lt;/p&gt;

&lt;p&gt;And they where able to pull it off really easily, without any hand-holding, not only the technical solution but also including the UI design.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;Will this save you from cancellations of people who needed a team but didn’t consider themselves a team, so they didn’t want to upgrade?&lt;/p&gt;

&lt;p&gt;Yes, this was one of the most requested features in Freckle. Definitely gives us and edge.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;How much time would it have taken you to develop it yourself? Given your current workload etc.&lt;/p&gt;

&lt;p&gt;Forever. :)&lt;/p&gt;

&lt;p&gt;We really have better things to do, like coming up with new applications.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;Right, and you seem pretty entrepreneurial, like you want to keep moving, and maybe it’s not the best use of your time to keep making improvements to the stuff you’ve already built.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;If you were starting Freckle from scratch today, do you think you would have involved them? Or in what ways do you think you could see them becoming involved?&lt;/p&gt;

&lt;p&gt;No, because we wouldn’t have had the money. We will however hire them to implement a specific complex component for our next product, Charm. Because they are so great with the details and knowledgeable, they’ll implement a very important part of our backend for us there too.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;If you could dream up the ideal client for Fingertips, what would that be like? What would be their situation, at what point would they say, “okay, we definitely need to bring Fingertips in right now?”&lt;/p&gt;

&lt;p&gt;They’d have some software product where they have a really difficult problem (either technical or with the UI) and/or want to be on the cutting edge technology-wise (like with all the fancy new HTML5 web stuff or native iOS development). &lt;/p&gt;

&lt;p&gt;And they want someone who’s really into this stuff but at the same time is serious about business and is not fooling around.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;At what stage in development is that? Is it already partly built, or is it just a gleam in their eye?&lt;/p&gt;

&lt;p&gt;That depends, I think. I guess it can be at any stage. It’s certainly good that we hired them for the freelancer feature, because we now have a super-solid base for permissions in freckle.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;There’s probably a lot of anxiety that comes up when people are thinking of hiring someone, because you never really know what’s going to happen until you’ve worked together. If your friend/colleague was thinking of hiring Fingertips and they voiced some fears or objections, what do you think the objections would be, and what would you say in response?&lt;/p&gt;

&lt;p&gt;I think the most common fear people have, besides technical skills, is that work will be too late, too unprofessional or over budget; or that one person doesn’t know what the other person is doing. We’ve not had a single of those issues with Fingertips.&lt;/p&gt;

&lt;p&gt;They’re really, really good at what they do, they’re timely, professional, and punctual. They’re also the only development company that we’ve referred our clients to. &lt;/p&gt;

&lt;p&gt;We completely trust them, and would refer them to anyone, putting our reputation at stake.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;What were you able to do with your business as a result of working with Fingertips that you wouldn’t have been able to do working with another firm or developer?&lt;/p&gt;

&lt;p&gt;I think being worry-free is the best answer to this question. Like I gave them a job to mess with the internals of our most important product, and wouldn’t even have to check twice what they’ve delivered; plus we haven’t had any issues afterwards.&lt;/p&gt;

&lt;p&gt;I also didn’t have to explain to them everything twenty times, and what they delivered was exactly what we wanted.&lt;/p&gt;

&lt;p class=&quot;question&quot;&gt;You said you considered them to be in the top 1% of firms. What percentage of projects would you say has bugs afterwards, typically? Not their projects, but other projects.&lt;/p&gt;

&lt;p&gt;Well, all software has bugs.&lt;/p&gt;

&lt;p&gt;But there are other factors, like how cleanly code is written, how understandable it is for other developers and how we can move on and support future feature with it.&lt;/p&gt;

&lt;p&gt;At the same time, development environments and languages are always improving, and they are on the ball with that.&lt;/p&gt;

&lt;p&gt;For example, they know what the latest browsers can do, and how to use these features to your advantage. But they also know what’s still too experimental, and then they’d recommend against it.&lt;/p&gt;</description>
        <pubDate>Wed, 06 Jun 2012 15:45:40 +0200</pubDate>
        <atom:updated>Tue, 17 Jul 2012 22:36:54 +0200</atom:updated>
        <guid>http://www.fngtps.com/2012/thomas-fuchs-on-working-with-us</guid>
      </item>
    
      <item>
        <title>How to add a Help Book to a Mac OS X Preference Pane</title>
        <link>http://www.fngtps.com/2012/helpbooks-in-preference-panes/</link>
        <description>
&lt;p&gt;Normally you can register a Help Book in your Cocoa application by &lt;a href=&quot;http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/ProvidingUserAssitAppleHelp/registering_help/registering_help.html&quot;&gt;setting &lt;code&gt;CFBundleHelpBookFolder&lt;/code&gt; and &lt;code&gt;CFBundleHelpBookName&lt;/code&gt;&lt;/a&gt; in your &lt;code&gt;Info.plist&lt;/code&gt;. When the application is launched the runtime automatically loads the Help Books based on this information.&lt;/p&gt;

&lt;p&gt;When an application loads additional functionality from a plugin bundle as is the case with preference panes it doesn't automatically load Help Books from the plugin. The plugin needs to take care of this itself.&lt;/p&gt;

&lt;p&gt;Authoring a Help Book is no different from a normal application. The developer documentation is a bit flakey here and there, in general it gives a good overview of how to do this. I assume you've succeeded in creating a Help Book and it's called &lt;code&gt;MailServer.help&lt;/code&gt;. Make sure that it's copied over to the &lt;code&gt;Resources/English.lproj/MailServer.help&lt;/code&gt; folder in your bundle.&lt;/p&gt;

&lt;p&gt;Now you add our Help Book to the &lt;code&gt;Info.plist&lt;/code&gt; as you would in a normal application.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;key&amp;gt;CFBundleHelpBookFolder&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;MailServer.help&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;CFBundleHelpBookName&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;Learn to use MailServer&amp;lt;/string&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;Newer versions of the Xcode plist editor show these keys as ‘Help Book directory name’ and ‘Help Book identifier’.&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;CFBundleHelpBookName&lt;/code&gt; has to match the title for the Help Book you specified in the main HTML file.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;meta name=&quot;AppleTitle&quot; content=&quot;Learn to use MailServer&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;If you want a specific part of the documentation to show up in the Help menu when the preference pane is loaded you can also define this in the &lt;code&gt;Info.plist&lt;/code&gt;.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;key&amp;gt;NSPrefPaneHelpAnchors&amp;lt;/key&amp;gt;
&amp;lt;array&amp;gt;
  &amp;lt;dict&amp;gt;
    &amp;lt;key&amp;gt;anchor&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;mailserver_help_index&amp;lt;/string&amp;gt;
    &amp;lt;key&amp;gt;title&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;Learn to use MailServer&amp;lt;/string&amp;gt;
  &amp;lt;/dict&amp;gt;
&amp;lt;/array&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;You can define multiple anchors. They will open the Help Book near the anchor in your HTML.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a name=&quot;mailserver_help_index&quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;This anchor can reside anywhere in the Help Book. The Help Viewer knows where to find it using the help index you generated as part of the Help Book.&lt;/p&gt;

&lt;p&gt;Now add the Help Book to your Xcode project as described in the documentation. If you did this properly it will show up in your application bundle in &lt;code&gt;Contents/Resources&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To complete the magic summoning of the Help Books you register it with the Help Manager.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;- (void) mainViewDidLoad {
  if (![[NSHelpManager sharedHelpManager] registerBooksInBundle:[self bundle]]) {
    NSLog(@&quot;Failed to register the Help Book for MailServer.prefpane.&quot;);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;If this fails you're basically on your own. There are a few things you can try though. I've notice that both the Help daemon and the Help Viewer are rather needy when caching. Every time I changed anything to my code or to the bundle I made sure all the caches were gone and &lt;code&gt;helpd&lt;/code&gt; was fresh.&lt;/p&gt;

&lt;figure&gt;
&lt;pre&gt;&lt;code&gt;$ sudo killall helpd
$ rm -Rf ~/Library/Caches/com.apple.help*&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;

&lt;p&gt;For a working example you can check out the &lt;a href=&quot;https://github.com/Fingertips/passengerpane&quot;&gt;Passenger Preference Pane&lt;/a&gt; project on GitHub.&lt;/p&gt;</description>
        <pubDate>Tue, 05 Jun 2012 10:48:01 +0200</pubDate>
        <atom:updated>Tue, 17 Jul 2012 22:36:54 +0200</atom:updated>
        <guid>http://www.fngtps.com/2012/helpbooks-in-preference-panes</guid>
      </item>
    
  </channel>
</rss>
