Archive

Archive for February, 2010

Eight guys, four weeks, one dream

February 16th, 2010 2 comments

A software coop

At our local Cocoaheads chapter, we started dreaming in December… What if we pooled our resources and multiple talents to create a software “co-op”? Shared resources, low buy-in, extra exposure and marketing…

Over the holidays, Cocoaminded was born. We have a domain, so we must exist, right?

Early January, Mark had an idea. What if we all worked together on a small iPhone app to promote our other apps, and learn something in the process?

Introducing Tweety10

Mark’s idea was to expand on his HockeyTweet to create an Olympic-themed Twitter client. It would have a live newsfeed (from Twitter, of course!), medal count and schedule. It would use web services to serve the data

And just like that, we decided to start what became Tweety10.

The first 80%

We all got together on Sunday, January 10th at The Code Factory and brought our laptops. Mark even brought his 24″ display. At 9:30, we had a kickoff meeting where we decided that at 5:00, no matter what, we would all go home. And we would decide if the app was in a good enough shape to continue working on it, with the goal of submitting within two weeks to the App Store.

I was nominated as Project Manager, which means that I was responsible for the big picture, so to speak. Given my past experience, here is what I had planned:

  • Each feature of the application, for example the News view, the Medals view, etc… was written on a 3×5 index card. Features would be then assigned, and divided into subfeatures as necessary. For the News view, you had the actual view, the Controller (UITableViewController, in this case) and the model, along with the web service. We wrote those subfeatures on cards
    The idea was, whatever was on a card should represent about an hour’s worth of work. If it took more than an hour, you made a new card. When you were done, you asked for a new card.
  • Version control with Mercurial.
    I suggested Mercurial (hg) early on because it is fast, simple and distributed. It also has a fairly quick learning curve, meaning I would not have to spend a lot of time explaining it to everyone.
    Mercurial had a couple of small glitches that were due to my unpreparedness, but overall it was very satisfactory.
  • We would use BitBucket.org to store our common code repository.
    BitBucket has a free, private repository (and unlimited public repositories). It was extremely simple to create the private project and add the other seven developers as writers to the project. You can also assign read-only access if you want: it is simple and quick, much like Mercurial itself.
  • Starting from the skeleton application (a variant of the Tab Bar Application Xcode template), we would add source code and resources as needed, and push to the common repository as often as possible. Continuous integration was the word.

I spent my day making cards, troubleshooting issues, helping out with code problems and generally having a blast integrating all of the code into a build system on my own computer. It was exhilarating to keep feeding six smart people with enough information to keep them busy, while at the same time making sure that they are not stuck on a problem or bored and going off-spec. The index cards were a hit, and BitBucket performed admirably.

At the end of the day, we decided we had an app, and it was worth continuing towards our goal of putting an app in the App Store.

The other 80%

Since we would not work in the same area anymore, I immediately transcribed all the cards on a Wiki page in BitBucket. This allowed us to put our name next to a virtual card and claim it. We could add cards, and mark them as complete when the work was done.

We started using Skype’s Chat feature to create a private chat amongst all of us. The great thing was, you did not have to stay logged-in like you would for IRC. If you disconnected from the chat, as soon as you re-connected Skype updated your chat window and you could see all of the conversation that you had missed. This is a great feature.

Although it was not formal, it was very helpful to meet two to three hours every week for NSCoder Nights. It was a great way to gauge progress and help each other out with all the little things that stop us from time to time.

We finalized our artwork and installed localizations, keeping abreast of changes in localizable files as much as possible (this late, the changes were far between).

Real artists ship… then get rejected

We submitted to the app store a week before the Olympics were due to start, and after three days got rejected because we used the word “Olympics” in our keywords. Oops! I wonder how people who live on the Olympic peninsula feel… We removed the keyword, re-submitted and after another four days of waiting…

Tweety10 is available on the App Store. It’s free, give it a try!

Post-mortem

Having a real, in-person kick-off day for the project helped tremendously. This would not have happened otherwise. Most of our subsequent interactions were online via email, Skype or BitBucket and if we had not smoothed out the communication channels beforehand, the friction would have been too great.

Mercurial is a great version-control system. Once we got past the initial hurdles of merging (hg does not come with a built-in merge tool, you have to set it up) and pushing (Mercurial Keyring Extension is a must).

BitBucket, with its one free private project, was an awesome instrument in communication via code and issues. You get an email when an issue is created or updated, and you can resolve issues by pushing a change containing text like “Fixes #23″.

Finally, I was delighted to see that as a group, we worked really well together. I hope we all gained some valuable knowledge and experience with this project; I certainly did.

This was really a case of the whole being larger than the sum of its parts! I hope you will enjoy the app and the 2010 Winter Olympics in Vancouver, Canada.

Categories: Development Tags:

Multiple developers, one iPhone app

February 10th, 2010 2 comments

I am working on an iPhone project with seven other iPhone developers, and we all have individual development certficates (the project did not require a group certificate, and we all had ours already).

Since one has to sign code to run outside the simulator, we all edited the Info.plist’s Bundle Identifier to match our certificates (mine was com.casgrain, as you can guess).

This leads to a permanently-modified file in your local copy of the source repository, one that you have to ensure you do not commit. It’s not very neat, and it is error-prone. And if you want to genuinely modifiy the plist, you must discard your changes, do the modification, commit and re-do your changes. Not pleasant.

I wanted to use plist pre-processing to solve this issue, since it will replace environemnt variables in the plist before using it, for instance to sign code.

The goal is to replace this:

	CFBundleIdentifier
	com.myCompany.${PRODUCT_NAME:rfc1034identifier}

with this:

	CFBundleIdentifier
	${DEVELOPER_DOMAIN}.${PRODUCT_NAME:rfc1034identifier}

Pre-processing supports environment variables, but not any environment variable. If you define a variable in ~/.profile (if you use bash or a bash-compatible shell), this does not work.
You have to define the variable in ~/.MacOSX/environment.plist, a special plist that is read at login time.

To define this variable, follow these three simple tasks in Terminal. You only need to do them once.

  1. Create the `/MacOSX folder if it does not exist. If it is already present, this is harmless
    	mkdir ~/.MacOSX
    
  2. Add the environment variable
    	defaults write ~/.MacOSX/environment DEVELOPER_DOMAIN -string "com.yourdomain"
    
  3. Ensure that the plist is human-readable and not compressed XML, in case you want to edit it later with a text editor
    	plutil -convert xml1 ~/.MacOSX/environment.plist
    

You will need to log out and back in for those changes to take effect.

Now, do the repkacement above in your Info.plist, substituting “${DEVELOPER_DOMAIN}” for “com.myCompany” or whatever the reverse-domain was for your project.

With this modification, you should now be able to build for the device without changing the plist every time.

Categories: Development Tags: