If you don't know client-side Web programming (HTML, CSS, and Javascript) already, it should be the next technology you learn! I'm pretty sure that 2009 starts the golden era of these technologies, and this post explains why. Asides from making my point, I highlight some cool and very useful pieces of technology along the way.
Overview
My argument goes along the following lines: Javascript has evolved into a mature language, with good frameworks. Browsers got faster at Javascript, and better at standard compliance. Major Web sites offer easy access to their data through APIs. Applications and widgets based on Web technologies can be easily integrated into the desktop, or other Web applications. Last, but definitely not least, generous free hosting is available, and can be set up quickly.
Read on, and find out what technologies I'm referring to.
The Platform Is Ready
Javascript got off to a really bad start. Starting from the language's name itself, and continuing with the horribly slow and buggy browser implementations, Javascript got a bad reputation.
However, today's Javascript is a well-understood and pretty productive language. Libraries like Dojo, Prototype/scriptaculous, and jQuery abstract browser incompatibilities away, and insulate programmers from the less inspired DOM APIs. The HTML5 draft, which is adopted pretty quickly (compared to the time it took to get CSS2 in) by the leading quality browsers, specs out many goodies, such as offline Web applications, push notifications, and better graphics.
Equally important, browsers are in a Javascript speed race, and the winners are us. Between Safari 4, Google Chrome, and Firefox 3.1, we should have fast Javascript execution on all major operating systems before the end of 2009.
Integration Opportunities Abound
Integration comes in two flavors. First, you might want to use data from other sources, like Google, Facebook, and Twitter. Second, your idea may not be suitable for an entire Web application, and might fare better on the desktop, or as a widget. There are great news coming from both fronts.
JSONP is an easy way to get data, despite the cross-domain restriction policy, and major companies have been taking it seriously. Google's search API and Twitter's API have JSONP support. Yahoo's Query Language goes one step further and lets you get other sites' content wrapped up in nice JSONP. Did I mention Dojo's seamless support for Google's search API?
If you want to integrate your application with your user's desktop, you have Google Gears and Mozilla Prism today, and HTML5 in the future.
Applications that don't need a lot of screen space can be packged effectively as widgets. Widgets are supported natively in Mac OS by Dashboard, and in Vista's Sidebar. For a more cross-platform solution, you should check out Google Gadgets, which work the same on the Web, in the Mac OS dashboard , in Linux, and in Windows.
Oh, and one more thing. Google's gadgets also work in their productivity suite - in Gmail, in Spreadsheets, and in Google Sites. So you could impress your boss by building a dashboard with important numbers straight into their Gmail.
REST Decouples Client From Server
Remember ugly long URLs? REST (Representational State Transfer) is a collection of design principles which yields the opposite of those long URLs. It matters because, once your client-server API obeys REST, your client is not dependent on your server implementation.
Using REST works out very well with the approach of pushing most of the application logic to the client-side Javascript code. An argument for why most of your code should be client-side follows.
If you're looking for free hosting (covered in the next section), the server code will not be in Javascript, but rather a server-side language, like Ruby, Python, or Java. Choosing a server language narrows down your platform choice (for example, at the moment, Google's App Engine only works with Python). If you're looking for free hosting, you want to be able to port your code quickly to whichever platform offers better free quotas at the moment.
Using REST designs with JSON input and output gives you "standardized" servers that are easy to interact with, and easy to code. On the client side, for example, Dojo automates the data exchange for you. On the server side, Rails scaffolds have built-in REST/JSON support, or you can pick up ready-made App Engine code.
Hosting Can Be Free
Web applications are very easy to access, but the servers are a pain to setup. Furthermore, hosting costs money - even if you're on Amazon EC2, there's a non-zero amount of money that you have to pay. Most of us, programmers, don't like to pay for stuff.
Fortunately, there's the Google App Engine, and it has a free tier which is pretty much equivalent to running your own server. "Pretty much" covers everything except storage, which is currently capped at 1Gb.
If you prefer gems to snakes, like me, check out Heroku for Rails hosting. Heroku's beta platform is free, and they promised a free tier on their production version. Their free tier may not end up to be as generous as Google's, but you can always downgrade to Python if your application becomes successful. Update: Google's App Engine can run Java now, which leads to support for Ruby and other languages. This post has more details.
Conclusion
I hope I have convinced you to make a priority from learning HTML, CSS, and Javascript this year. If not, here's "one more thing" - you can build hosted solutions for small companies (50 people or less) with zero infrastructure cost. Google Apps, together with the App Engine gives you SSO (single sign-on), and Gadgets can be used to integrate into Gmail.
Thanks for reading this far, and I hope you have found this post to be helpful!
Wednesday, March 11, 2009
Saturday, February 28, 2009
iPhone Development and Code Sharing
This post describes an elegant method for sharing code between iPhone applications. According to my knowledge, the techniques in this post are the first major breakthrough over manually configuring a static library, or building a SDK.
The post starts with an explanation of how I package code in an Xcode project, so that the code can be reused. The structure description is followed by a step-by-step guide of importing reusable code in another Xcode project. My process has the following advantages:
The first two targets are static libraries. Create a static library target by going to Xcode's menu, selecting Project > New Target. Name your library, then select OK.
In order to add files to the static library, first make it the active target, by selecting it from the top-left drop-down (see picture at the right). Then click on the folder holding all your sources in under Groups & Files (Xcode's project tree) and click the checkboxes next to the files that you want in your static library, as shown in the picture below and to the left.
The post starts with an explanation of how I package code in an Xcode project, so that the code can be reused. The structure description is followed by a step-by-step guide of importing reusable code in another Xcode project. My process has the following advantages:
- the reusable code is imported in the consumer Xcode project, so it is built together with the consumer code, and the developer has full browsing and debugging support
- the reusable code that was imported into a project can easily be updated to newer versions
Update: I have open-sourced the iPhone toolkit that I used when writing this article. This means you can find an example packaged project structure here, and you can read more about the toolkit here.
Reusable Xcode Projects
First, notice how all the code has been tucked away under a single folder, with the same name as the project, which is ZergSupport for this example. This is because everything in the project will be imported directly into Xcode projects that use the code, and we don't want to litter their directory structure.
The other important feature of this project is its targets. The code is grouped into three targets:
- All the "production" code that is supposed to end up on customers' iPhones is included into a static library with the same name as the project (ZergSupport).
- Code intended to help test the production code above is included into another static library. I named the library ZergTestSupport in my example, because I don't know an obvious naming convention. This library includes the main library (ZergSupport).
- Tests for all the code above are separated into another target, whose name is the project name plus the suffix Tests (in this case, ZergSupportTests). This target is an iPhone application, prepared according to the instructions in the Google Toolbox for Mac.
The first two targets are static libraries. Create a static library target by going to Xcode's menu, selecting Project > New Target. Name your library, then select OK.In order to add files to the static library, first make it the active target, by selecting it from the top-left drop-down (see picture at the right). Then click on the folder holding all your sources in under Groups & Files (Xcode's project tree) and click the checkboxes next to the files that you want in your static library, as shown in the picture below and to the left.
- Shipping testing code in an iPhone application will increase its size. If the application goes above 10Mb, people cannot download it over a cellular connection, and need either WiFi or a computer. This means less customers. So separate test code from production code.
- Some open-source licenses (e.g. GPL, BSD with advertising clause) tend to have more relaxed requirements if the code is only used in-house. Testing code meets this condition, as long as it doesn't end up in the binary that is sold. So separate test code from production code :)
- People using your reusable code should not have to run your unit tests (and wait for them), if they don't modify your code. So separate test code from test-supporting code.
Last, maintaining target membership can be simplified by using good naming conventions, and a tool I wrote. For instance, suppose you have two targets, CodeTargetName (for the code that ends up in the client) and TestTargetName (for the test cases), and all your test code is in files whose names end in Test (example: RssReader.m, RssReader.h, RssReaderTest.m). The following commands in your project folder will bucket your files correctly between your targets.
$ zerg-xcode retarget . ".*" CodeTargetName $ zerg-xcode retarget . "Test\.m$" TestTargetName
The commands above use zerg-xcode, a tool that is introduced below.
Importing Reusable Code
Fortunately, using code packaged in the manner described above is much easier than packaging the code.
The instructions below assume that the library project (ZergSupport in my example) and the project that consumes it are in sibling folders. For example, I have all my Xcode projects in ~/xcodes so I would download the reusable project in ~/xcodes/ZergSupport and my application, which wants to use it, would be in ~/xcodes/MyApp. The following commands will perform the import, when issued from the directory of the consumer application (MyApp).
$ sudo gem install zerg-xcode $ zerg-xcode import ../ZergSupport $ zerg-xcode addlibrary ZergSupport MyApp $ zerg-xcode addlibrary ZergTestSupport MyAppTestsThe first command installs the tool that does the importing. The second command adds everything in the ZergSupport Xcode project to the MyApp project, and copies all the necessary files. The last two command add the right library dependencies - my application will include the "production" code in ZergSupport, and my tests will include the testing helpers.
Last, and probably most important - updating to a newer version of the reusable code is achieved by downloading the new version in the same place as the old one, and re-issuing the import command above. The importing logic will preserve dependencies.
Conclusion
Code reuse doesn't come easy in iPhone development, especially because frameworks are forbidden. This post presents a method that facilitates code reuse. I hope my work will facilitate the appearance of open-sourced components that will build up to an infrastructure of similar depth and quality as Rails.
Recognition
I learned about using static libraries on the iPhone in this awesome blog post. I used that as my starting point, and tried to automate the process as much as possible.
Monday, February 23, 2009
Hello, Xcode!
This post is "the making of" for a tool I'm writing that does automated modifications to Xcode projects. If you want to use the tool, or see the code, go to http://github.com/costan/zerg_xcode (scroll down to the bottom for the instructions).
Motivation
To the best of my knowledge, Xcode does not have a public API for interacting with its projects (asides from building with xcodebuild), and there is no tool out there filling this gap.
Xcode has a pretty good user interface, so it may seem that such a tool isn't worth the trouble. I beg to differ. Do you have unit tests? If so, you know they belong in a separate target... and once you have more than one target, you've seen Xcode's less-then-stellar UI for managing target membership. Wouldn't it be nice to have all the files ending in Test.m automatically placed in your unit test target?
Managing test case membership is not that difficult. But then came the iPhone. Xcode has no decent way of incorporating other people's code in a project. My standard for "decent" is being able to add someone's code quickly, and then change that code, as well as receive upstream updates.
Last but not least, the project format is rather readable. I think it was designed to be understood, and I assume Apple folks won't be unhappy to see programmatic access to their format.
My Goals
I hope that, one day, iPhone applications will be as easy to develop as Rails applications. This is what I would like to get done, eventually:
I know I can't possibly figure out how people will want to interact with their Xcode projects. After all, Apple tried and didn't get it perfectly right. So I wanted to make my tool inviting to use and learn, so fellow developers can code up the functionality they need quickly, and hopefully contribute it back to the project, so everyone's life is easier.
I developed the tool in Ruby, because I know and like the language. I packaged it using Rubygems, which comes pre-installed on OSX Tiger and above, so the tool can be installed with one command (the download happens automatically). I hope the quick installation will lower the barrier to adoption, and get me users, some of which will become developers.
I wrote a setup for Ruby's interactive sell (irb) so people can easily explore the structure of Xcode projects, and even experiment with changes. The 22 lines of code paid for themselves many times over, as I used the interactive shell myself to figure out. In the end, people will try to improve the tool if the time it saves them exceeds the time it takes them to learn the tool plus the time it takes to code the change. I hope the interactive shell tilts the scale in my favor.
I tried to make my code look decent, so it doesn't turn away developers who want to try changing it. I pushed big parts in separate directories, because having less to read is always nice. I used a plug-in architecture (don't think it's a big deal, it's less than 40 lines of code) to make it easy for others to implement new commands, and make it easy for me to intergrate the changes.
I wrote tests while developing, so I can feel when my API sucks, and so I can have good examples for using the API. This is asides from the traditional use of tests to assue quality.
Call for Contributions
I wrote this code because I didn't want to do repetitive actions while working with Xcode. I hope I'm not alone.
My code is a good foundation for tweaking Xcode projects. But a good foundation is nothing without good features on top. This is where you come in. Fork the project on Github, do something, and send me your changes!
Motivation
To the best of my knowledge, Xcode does not have a public API for interacting with its projects (asides from building with xcodebuild), and there is no tool out there filling this gap.
Xcode has a pretty good user interface, so it may seem that such a tool isn't worth the trouble. I beg to differ. Do you have unit tests? If so, you know they belong in a separate target... and once you have more than one target, you've seen Xcode's less-then-stellar UI for managing target membership. Wouldn't it be nice to have all the files ending in Test.m automatically placed in your unit test target?
Managing test case membership is not that difficult. But then came the iPhone. Xcode has no decent way of incorporating other people's code in a project. My standard for "decent" is being able to add someone's code quickly, and then change that code, as well as receive upstream updates.
Last but not least, the project format is rather readable. I think it was designed to be understood, and I assume Apple folks won't be unhappy to see programmatic access to their format.
My Goals
I hope that, one day, iPhone applications will be as easy to develop as Rails applications. This is what I would like to get done, eventually:
- merge targets from an Xcode project to another project; then we could have libraries that are as easy to integrate into projects as Rails' plugins (done)
- sync between Xcode file listing and on-disk files; this would allow me to move files around in sub-folders, and have Xcode reflect my actions automatically; also, I would be sure I didn't forget to delete files that I removed from my Xcode project; this is especially important for headers, which can impact a build even if they're not in the project
- build an iPhone application with all the settings needed for submission to the iTunes store
I know I can't possibly figure out how people will want to interact with their Xcode projects. After all, Apple tried and didn't get it perfectly right. So I wanted to make my tool inviting to use and learn, so fellow developers can code up the functionality they need quickly, and hopefully contribute it back to the project, so everyone's life is easier.
I developed the tool in Ruby, because I know and like the language. I packaged it using Rubygems, which comes pre-installed on OSX Tiger and above, so the tool can be installed with one command (the download happens automatically). I hope the quick installation will lower the barrier to adoption, and get me users, some of which will become developers.
I wrote a setup for Ruby's interactive sell (irb) so people can easily explore the structure of Xcode projects, and even experiment with changes. The 22 lines of code paid for themselves many times over, as I used the interactive shell myself to figure out. In the end, people will try to improve the tool if the time it saves them exceeds the time it takes them to learn the tool plus the time it takes to code the change. I hope the interactive shell tilts the scale in my favor.
I tried to make my code look decent, so it doesn't turn away developers who want to try changing it. I pushed big parts in separate directories, because having less to read is always nice. I used a plug-in architecture (don't think it's a big deal, it's less than 40 lines of code) to make it easy for others to implement new commands, and make it easy for me to intergrate the changes.
I wrote tests while developing, so I can feel when my API sucks, and so I can have good examples for using the API. This is asides from the traditional use of tests to assue quality.
Call for Contributions
I wrote this code because I didn't want to do repetitive actions while working with Xcode. I hope I'm not alone.
My code is a good foundation for tweaking Xcode projects. But a good foundation is nothing without good features on top. This is where you come in. Fork the project on Github, do something, and send me your changes!
Sunday, February 15, 2009
Synchronizing Git repositories without a server
This post describes a method for pushing changes between two repositories without using a server with network connections to both hosts having repositories. The solution is a reasonably straightforward application of local repositories, and I'm providing it to save the time of fellow developers with similar needs.
I first describe a solution using a USB stick to move data, which can be generalized to any other method for transferring files offline. Then I explain how to use this solution to deploy Rails applications using my tool, without a version control server. In case you're curious, I end the post explaining what prompted me to do this. Obviously, you can stop reading after you learned all you needed to know.
Pushing Changes with a USB Stick
I'm assuming your working directory is the place where you have your source repository. If not
Deploy Rails Applications without a Version Control Server
rpwn assumes that the source code for Rails applications is under version control on a server. But, at least when using git, applications can be deployed from repositories on USB sticks, created as explained in the previous section. Install an application as follows.
Motivation
I wanted to help someone deploy a Rails application in a government setting, where the application server is not connected to the Internet (stupid security rules). Worker's computers are still connected to the Internet, so we wanted to host the Git repository on Github. This way, the application can be developed and tested anywhere.
So, the development machine is connected to the Internet, but the application server is not. I didn't want to push unversioned source code to the application server, and I was hoping I don't have to add extra logic to rpwn to handle this case. Git local repositories turned out to be an awesome, if not well-documented, solution.
I hope you found this post useful, and kindly ask that you share any better methods you may come up with to solve your own problem.
I first describe a solution using a USB stick to move data, which can be generalized to any other method for transferring files offline. Then I explain how to use this solution to deploy Rails applications using my tool, without a version control server. In case you're curious, I end the post explaining what prompted me to do this. Obviously, you can stop reading after you learned all you needed to know.
Pushing Changes with a USB Stick
I'm assuming your working directory is the place where you have your source repository. If not
cd /path/to/your/repositoryStart up by creating a repository on the USB stick.
mkdir /path/to/usb/stick/repository.git git clone --local --bare . /path/to/usb/stick/repository.gitThen register the repository on the USB stick as a remote repository, and push the desired branch to it (if you don't want to push master, substitute your desired branch).
git remote add usb file:///path/to/usb/stick/repository.git git push usb masterIn the future, you can treat the USB repository as any other remote repository. Just make sure it's mounted :) For instance, the following pushes new changes to the USB repository.
git push usb
On the receiving end, mount the USB stick, and use a file URL for the repositoryfile:///path/to/usb/stick/repository.gitA few handy commands:
- cloning the repository on the USB stick
git clone file:///path/to/usb/stick/repository.git
- updating a repository cloned from the USB stick using the above command
git pull origin
- adding the USB stick repository as a remote for an existing repository
git remote add usb file:///path/to/usb/stick/repository.git
- updating from a remote repository configured using the above command
git pull usb master
Deploy Rails Applications without a Version Control Server
rpwn assumes that the source code for Rails applications is under version control on a server. But, at least when using git, applications can be deployed from repositories on USB sticks, created as explained in the previous section. Install an application as follows.
sudo rpwn install file:///path/to/usb/stick/repository.git
Keep in mind that rpwn will use the same repository URL to update the application, so you will always have to use a USB stick that mounts to the same location. This limitation can be overcome by adding another indirection layer -- create a symbolic link to the remote repository, and use that symlink when installing.ln -s /path/to/usb/stick/repository.git ~/victor/repository.git
sudo rpwn install file:///home/victor/repository.git
Note that the symlink preserves the repository name, so rpwn will still use the right name for the application.Motivation
I wanted to help someone deploy a Rails application in a government setting, where the application server is not connected to the Internet (stupid security rules). Worker's computers are still connected to the Internet, so we wanted to host the Git repository on Github. This way, the application can be developed and tested anywhere.
So, the development machine is connected to the Internet, but the application server is not. I didn't want to push unversioned source code to the application server, and I was hoping I don't have to add extra logic to rpwn to handle this case. Git local repositories turned out to be an awesome, if not well-documented, solution.
I hope you found this post useful, and kindly ask that you share any better methods you may come up with to solve your own problem.
Sunday, January 25, 2009
Dismissing the Virtual Keyboard on iPhone
This post is a quick recipe for making the virtual keyboard go away on the iPhone SDK. There are two aspects to the problem: dismissing the keyboard when the user taps Done (easy, most resources describe this right) and dismissing the keyboard when the user taps the screen outside any control that can receive focus.
When the user taps Done
Go to Interface Builder, and connect the edit control's delegate outlet to your view controller (in most cases, that will be the File's Owner). If your delegate is different, follow the steps below making changes when appropriate.
In the view controller, use the following snippet:
That's it, you're done. Run the code in the simulator and confirm it works.
When the user taps outside the field
You might see some more complicated solutions elsewhere (like Apress' book). The solution below works without any UI changes. Add the snippet below in your view controller. The snippet belongs in the view's controller, even if your text field's delegate is another object.
Bonus: reacting to the user leaving the field
If you want to take an action when the user leaves a field (such as issuing a Web service request in the background), the approach below plays nice with the modifications described in this post:
This code belongs in the text field's delegate (most of the time, it is your view controller).
I hope this post makes your life a bit easier. Happy coding!
When the user taps Done
Go to Interface Builder, and connect the edit control's delegate outlet to your view controller (in most cases, that will be the File's Owner). If your delegate is different, follow the steps below making changes when appropriate.
In the view controller, use the following snippet:
That's it, you're done. Run the code in the simulator and confirm it works.
When the user taps outside the field
You might see some more complicated solutions elsewhere (like Apress' book). The solution below works without any UI changes. Add the snippet below in your view controller. The snippet belongs in the view's controller, even if your text field's delegate is another object.
Bonus: reacting to the user leaving the field
If you want to take an action when the user leaves a field (such as issuing a Web service request in the background), the approach below plays nice with the modifications described in this post:
This code belongs in the text field's delegate (most of the time, it is your view controller).
I hope this post makes your life a bit easier. Happy coding!
Sunday, January 11, 2009
Date, time, and datetime validation in Rails 2.x
This is a very short post pointing to a good plug-in for validating time stuff in Rails. One-line summary: use validates_timeliness.
I wanted to validate the format of a datetime field in one of my models, so I tried validates_date_time and saw that Rails doesn't have it installed. I googled validates_date_time, and stumbled upon the plug-in with the same name by Jonathan Viney.
I installed the plugin, fixed the unit tests to run on Rails 2.2 with sqlite3, and then proceeded to write my validation, complete with unit tests. All the code is included, for your pleasure. After some booring debugging, I came to the conclusion the plugin can't handle invalid formats on new models, because of how it's using _before_type_cast to determine whether its parser failed or succeeded.
I googled for datetime validation in rails 2.2, hoping that someone fixed the bug. I didn't find a fix, but instead stumbled over the validates_timeliness plugin, written by Adam Meehan. In case you're seeing this in plain text, the link to the plug-in is http://github.com/adzap/validates_timeliness/
I hope Google indexes my post, and that it helps you avoid going through the same trouble that I have.
The code I used for this post:
I wanted to validate the format of a datetime field in one of my models, so I tried validates_date_time and saw that Rails doesn't have it installed. I googled validates_date_time, and stumbled upon the plug-in with the same name by Jonathan Viney.
I installed the plugin, fixed the unit tests to run on Rails 2.2 with sqlite3, and then proceeded to write my validation, complete with unit tests. All the code is included, for your pleasure. After some booring debugging, I came to the conclusion the plugin can't handle invalid formats on new models, because of how it's using _before_type_cast to determine whether its parser failed or succeeded.
I googled for datetime validation in rails 2.2, hoping that someone fixed the bug. I didn't find a fix, but instead stumbled over the validates_timeliness plugin, written by Adam Meehan. In case you're seeing this in plain text, the link to the plug-in is http://github.com/adzap/validates_timeliness/
I hope Google indexes my post, and that it helps you avoid going through the same trouble that I have.
The code I used for this post:
Sunday, January 4, 2009
Auto-rotating Tab Bars on the iPhone
This post is a quick summary of what's needed to get a tab bar (like the one in the Clock application) to switch from portrait to landscape when the user rotates their phone. Accelerometer goodness, yum!
The process is easy, but it has a couple of pitfalls. Here are the steps:
I hope you found this useful. If you have more tips, please post them in the comments, and I'll edit the posting accordingly, so others can have an easier time finding this information.
The process is easy, but it has a couple of pitfalls. Here are the steps:
- You have to override shouldAutorotateToInterfaceOrientation: in the view controllers for all the views in the tab bar. If a view controller's shouldAutorotateToInterfaceOrientation: returns NO, then the tab bar will not rotate, even if the view is hidden at the time of the rotation.
- You should not override the tab bar controller's version of shouldAutorotateToInterfaceOrientation:
- For regular views in the tab bar add the code below to viewDidLoad. If you skip this, your view will not resize when the phone is rotated while it's selected. However, it will resize when the user transitions to it from another view.
- Make sure the controls on your regular views respond to changes in view size. If you're using Interface Builder's springs and struts, you can test the views right in IB, using the arrow at the right of the views' title bars.
I hope you found this useful. If you have more tips, please post them in the comments, and I'll edit the posting accordingly, so others can have an easier time finding this information.
Subscribe to:
Posts (Atom)

