Sit back, relax, and enjoy the code.

iPhone OS 3.0 GM Seed installation steps via iTunes & XCode

Posted: June 9th, 2009 | Author: abel | Filed under: iPhone | Tags: | No Comments »

I couldn’t find these instructions in the iPhone Development portal, so I figured i’d share them with you here.  Once you download the appropriate GM seed, here’s how it’s done (I’m assuming you’ve already designated your phone as a dev device.):

  1. Make sure…
    1. to downloaded correct GM Seed for your iPhone (1st Gen or 3G).
    2. that your system and version of iTunes meet the requirements: 

      “You must be running Mac OS X v10.5.7 and iTunes 8.2 in order to install iPhone SDK 3.0 GM Seed and iPhone OS 3.0 GM Seed.”

      “You must be running Mac OS X Snow Leopard Final Developer Preview (Build 10A380) and iTunes 8.2 in order to install the iPhone SDK 3.0 GM Seed for Snow Leopard and iPhone OS 3.0 GM Seed.”

  2. Extract the firmware .ipsw to a folder.
  3. Connect the iPhone to your computer.
  4. Back up your phone!
  5. Open iTunes and click Restore while holding the Shift key (for Windows) or Option key (for Mac).
  6. Locate or browse to the firmware IPSW.
  7. Wait for iTunes to unpackage and install the firmware.

OR you can just use Xcode…

  1. Back up your phone!
  2. Open Xcode
  3. Open the Organizer (Window -> Organizer)
  4. Flip the software version to “Choose…”
  5. Select the GM Seed ipsw file
  6. You should  see a message that says something like “These changes will take effect when you restore you phone”
  7. Click on the “Restore iPhone” button and watch the magic happen.

By backing up your phone ahead of time, you’ll be able to tell iTunes to put all of your crap back on it when the process is done.  It’ll even try to preserve icon locations :)

Happy hacking.

  • Share/Save/Bookmark

Quick Hits:Deploying iPhone projects to your iPhone/iPod Touch

Posted: June 4th, 2009 | Author: abel | Filed under: Quick Hits, Uncategorized, iPhone | Tags: , , | No Comments »

This process sucks. Period. To get you through the suckage, I found this article with clear and useful steps. If you’re becoming an iPhone/iPod Touch developer, this is something you NEED to read. The article presents the steps of the deployment process in the best order possible to improve your chances at a successful push.

Deploying iPhone Apps to Real Devices

Happy hacking!

  • Share/Save/Bookmark

Quick Hits: A great FAQ for iPhone game developers

Posted: May 30th, 2009 | Author: abel | Filed under: Quick Hits, iPhone | Tags: , | No Comments »

I came across this video from Brian Greenstone, the president and CEO of Pangea Software.  You might remember him from such iPhone games as Enigmo, Cro-Mag Rally, or Bugdom 2.

He’s made a video answering “10,000 ft view” questions about iPhone game development that people who are new to the platform should hear.  What he’s saying isn’t revolutionary, but it’s a lot of very good advice in 1 spot.

Enjoy and happy hacking!

  • Share/Save/Bookmark

Quick Hits: Things to keep in mind

Posted: May 17th, 2009 | Author: abel | Filed under: Quick Hits, Rails, Uncategorized | 1 Comment »

(1) Before you unpack your gems, navigate to your vendors directory:

/Users/[yourname]/[your-app]/vendor/gems: gem unpack [gem name]

It isn’t the end of the world if you don’t do it ahead of time, but it does make life slightly easier.

(2) Remember that when you find a bug, you should write a test for the expected behavior BEFORE fixing the bug.  “The Rails Way” has a great quote about testing:

“It’s not that Rails encourages you to do test-driven development, it’s that it makes it difficult for you not to do test-driven development.” ~Brian Eng

I’ve interpreted this quote into the following mantra:

“It’s not that rails makes it easy to test, it that it makes you pay when you don’t”.

Finding a bug after creating your test suite just means that you missed a test.  Take the opportunity to correct that.

Happy hacking.

  • Share/Save/Bookmark

Google Maps events in Mobile Safari and PhoneGap for iPhone

Posted: April 29th, 2009 | Author: Brad | Filed under: Google Maps, HTML, Javascript, Programming, hacks, iPhone | Tags: , , , , | 1 Comment »

Having trouble getting your Google Maps div to respond to events like you want in Mobile Safari or a PhoneGap app for iPhone? So was I. Disabling pinch-zoom is simple enough, but getting a finger drag to (a) not move the map and (b) draw something on the map was a major pain. I share my solution below: Proxying events through a transparent div overlaid on the Google Maps div.

To play along at home, you’ll need your own Google Maps key or you can just aim your mobile browser to my example code at http://kickasslabs.com/examples/gmap_events.html. (Note that this will not work in a regular desktop browser.) Besides a <script> tag importing the GMaps JavaScript, you should not need any other libraries or tools besides Mobile Safari to view and use the example page. If the page is zoomed way out when you start, just double-tap the map tile in the upper-left corner - it should zoom to fill your viewport.

What you should see is a map tile with a line painted on it. If you touch the screen, you should see one end of the line follow your finger.

It looks simple but I had a bit of trouble getting it to work, because touch events are not like mouse events (curious as to why?), and GMaps doesn’t respond to touch events by default.

Step by Step

First, you need 2 divs:

    <!-- This div holds our map -->
    <div id="map" style="width: 320; height: 320px"></div>
 
    <!-- This div lies on top of the map and acts as an event proxy -->
    <div id="mapoverlay" style="height:320px; width: 320px; position: absolute;"></div>

And you need to position one div over the other:

    mapDiv = document.getElementById('map');
    mapOverlayDiv = document.getElementById('mapoverlay');
    mapOverlayDiv.style.top = (mapDiv.offsetTop + 0) + 'px';
    mapOverlayDiv.style.left = (mapDiv.offsetLeft + 0) + 'px';

You set up the map div like you would for any other GMaps-enabled page:

    // the map
    _map = new GMap2(document.getElementById("map"));
 
    // coordinates for home base
    _lat = 37;
    _lng = -95;
    mapCenter = new GLatLng(_lat, _lng);
    _map.setCenter(mapCenter, 15);

Set up the overlay div to respond to touch events by firing a custom event for your map, e.g.:

    mapOverlayDiv.ontouchstart = function(e) {
      GEvent.trigger(_map, 'customTouchStart',
        (e.touches[0].pageX - mapDiv.offsetLeft),
        (e.touches[0].pageY - mapDiv.offsetTop));
    }

Now have your map respond to that event:

    GEvent.addListener(_map, 'customTouchStart', mapTouchStart);

…where mapTouchStart is a callback function that does something useful in response to a touch:

    function mapTouchStart(xPixel, yPixel) {
      redrawLine(xPixel, yPixel);
    }

And… well, then you’re done. My example also responds to the touchMove event and has a little code for drawing lines, but you’ve seen all you need to know to get event proxying up and running for your app.

Got a question? Got working code for an easier way? Drop me a line in the comments!

  • Share/Save/Bookmark

Rails Gotcha: ActiveRecord Caches Associated Records by Default

Posted: April 23rd, 2009 | Author: gabe | Filed under: Rails | Tags: , , , , | 2 Comments »

ActiveRecord will cache the results of association method calls by default, unless you tell it not to.

(This applies to Rails 2.3.2 and perhaps earlier versions.)

From the documentation:

project.milestones             # fetches milestones from the database
project.milestones.size        # uses the milestone cache
project.milestones.empty?      # uses the milestone cache
project.milestones(true).size  # fetches milestones from the database

Normally, this is great. However, if you’re not aware of this default caching, you might see some strange behavior in your app or tests and have no idea what’s going on. This default caching behavior had me and Abel stumped until we read about it in the docs.

Working with the same concept as the example in the documentation, where a Project has many Milestones, here’s a more explicit example of the caching behavior in action:

project_1 = Project.find_by_id(1)  
project_2 = Project.find_by_id(1)  
# Load the same Project into two variables
 
project_1.milestones.length   
# - Hits the db's Milestones table.  
# - Caches milestones object on project_1.
# - Returns 0. 
 
Milestone.create(:project_id => 1, :name => 'New Milestone')  
# Adds a milestone to the project. 
# But we don't do it through the project_1.milestones association
# because that _would_ update project_1.milestones's cached value
 
project_1.milestones.length   
# Returns 0 (not 1, like you'd expect) 
# because project_1.milestones was cached when 
# previously requested above.
 
project_2.milestones.length  
# Returns 1, because project_2.milestones 
# hasn't been requested/cached yet.
 
# Note: project_2.milestones is 
# a COMPLETELY DIFFERENT IN-MEMORY OBJECT 
# than project_1.milestones.
# Taking this point further, here's an explicit example:
 
project_2.milestones << Milestone.create(:name => 'Another Milestone')
# Put another milestone on the project through 
# project_2's milestones association.
 
project_1.milestones.length
# Still returns 0, because project_1 already cached it's copy of 
# the milestones association back when there were 0.
 
project_2.milestones.length 
# Now returns 2, because only project_2 knows about the new milestone.
 
project_1.milestones(true).length  
# Returns 2, because ActiveRecord updates the cache 
# when association(true) is present.

Another funny something to note about the association caching behavior is that even when ActiveRecord uses a cached value, it still emits SQL to the log file. So, don’t let that trip you up either.

  • Share/Save/Bookmark

Quick Hits: Setting the User Agent Header in Webrat

Posted: March 31st, 2009 | Author: Brad | Filed under: Rails, Testing, ruby | Tags: , , , , | No Comments »

If you’ve read the new PragProg beta e-book on RSpec, you may have read that you can set HTTP headers for your Webrat request like so:

Given /^I am browsing the site using Safari$/ do
  header "User-Agent" , "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us)"
end

Like me, you may have found out the hard way that this doesn’t work. Webrat does not automagically apply these new HTTP headers to your request - they certainly don’t make it to my controller. What worked for me:

Given /^I am browsing the site using Safari$/ do
  headers["User-Agent"] = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us)"
end
 
When /^I visit my precious site$/ do
  get '/my/precious/path', my_query_string, headers
end

In the code above, headers is a method call that returns all the HTTP headers for your request. Just tack headers on as the third argument of your request, and you’re good to go.

  • Share/Save/Bookmark

FasterCSV and noob-ish silliness

Posted: March 23rd, 2009 | Author: abel | Filed under: Programming, Quick Hits, Rails | Tags: , | No Comments »

Here are two things I discovered this weekend:

Thing 1: FasterCSV is really cool!  It’s easy to use and does exactly what it should.  Here’s Scott Becker’s exporting tutorial.  For importing, i’ve hacked together bits from Peter Larkmund’s travels and the FasterCSV documentation.  Thanks to these tutorials, AMB will give users the ability to upload and export CSVs.

Thing 2: Default values for the win!  If you have a table that has a column for an amount, feel free to set the default value to 0.00.  Otherwise you won’t be able to do the following:

a = Account.new
a.amount += 20

…because a.amount will be nil.  You’ll throw an error and if you just updated a bunch of code, you might waste an hour trying to figure out why you’re throwing an exception.  However, if you declare a default value, you’ll be able to avoid any issues.

If you want me to go into further detail on either thing, just leave a comment.

Thanks for reading and happy hacking.

  • Share/Save/Bookmark

F@#$ing get V1 out

Posted: March 15th, 2009 | Author: abel | Filed under: Programming, Rails | Tags: | No Comments »

I’m not new to software development, but unlike Gabe and Brad I’m new to hacking rails.  I’ve created simple tutorial apps in rails (an online store, a blog, etc.) and I now feel comfortable enough to  create something for the world to see.  At the same time, I realized that I would need to care about the project in order to keep coding it.  I decided to turn the spreadsheet that I use for budgeting into a rails app.  AM-Budget (which I like to call AMB) is my first rails app and I’ve learned a lot leading up to its deployment.  I’d like to share the following with you in the hopes that I can encourage other ruby-newbies to release a v1.

Read the rest of this entry »

  • Share/Save/Bookmark

Ruby/Hadoop talk on Tuesday

Posted: March 8th, 2009 | Author: Brad | Filed under: Events, hadoop, ruby | Comments Off

A note for interested parties: I (Brad) will be giving a short (10-15 minute) talk on using Ruby with Hadoop for distributed computing. The plan is to give an ultra-brief description of the MapReduce algorithm and Hadoop, show 2 examples of working code (including one with Wukong, Flip Kromers Hadoop Streaming wrapper), and closing notes on my attempts to use JRuby to create Hadoop jobs.

The talk will be on Tuesday at the NYC.rb meeting, 7:00 at Bway.net’s offices. Get there early for a seat, the last one was packed.

  • Share/Save/Bookmark