RSS Feed!

Recent Posts

Recent Comments

Archive for the ‘iPhone’ Category

AKL Transit

Friday, May 14th, 2010

I was going to send a tweet instead of posting here but 140 characters would not have been enough…

The Auckland Transit iPhone and iPod Touch application has been in the app store for a few weeks now and it’s already providing me with some very interesting statistics.

Unlike Wellington, most of the iPhone users are NOT using a 3GS model but 3G rather. The number of jailbroken devices is 4 times the one in Wellington and, more interestingly, whilst in Wellington the peak is Mondays or Fridays in Auckland it seems to be Saturday instead.

Monitoring user behaviour between Wellington and Auckland will be an interesting exercise, especially since the Auckland user numbers are growing so rapidly.

Wellington – Real Time Public Transport Information

Sunday, February 28th, 2010

WelliBUS users have been asking me for real time bus info ever since WelliBUS was first released a long time ago.

I have been in touch with the Metlink people (who are just awesome) but sadly the information will not be available any time soon, and even when it will become available 3rd parties will probably have to wait even longer (unless they decide to start scraping HTML).

So after doing some thinking I have decided to try and implement it myself. Yup, I am indeed crazy. The craziest part is that I believe that this could work, especially if you get involved. At the moment 4000 of you are using WelliBUS and I would like to thank each and every one of you. Most of you are using iPhones, the rest are on iPod touches and Android devices. Although this is intended mostly for iPhone users there are scenarios when even an iPod touch can be used (WiFi on the bus, Free Wifi Hotspots, etc).

If out of 4000 people just 2000 decide to use this system I am sure we will get pretty good coverage, especially at peak times when we need it the most.

I have already starting implementing this which is why I am asking for everyone’s help. Please post comments below to tell me what you think, what I should and should not do, what you think is most important in the first release, what I missed out on, whatever you think might be useful. Once you’ve done this please spread the word. Don’t forget to download WelliBUS if you have an iPhone, iPod touch or Android device.

Here’s how I was thinking that it would work.

User waiting for the bus:

  • Starts the app and selects the bus stop number they are at and also the service numbers that they want a notification for.  (e.g. Stop 5002 – St James Theatre, Services 1 – Island Bay, 46 – Broadmeadows, 54 – Churton Park)
  • Either leaves the application running (at least in the 1st release) or closes the application and waits for a push notification (future release)

User traveling on the bus:

  • After getting on the bus the user selects the service that they are on and taps “I’m on the Bus“. (e.g. select stop 5000 – Courtenay Place, Service 54 – Churton Park)
  • User leaves the application running and can alternatively see on a Google Map view as the bus travels towards its destination
  • User sees a Good Citizen points indicator. See how the points work below.

WelliBUS will:

  • Notify the user in stop 5002 that a service 54 – Churton Park is on its way and reports the approximate distance between the stops
  • Reward the user on the bus 1 Good Citizen point for having helped another traveller find out when the bus was coming. The more people use the information broadcast by the user on the bus the more Good Citizen points the users get. All users that broadcast their location on the bus will get “rewarded”
  • Provide a Good Citizen ranking system (users can register and submit their points to our server)

Good Citizen points:

  • A user that leaves the application running while on the bus (between start and stop) will accrue 0.5 points for each stop they pass by
  • If at least another user is on the same bus and broadcasts the information then all users receive another 0,5 points
  • For each user that is notified about the bus that the Good Citizen is on then another point is awarded.
  • Sponsors can reward Good Citizens: e.g. maybe Snapper can give them extra credit, maybe Metlink could discount a monthly pass as long as a minimum number of points is accrued the previous month. Other sponsors can be as creative as they want. The rewards should be provided in exchange for Citizen Points. The claimed points will go towards a Sponsors Ranking. (e.g. If my favourite coffee shop in Wellington, Mojo Old Bank give a free coffee for every 200 Citizen Points then their points value will go up by 200 every time they offer a reward. This is a rough guide at the moment)

Cheating:

  • If a person is in a car rather than on a bus then the application will detect the car speed, missing the stops, and other similar checks
  • If somebody does manage to fool the “system” the other people will be able to veto them. e.g. if user A reports being on a bus that never reaches user B although it should then user B will be able to give thumbs down to user A. The more thumbs down the slower the user accrues Citizen points. Eventually a lying user can be removed from the system.
  • Other “punishments” could be applied. Be creative!

You can:

  • Donate. You can help the development of this feature by contributing with funds.

  • Spread the word! Nothing is more helpful.
  • Twit about this. Here’s an example Help Wellington get Real Time Public Transport information. http://bit.ly/9pq2v3 Please RT
  • Post a link to this post on your Facebook wall. For example you could post Make Wellington the first city in the world with real time traffic info driven by us. Details here http://bit.ly/9pq2v3
  • You could sponsor this project. There are many ways in which you can help. First email office [at] tmro [dot] net and we will take it from there.
  • You could buy ads in WelliBUS. Your business logo and a 1 sentence message could be displayed on the Map View close to a relevant stop.
  • You could help in ways I haven’t even thought about.

Cheers…

Updating the UISearchBar programmatically

Friday, October 16th, 2009

Today I had to update WelliBUS’s search bar programmatically because I needed to use the street picked up via GPS as my street name.

Until this point implementing the search bar seemed easy:

  • adopt a couple of protocols: UISearchDisplayDelegate and UISearchBarDelegate
  • implement a few callback methods (from the delegates listed above)
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString;
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption;
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller;
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller;
  • and implement my own filtering function
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope;

The problem I had on my hands was how to programmatically update the text in the UISearchBar and force the UISearchDisplayDelegate to call the appropriate callback methods.

Turns out it was simpler than expected (despite not being able to find a solution by googling). All that was needed was:

[self.searchDisplayController.searchBar becomeFirstResponder];
self.searchDisplayController.searchBar.text = returnString;

Cheers…

Urban Airship – Push Notifications

Sunday, October 4th, 2009

Today I have finally added Push Notifications to Parcel Trackr.

I decided not to waste time and I went for Urban Airship. I registered, uploaded my push certificate, downloaded the sample and integrated the two systems.

Not everything went smoothly though because when I first ran the application I got a

Failed to register with error: Error Domain=NSCocoaErrorDomain Code=3000 UserInfo=0×120610 “no valid ‘aps-environment’ entitlement string found for application”

I thought my provisioning profile did not include the right entitlement… so I re-downloaded it and tried again. Turns out I was using the wrong provisioning profile.

So if you want to avoid my mistake just make sure that after you’ve configured push services in the iPhone Dev Center you download the updated provisioning profile and then you install it via XCode.

Other things worth checking include: the product name in your build configuration matches the app id and of course, the ultimate solution, clean all targets before building!

Cheers…

WelliBUS is out

Monday, September 21st, 2009

Overview
On Thursday 17th of September Apple approved WelliBUS. Now the people in Wellington, NZ have a new option when it comes to finding out when their bus comes:
- use www.metlink.org.nz
- txtBUS 287 (20c / msg)
- 0800 801 700 (free)
- WelliBUS (free, needs an active internet connection)

A quick look at txtBUS will show you what a neat service it is. Type the stop number (optionally the service number and time), send yr msg to BUS (287) and there you go. But what happens when you don’t know that stop number? Or what if you forget the txt syntax? You can browse the metlink website or you can call their 0800 number. Alas neither option is convenient. This is where WelliBUS excels!

With WelliBUS you can do everything that you can do with txtBUS but you can also find out the bus stop number by searching by a street name or by simply tapping a GPS button that will do the hard work for you. Then you’ll be returned a list of nearby stops. Just tap one and you’re done! WelliBUS let’s you filter by date or service number just as you’d expect it to.

Launch
WelliBUS has been out there for only a few days now and I have to say I am impressed by the feedback I’ve received. Thank you everyone.
I don’t know if it is because it’s free or because Wellingtonians love their iPhones or because they use public transportation a lot.

I know many of you are asking about real time bus information, it’s coming but you have to be patient, from what I’ve heard you won’t have to wait much longer… At this point treat this as a rumor.

I hear a few of you have found some issues, please post them here as comments and I will prioritize them and tackle them as soon as I can. I know there is a typo and I know that if you filter by buses using 00 prefixes the app fails to filter. So if you search for service 008 please use just 8 instead.

If you want a copy, the app is here WelliBUS

Rest assured the app will stay free, ad-free, bloatware free. But if you like it I encourage you to download one of my paid apps from here: tmro apps.

Cheers…

p.s. My close friends know the funny story of how this application was conceived, but this is neither the place nor the time to share that story…

p.p.s. please leave your comments and feature requests as comments below.

iPhone how to: center and horizontal align the contents of a UITextField

Friday, August 7th, 2009

It’s as simple as:

1
2
theTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
theTextField.textAlignment = UITextAlignmentCenter;

Basically this will ensure that no matter how tall your text field is the actual text will be centered both vertically and horizontally.

Cheers…

iPhone build error

Saturday, July 18th, 2009

I had to deal with the same problem twice in the past 2 days so I decided to put together this little post explaining what one needs to do when they see an error message like this:

error: syntax error before ‘AT_NAME’ token
error: syntax error before ‘}’ token
fatal error: method definition not in @implementation context
Build error message

Build error message

Basically, what happens here is that the target for my iPhone application is using the wrong C/C++ Compiler version.

Here’s the fix:
Step 1 double click the target (or right click Get Info) and change the Compiler version to GCC 4.0

Compiler Version changed to 4.0

Compiler Version changed to 4.0

Step 2 add 2 new build setting conditions (one for the simulator and one for the device)

Build Setting Conditions

Build Setting Conditions

Step 3 Set the values to GCC 4.2

Final settings

Final settings

Hit the magic Cmd + B and you should now have a project that builds (or at least no longer complains about the syntax error above.

Cheers…

UITabBarButtonItem did not change its title

Monday, May 18th, 2009

Today I needed to implement the UITableView's edit / delete functionality inside my UITableViewController. That is fairly simple: 

1. in Interface Builder add a UITabBarButtonItem 
2. from the identifier list select "Edit"
3. Associate with the correct file owner
4. Pick selector and
5. In the selector implementation change the title from "Edit" to "Done" and the other way round depending on the tableView.editing property.
(6. the actual delete operation is not covered in this post)  
I assumed that after tapping the tab button the label would change to "Done". Sadly that did not happen. After a bit of debugging I found that the weird behaviour is caused by a set of _barButtonItemFlags. One of these flags is called "isSystemItem". Unfortunately this flag is set by the Interface Builder in step 2 above.
The solution:  
In step 2 above select Custom and the set the Bar Item Title below in the Interface Builder. 
In step 5 make sure you set the title back to "Edit" when coming out from the editing mode.
Even better solution (biased oppinion):
Avoid using IB to create you UIBarButtonItem! Instead just create the button programmatically using initWithTitle:style:target:action  
How do you create your Buttons?
Cheers…

Selecting a contact on the iPhone

Tuesday, May 12th, 2009

Today I had to load a Contact browser in my iPhone application I have to say I was surprised to see how easy it was!

The first thing that I thought about was to… google for it. Sure, I didn't know this side of the API and I imagined I would have to query some address book database and then build a table view using my query results as datasource. And guess what, this can actually be done very easily.
 
Luckily I looked deeper in the SDK API and found that there is a Navigation Controller already available that does everything I need.
Here are the steps I had to follow in order to implement this functionality.

1. Imports
Add the AddressBook and AddressBookUI frameworks to my project (control click the Target and then Get Info and Add Framework)

2. Set up the controller
Create an instance of ABPeoplePickerNavigationController on the control that you want to trigger the contact selection.

3. Set up a delegate
The controller will make a series of callbacks which is why you need to implement a protocol that is the actual delegate for the above controller. The delegate is ABPeoplePickerNavigationControllerDelegate and the callback methods are below:
– (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;  
Gets called when the user taps the Cancel navigation button. Here you should dismiss the person picker navigation controller. See point 4 below.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person;
This is the place where you get access to the actual section therefore you have to make sure you use the person reference to extract the data you need. See point 5 below. If you want the user to get detailed information about the selected user return YES, if you're only after the name and want to limit navigation just return NO.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier;
This is where you take action if the user taps various properties such as phone number, email, etc If you are simply after the person's name like I was simply return NO.

4. Loading the controller and dismissing it
You load the ABPeoplePickerNavigationController using your current navigation controller's presentModalViewController method. You implement this wherever you handle the tap / action on the triggering control.
When the user taps cancel you dismiss the people picker controller via the dismissModalViewControllerAnimated method belonging to your controller. You implement this in the peoplePickerNavigationControllerDidCancel method above.

5. Extracting the relevant information
The ABRecordRef pointer gives you access to the contacts details. Here is how you'd extract the contact's first name:
 
  CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);

Notice the  kABPersonFirstNameProperty constant. There are many more like this one that enable you to get the data you need. Here is the complete list:

kABPersonFirstNameProperty
kABPersonLastNameProperty
kABPersonMiddleNameProperty
kABPersonPrefixProperty
kABPersonSuffixProperty
kABPersonNicknameProperty
kABPersonFirstNamePhoneticProperty
kABPersonLastNamePhoneticProperty
kABPersonMiddleNamePhoneticProperty
kABPersonOrganizationProperty
kABPersonJobTitleProperty
kABPersonDepartmentProperty
kABPersonEmailProperty
kABPersonBirthdayProperty
kABPersonNoteProperty
kABPersonCreationDateProperty
kABPersonModificationDateProperty

Don't let the CFString data type scare you. You can simply cast to a (NSString *) and use it… This is just one of the interchangeable data types, but that will be another post.

Cheers…

Special App Stores

Friday, May 8th, 2009

Today I was having a conversation about the Apple App Store App Review process and I realized that I don't really mind a little bit of censorship but with a twist…

Let me explain:
1. The Junk Store
Not all apps should make it to the store. I honestly think that if an app does not really do anything then it probably should not be allowed in the store. Say an app says: "I'm rich!". Is it really an app? Owning a Porsche would achieve the same result (telling people I'm rich) and it would also help the German economy… 
Now the question is what does one do with this app though? Somebody wrote it, and they want it to be available to all the people who find it useful. I vote for the creating of another App Store called "The Junk Store". Really, so many apps could go in there. Just imagine: you write an app and you immediately get access to the Junk Store: you can upload apps, updates, etc. In the Junk Store all apps are equal, they need no review process, they come with no warranty and they make no promises that they won't break your phone or eat your battery alive. Users only need to point to the Junk Store and then a jungle awaits them in there. Knock yourselves out people, download and try stuff at your own risk!
2. The Awesome People Store
Now there are some people (see these ones) who have hundreds of applications in the app store. They just clutter the gorram store! Now I vote for creating "The Awesome People Store". In this store developers "move" the apps that they consider to be the least likely to generate revenue for them. Think of it as the Archive Store… apps go to the App Store and after a while, when they fall in disgrace and people seldom download them they get moved to the Awesome People Store. Accessing this store can be done either via the main store or directly… Apps here are not guaranteed to work on the latest iPhone OS version either which a bonus.  
3. The Enterprise Store
Now this is maybe a bit too serious for this post. I believe there is a need for an Enterprise Store because there are just too many enterprise-ish applications that don't really belong in the public App Store. Say your company has 200 employees. You cannot really get an Enterprise license and you have to put your app(s) in the bloody store. There they will be public and people might end up downloading them for no reason: waste of bandwidth and time plus a bonus of frustration for some of us… Another reason for this Enterprise Store is that currently it is very hard to build a product (iPhone app) that can be sold and resold to enterprises with a little bit of specific branding on it. You either have to make some sort of activation screen or you need to issue a new app for each of your customers (this means going through approvals and such that are time wasting and annoying).
An Enterprise Store will solve this issue: you create a Product, you sell it to your first customer (enterprise) and the app goes through the usual process. After that you "notify" Apple that you've released a new app (with just a different branding, service endpoint, function configuration etc) and you just move along…
What would all these new rules achieve is a less cluttered, more value adding App Store. I am keen to hear what you people think so feel free to post your comments below…
Cheers…
p.s. what "stores" would you like to see?