Friday, April 11, 2014

iOS Singleton Pattern Under ARC

Singleton Pattern is one of the most famous software design pattern being used in many softwares. It simply and surely always return the same one single instance of a class. It will provide the same instance for whoever need an instance of it.

Basically in Java, if you need a singleton class, you need to define a private static variable, which could be initialized and assigned once. Then, any time other class needs an instance of this class, this class will check if the static instance variable is null or not. If it's not null, return it. Otherwise, initialized and assign it. For more detail, I'd recommend the book <Head First Design Patterns>(This book's code is implemented in Java).

While the problem is how can we implement this design in Objective-C.

Here is the snippet of code.

+ (MyClass *)sharedInstance {
    static MyClass *sharedInstance;
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [[MyClass alloc] init];
        }
    }
    return sharedInstance;
}

The Apple doc recommends the fowlloing way, which is the same as the one above:

+ (MyClass *)sharedInstance
{
    //  Static local predicate must be initialized to 0
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

Tuesday, April 1, 2014

How to Remove All the Map Annotations except Current User Location Annotation

Today, working on the project focused on Location and Map View Programming. I need to update the Map Annotation Display when user zoom in and out the map. This would totally make sense here the Annotation will not be resizable and too many of the Annotations displayed in a very small area on the Map.

It's like this April Fool's Day, Google Map on mobile device gave people the fun of being a Pokemon Master by finding all the Pokemon, which is displayed as an Annotation on the map. It could be seen only when certain zoom level you are in. So, to find all the Pokemon, you have to zoom to certain level, then search it manually like a tank.

So, the question here is how can we remove these MKAnnotations.

This task is very easy by using one line code:


[self.mapView removeAnnotations:self.mapView.annotations];

The mapView is the outlet connected with MKMapView in the storyboard.

But this line of code would remove all of the annotations on the map. While my app intentionally need to keep the current user location's annotation to constantly display the current location of the user. How can we do that?

We need to iterate through all the annotations, find out which one is not the Current User Location Annotation.


for (id<MKAnnotation> annotation in self.mapView.annotations) {
    if (![annotation isKindOfClass:[MKUserLocation class]]) {
        [self.mapView removeAnnotation:annotation];
    }
}

Simple solution.

Good luck with your own project.