If you are implementing application settings using iPhone’s Application Preferences, then you will want to take note of this pitfall.
Referring to the schema reference for PSTextFieldSpecifier, you would notice that there is a DefaultValue key. You might thought that this key is to return a default value, when the preference is not set.
In terms of code, you might thought that myvalue would return the default value.
NSString *myvalue = [[NSUserDefaults standardUserDefaults] stringForKey:@"mykey"]
But no, that is NOT the case. myvalue will always return nil, until you go to the Application Preferences page. In order to read a default value correctly, you will have to do more.
Refer to AppPrefs Sample Code on how that can be done. The code is copied here for reference.
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey];
if (testValue == nil)
{
// no default values have been set, create them here based on what's in our Settings bundle info
NSString *pathStr = [[NSBundle mainBundle] bundlePath];
NSString *settingsBundlePath = [pathStr stringByAppendingPathComponent:@"Settings.bundle"];
NSString *finalPath = [settingsBundlePath stringByAppendingPathComponent:@"Root.plist"];
NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:finalPath];
NSArray *prefSpecifierArray = [settingsDict objectForKey:@"PreferenceSpecifiers"];
NSString *firstNameDefault;
NSDictionary *prefItem;
for (prefItem in prefSpecifierArray)
{
NSString *keyValueStr = [prefItem objectForKey:@"Key"];
id defaultValue = [prefItem objectForKey:@"DefaultValue"];
if ([keyValueStr isEqualToString:kFirstNameKey])
{
firstNameDefault = defaultValue;
}
// Handle for other preferences you might have
// ...
}
// since no default values have been set (i.e. no preferences file created), create it here
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
firstNameDefault, kFirstNameKey,
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// we're ready to do, so lastly set the key preference values
firstName = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey];
August 1st, 2010 in
How-to | tags:
pitfall |
View Comments
I refuse to pay an extra $20, for a smaller SIM card.
With dignity, I cut my Singtel standard SIM card to fit for my iPhone 4.
As you can see, it is not hard. Just cut around the metal piece.
July 30th, 2010 in
How-to | tags:
iPhone |
View Comments
I was out jogging the other day.
At the end of my run, I wanted to buy a drink, but I soon realized that I have forgotten to bring along cash with me! I have my iPhone with me, but can it pay for my drinks?
I started to think of solutions..
Thinking: If everyone is a mobile ATM, and I could use my phone to transfer money electronically to these mobile ATM, it will be great! As long as they could “dispense” the money, I would not mind paying a commission fee for the service.
Not bad an idea.. Hence I am submitting it for Paypal X Developer Challenge.

On a full page advertisement for Samsung Galaxy S in Straits Times today:
I am happy to find SG Toto as one of the app that works for the Android phone.
Great.
But wait, I don’t remember releasing the app for Android..
We are proud to announce the release of a new iPhone app – The LOST Whispers
This is the first entertainment app we have created, and a good prank app we believe it is. What you can do with the app is simple.

Yup. That’s what the app does – Play creepy whispering sounds and terrify your friends!
For more info about the app, visit whispers.just2us.com, or simply download now.
Apple seems to lack a MapKit programming guide. I have to look through the MapKit reference, search on the Internet, and read blog articles in order to do a few simple tasks with MapKit.
I thought it would be great if there is a MapKit programming guide, similar to the Push Notification Service programming guide provided by Apple.
But there isn’t. So I am here writing one for developers who are interested to use MapKit for that few simple tasks. This post contains 8 code snippets for 8 tasks.
1. Adding a map view
If you simply want to add a map to your view, simply create a MKMapView object and insert it. That’s our first big step!
- (void)viewDidLoad {
[super viewDidLoad];
// Init our map view
mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:mapView atIndex:0];
}
2. Configuring the map
With a map, you could now configure various aspects by setting the mapView properties. Examples below:
// Set the map type such as Standard, Satellite, Hybrid
mapView.mapType = MKMapTypeStandard;
// Config user interactions
mapView.zoomEnabled = NO;
mapView.scrollEnabled = YES;
// Set the region and zoom level
MKCoordinateRegion region;
MKCoordinateSpan span;
CLLocationCoordinate2D location;
location.latitude = 1.302851; // Singapore!
location.longitude = 103.85523;
span.latitudeDelta = 0.02;
span.longitudeDelta = 0.02;
region.span = span;
region.center = location;
// Set to that region with an animated effect
[mapView setRegion:region animated:TRUE];
// Lastly, set the MKMapViewDelegate (we will use this later)
mapView.delegate = self;
3. Showing the user’s location
To show the user’s location on the map, we set this one special property.
mapView.showsUserLocation = YES;
4. Creating custom annotations/landmarks
If you want to display some landmarks, aka annotations, on the map, you will need to create your annotation class that implement the MKAnnotation protocols.
Say you want to display some shops on the map, this is want you would do.
// ShopAnnotation.h
@interface ShopAnnotation : NSObject <mkannotation> {
Shop *shop; // Assuming this class contains info about a shop
}
// ShopAnnotation.m
// Required to implement
- (CLLocationCoordinate2D)coordinate {
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = shop.latitude;
theCoordinate.longitude = shop.longitude;
return theCoordinate;
}
// Optional
- (NSString *)title {
return shop.name;
}
// Optional
- (NSString *)subtitle {
return shop.address;
}
5. Adding annotations to the map
To add the annotations to the map, you would create the ShopAnnotation earlier and add them to mapView.
for (Shop *shop in allMyShops) {
ShopAnnotation *shopAnnotation = [[[ShopAnnotation alloc] initWithShop:shop] autorelease];
[mapView addAnnotation:*shopAnnotation ];
}
6. Handling the annotation views
Annotations are not views. After you added your annotations to the map, you would still need to provide its views. The mapView delegate methods will be called to ask for your annotations’ VIEWS. You will need to create the view and return it for mapView to display.
In our example, we create a MKPinAnnotationView, which is a standard pin that you see in Maps app. You could otherwise create your custom view that extends MKAnnotationView.
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <mkannotation>)annotation {
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// If it is our ShopAnnotation, we create and return its view
if ([annotation isKindOfClass:[ShopAnnotation class]]) {
// try to dequeue an existing pin view first
static NSString* shopAnnotationIdentifier = @"ShopAnnotationIdentifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:shopAnnotationIdentifier ];
if (!pinView) {
// If an existing pin view was not available, create one
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:shopAnnotationIdentifier] autorelease];
customPinView.pinColor = MKPinAnnotationColorRed;
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
// add a detail disclosure button to the callout which will open a new view controller page
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;
} else {
pinView.annotation = annotation;
}<strike></strike><strike></strike>
return pinView;
}
}
7. Selecting a pin
When a user selects a pin and press the UIButtonTypeDetailDisclosure button within the callout, we can present more details about the annotation. Implement another MKMapViewDelegate to handle this.
- (void)mapView:(MKMapView *)_mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
// Handle it, such as showing another view controller
}
8. Open Maps app
If want to provide a route from the user location to the selected annotation, you would need the help of iPhone’s Maps app. This means that your app will exit and Maps app will be opened, with you telling Maps the source and destination to route.
You can open Maps with the schema as such.
NSString *url = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f";, userLatitude, userLongitude, [shop.latitude floatValue], [shop.longitude floatValue]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
With that, we have come to the end of a few simple tasks with MapKit!
WP-Syntax is the answer.
For example, this is how I highlight an iPhone’s Objective-C code in this post.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *title = [NSString stringWithFormat:@"My %@ syntax", @"AWESOME"];
self.title = title;
}
To use WP-Syntax, simply surround the code with <pre lang=”LANGUAGE”> and </pre>, where LANGUAGE is the programming language.
To find out what to use for LANGUAGE, look under supported languages here.
This is an issue where an application that is opened from Android’s Market might encounter a force close. txeet had the same issue:
This is due to the application having two launcher components, and Market is confused and therefore not able to launch. Strangely, some phones do not face the same problem.
Though this is a bug on Android side, the application can resolve by simply adding a line in the manifest file.
<activity-alias android:name="com.android.internal.app.ResolverActivity" android:targetActivity=".Main" android:exported="true"/>
Just like my other apps that have gone v2, SG Blood is upgrading to v2 too!
SG Blood is an app for blood donor, and was first released in Jan 2009. I didn’t update the app much over the year, partly because it works well and has no bugs, and partly because I have no improvement planned for it.
But today, I am proud to announce a new feature for the app: Checking blood stock level!

The feature is kindly provided by donorweb.
Ok, I once said that I don’t think much of Nexus One.. but Google is generous enough to give me one.. and since I promised, I shall switch to use Nexus One for a week (:
And ya, her name is iNexus.
April 30th, 2010 in
Android | tags:
Android |
View Comments