iPhone Design and Development Resources

Designing for the iPhone is like a hybrid of print and web design.

-37 Signals

Some great resources for designing and developing for the iPhone here.

I may be jaded when it comes to Apple and their elitist platform, but I still plan on staying up on what’s going on with it.

Apple is the new Microsoft… in a bad way.

Alright - expounding on my previous post and inspired by a lengthy conversation between Brit and myself; I’m about to open the flood gates of flame ware hell.  I realize this and I really don’t want to go where I’m about to go, but I’ve got to vent.  (I also realize that half of the comments I’ll receive will be from Apple fanboys that will fail to read anything except for the headline of this post.)

Recently Dirk Holtwick recieved notification that his application,Big 5, was rejected by Apples App Store approval process.  His application was built using PhoneGap, a project that allows access to the iPhone SDK through the use of Javascript - exciting because it means that web developers like myself don’t have to learn an obscure language like Objective C to get our ideas onto our iPhones; we can use a language we’re already comfortable with instead of fighting through a bunch of new classes and methods in an unfamiliar IDE, using unfamiliar syntax.

Ultimately Big 5 is an alternative to using safari on an iPhone - the big difference is that it allows a web developer to send alternate content that makes use of iPhone features to their users.  So - say I have a recipe website and I’d like to allow a user to take a photo of a dish they just cooked with their iPhone camera and upload it directly to my site - I could do so using a Big 5 enabled site and all I’d have to do is include a little bit of Javascript on my site.  Very cool.

What Apple is doing on the other hand - not so cool.

No telling how many hours went in to Big 5 development, but all Dirk got in return was the following email:

Dear Developer,

We’ve reviewed your application Big Five.   We have determined that this
application is of limited utility to the broad iPhone and iPod touch
user community, and will not be published to the App Store.

Sincerely,

Nice of them to let him know why his app didn’t make the cut. Several theories abound, but the one that bugs me the most is that the SDK agreement that a developer agrees to when they download the SDK states that an application cannot execute code. The funniest thing about that argument is that the security risks presented in an app like Big 5 are identical to those that are posed any time any user access a website via safari on an iPhone - Big 5 uses the SDK component, Web View, to access a site just like safari.

This seems to be a power play to make sure that safari is the only web browser on an iPhone. I understand the move, but why not allow developers a similar solution using safari - allow users to have javascript hooks into the SDK for alternate content so that we can take advantage of iPhone features. And for God’s sake, please give a developer that spent a lot of time an explanation as to why their app was rejected. At this point, I could spend 100+ hours of my development team’s expensive time kicking out a killer app for a market that Apple doesn’t deem important only to get rejected with the same form email as a guy making a “I am rich” app.

The worst part of this whole situation is something that really infuriates me. As a developer, having downloaded the SDK, I am automatically under a non-disclosure agreement. I can’t talk about any of te projects I’m working on… I can’t post code of solutions to problems… Technically I can’t even write this freaking article bashing Apple for crushing something that could open the door to a lot of cool stuff. There are very few sites with iPhone SDK programming tutorials because of this, and the ones that are out there are in violation of the NDA… and this makes the Objective C (and the iPhone SDK) even less accessible.

Been to Barnes and Nobles recently? Notice that there’s only one book on iPhone development on the shelves and its pre-SDK (using open source tools and jailbreaking)? Look on amazon and see how many books are out there for iPhone development and then realize that none of them can ship until the NDA is lifted…

And why would Apple make it’s SDK developers agree to an NDA that would prevent people from evangelizing its toolset? Because (according to U.S. patent law) by keeping everyone using their SDK under an NDA Apple can own anything developed on their platform - without exception. So… how’s that for spurring innovation?

Now - realize this - I’ve been accused of being an Apple fanboy many times in my life… I’ve owned almost every generation of iPod, I’m on my fifth Apple laptop and I’ve been responsible for evangelizing Apple products in the video world for several years now (A certain professional football team switched to Final Cut Pro from Avid because of my constant bitching). All told, I’ve been responsible for about a quarter of a millions dollars worth of Apple gear being bought in the last 4 years. Take all of that into consideration when I say what I’m about to say:

Only a company that has a zealous following can do what they’ve done in the last few months. MobileMe anyone? Any other company would’ve been burned to the ground. What about blacklisting apps that are useful to a large market without giving justification to the developers? It even pisses me off that they pulled the “I am rich” app - it serves the same purpose as a $300 purse. If someone wants to spend $300 on something that just holds their makeup and wallet, that’s up to them, not Apple.

So - let the onslaught begin, but please - at least act like you’ve read the post.

Downtown Seattle Panoramic




Downtown Seattle Panoramic

Originally uploaded by shaun.gish

More Seattle photos to come - this is from Queen Anne Hill, taken during the Sub Seattle Tour, a tour that takes you through all of the subcultures in Seattle.

PhoneGap - Native iPhone Apps running your HTML/JS/CSS

Brit ran across something huge yesterday - PhoneGap

The idea behind PhoneGap is basically to allow developers to create a native iPhone application that pushes thru to the web application of their choice… some of the iPhone SDK is available via javascript.

This is a great way to get an iPhone app developed without having reinvent the wheel in Objective-C.  Who want’s to write 30 lines of code just to display a map anyway?

Scalable Tagging System in CakePHP

Tag clouds are a great way to allow users to navigate/search through your site but if you don’t design your application correctly from the ground up they can become a serious nightmare.

So - here’s my solution for creating a scalable tagging system in CakePHP (using MySQL in this instance but the theory applies to any other DB… yes… even you PostGRE’ers)

My example is a cookbook of recipes.

Most people that attempt a tagging system the first time around just go for a HABTM relationship - A recipe has and belongs to many tags.  So - you have you “recipes”, “tags”, and “recipes_tags” tables… all you have to do to find your tags is:

  1.  
  2. $this->Tag->find(‘all’);
  3.  

And to find what tags go with what recipes (assuming you setup your models correctly) is:

  1. id(int)
  2. tag(varchar)
  3. count(int)
  4. created(datetime)
  5. modified(datetime)

I pretty much always add fields for “created” and “modified” and set them to datetime - Cake fills them in automatically and it can be useful sometimes to have that history (you never know when a client wants to see something organized by the date they were added to the system - kinda sucks not to capture that info). Also - always, always, always create an “id” field that’s a unique, auto-incrementing, primary key for EVERY table… don’t call it something silly like uid or user or anything stupid like that. It’s just best practices. Period.

But, I digress;

So - your “recipes” table should look something like this:

  1. id(int)
  2. title(varchar)
  3. description(text)
  4. ingredients(text)
  5. method(text)
  6. tags(text)
  7. created(datetime)
  8. modified(datetime)

Notice that the “tags” field here is a text field - this is where we are going to store the tags, as written, by the user as one big block of text.

So - whenever a user creates a recipe we’re going to save all of the pertinent data to the database and then run a function called generate_tags:

  1.  
  2. function generate_tags($id=null)
  3. {
  4.    //get recipes by $id
  5.    $recipe = $this->Recipe->findById($id);
  6.          
  7.    //get all tags in the db
  8.    $tagsOld = $this->Tag->find(‘all’);
  9.          
  10.    $tagsOldArray = array();
  11.    $tagsOldArrayValues = array();
  12.          
  13.         //loop thru tags in db and create an array like so: $tag = array (’id’=>$id,’count’=>$count)
  14.    foreach($tagsOld as $key => $values)
  15.    {
  16.    $tagsOldArray[$values[‘Tag’][‘tag’]] = array(‘id’=>$values[‘Tag’][‘id’],‘count’=>$values[‘Tag’][‘count’]) ;
  17.    }
  18.             
  19.    $tagsArray = explode(‘,’,str_replace(‘, ‘,‘,’,$recipe[‘Recipe’][‘tags’]));
  20.    foreach($tagsArray as $tag)
  21.    {
  22.    $tags[] = $tag;
  23.    }
  24.             
  25.    $countArray = array_count_values($tags);
  26.          
  27.    $tagsOldArrayValues = array_keys($tagsOldArray);
  28.  
  29.    foreach($countArray as $tag => $count)
  30.    {                          
  31.         if(in_array($tag, $tagsOldArrayValues) == true)
  32.         {
  33.              $this->Tag->create();
  34.         $this->Tag->query(‘INSERT INTO `tags` (`tag`) VALUES (\’.$tag.\’) ON DUPLICATE KEY UPDATE `count` = `count`+1′);
  35.          } else {
  36.         $this->Tag->create();
  37.         $this->Tag->saveField(‘tag’,$tag);
  38.         $this->Tag->saveField(‘count’,$count);
  39.          }
  40.    }
  41. }
  42.  

What’s going on here? Well - first we find the recipe that you’re editing (or just inserted). Then we get all of the tags in the db. We foreach through the $tagsOldArray to format the array so that you have a nested array for each tag that contains the tag’s id and current count. We then explode the $tagsArray (the tags that are stored as plain text for the recipe at hand). We loop through the $tagsArray and then count the values of the keys. We then use array_keys to return the keys of $tagsOldArray which is used to determine whether or not a tag is already in the database. If it is in the array we execute the following query:

  1. $this->Tag->query(‘INSERT INTO `tags` (`tag`) VALUES (\’`.$tag.`\’) ON DUPLICATE KEY UPDATE `count` = `count`+1′);

This updates the count of the tag value by 1. If the tag is in the array we insert the tag and count.

There’s probably a much more elegant way to do all of this - maybe one of these days I’ll pair this code down (I threw it together tonight for a project - and looking at it now I can see some obvious redundancy… but alas there’s not enough time in the world to optimize code and actually launch a website…).

But the theory is sound…

Now it’s your turn to play along - we have to remember to do is decrement the `Tag`.`count` for all tags associated to a recipe if a user deletes that recipe… and we have to update the counts for any tags a user edits when they edit a recipe… Not as big a deal as it sounds…

My next post will focus on the view for a tag cloud using this setup.