Trap when a class property is set/get

Trap when a class property is set/get

The aim of this post is just explain in a simplified way how to trap when a class property is set/get. The most typical scenario where this mechanism is used is when you have to do some calculations before returning a property value (in case or get) or when you have some tasks when is being set a new property value (in case of set). This mechanism is also very useful when somethings does not go as you expect  with an attribute.

 

The syntax

The syntax is quite straightforward. If I have a property called xxxx, then the methods that you have to overwrite are setXxxx and Xxxx.  It has been added the prefix ‘set’ followed by the first uppercase letter attribute name, ant the rest as it is. Let me show you an example for better understanding, this is the property declaration:

#import <Foundation/Foundation.h>

@interface Alice : NSObject

@property (strong,nonatomic) NSString* name;

@end

… And those are the overwritten methods:

#import "Alice.h"
@interface Alice(){
    int iSetNames;
    int iGetNames;
}
@end

@implementation Alice

@synthesize name;

-(NSString*) name{
    iGetNames++;
    NSLog(@"Get name called: %d times",iGetNames);
    return name;
}

-(void) setName:(NSString *)name{
    iSetNames++;
    NSLog(@"Set name called: %d times",iSetNames);
}

@end

Let’s play with it

I have created a sample singe view project, and in the ViewController class viewDidLoad method I have added the following chunk:

Alice *aAlice = [[Alice alloc]init];
aAlice.name=@"Alice";
NSLog(@"%@",aAlice.name);

And this is the log:

2015-04-05 08:57:47.080 PropertiesSimplified[939:31102] Set name called: 1 times
2015-04-05 08:57:49.429 PropertiesSimplified[939:31102] Get name called: 1 times

You can find the sample project that I have use for writing this post here.

 

Notification mechanism simplified (swift)

The aim of this post is to explain and provide an example about notification mechanism simplified (,but not simplistic) in swift. The first thing that you need to be clear is when to use this mechanism and when delegate mechanism.

Both mechanism help to decouple view controllers. Notifications offer the advantage that multiple objects can observer one notifications.  In delegate mechanism the communication is direct (through a protocol method implementation) with the delegate class.

The example that I am going to present to shows the notification mechanism as a broadcast service. A timer periodically will launch a notification, on the other side there will be two classes (Alice and Bob) that will be intercepting the message.

public enum NotificationMessage: String {
    
    case kTimerNotificationId = "NotificationIdentifier"
}

class ViewController: UIViewController {

    
    var aAliceClass:ClassAlice!
    var aBobClass:ClassBob!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        aAliceClass = ClassAlice()
        aBobClass = ClassBob()
        
        // Do any additional setup after loading the view, typically from a nib.
        var timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: Selector("sendNotification"), userInfo: nil, repeats: true)
    }
    
    func sendNotification(){
        NSNotificationCenter.defaultCenter().postNotificationName(NotificationMessage.kTimerNotificationId.rawValue, object: nil)
    }

}

As you can see in the code every 3 seconds is sent a notification that is intercepted by Alice and Bob class in the following way:

class ClassAlice: NSObject {

    var counter:Int = Int()
    
    override init() {
        super.init()
        
        counter = 0
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:NotificationMessage.kTimerNotificationId.rawValue, object: nil)
    }
    
    func methodOfReceivedNotification(notification:NSNotification){
        println( "Message intercepted from Alice")
        
        counter++;
        
        if(counter >= 3){
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    }
}

Is important to keep under control when to unsubscribe to the notification mechanism. In case of Alice is after receiving 3 messages and in case of Bob is when the class is removed from memory.

class ClassBob: NSObject {

    
    override init() {
        super.init()
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:NotificationMessage.kTimerNotificationId.rawValue, object: nil)
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func methodOfReceivedNotification(notification:NSNotification){
        println( "Message intercepted from Bob")

    }

}

Once we run the project we should have to see the following in the log window:

logs

You can find the sample project here.

 

 

 

 

 

Key-Value Observing mechanism simplified

The aim of this post is to show how it works Key-Value Observing mechanism (KVO). KVO is a mechanism for transparently notifying observers of changes in object properties. In other words,  this mechanism will allow us to trap when some object property value is being modified.

Implementation

We will create a class that will hold the property to be observed:

#import <Foundation/Foundation.h>

@interface NewObject : NSObject

@property int iPropertyToBeObserved;

+ (id)sharedInstance;

@end

Its implementation is the following:

#import "NewObject.h"

@implementation NewObject

+ (id)sharedInstance {
    static NewObject *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

-(id) init{
    if([super init]){
        self.iPropertyToBeObserved=3;
    }
    return self;
}


@end

As you can see the property is set to 3 in the class initialiser. Now we are going to implement the KVO mechanism in the ViewController. We will add the observer in the viewDidLoad Method:

...
     [[NewObject sharedInstance] addObserver:self forKeyPath:@"iPropertyToBeObserved" options:NSKeyValueObservingOptionInitial context:nil];
...

As important as setup the observer is remove it when it is not necessary, I will add it in the dealloc method:

-(void)dealloc{
    [[NewObject sharedInstance] removeObserver:self forKeyPath:@"iPropertyToBeObserved"];
}

In the viewWillAppear method I will update property that is being observed:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    NewObject  *aNewObject=[NewObject sharedInstance];
    aNewObject.iPropertyToBeObserved=5;
}

The callback that is being called every time that the property is changed is the following:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"iPropertyToBeObserved"]) {
        NSLog(@"New Value:%d",[[NewObject sharedInstance] iPropertyToBeObserved]);
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

@end

When you will run the project you will see that the above function is called twice. Once during NewObject initialisation and the other during viewDidAppear.

kvo

And in the log screen:

2015-03-11 22:33:15.437 KVOSimplified[5865:118370] New Value:3
2015-03-11 22:37:33.297 KVOSimplified[5865:118370] New Value:5

You can download the code from here.

 

 

Singleton design pattern in a template

The aim of this post is to present Singleton design pattern in a template. I have seen some post and articles that showed the implementation key points separately, so this is why I have decided to write a mini-post showing an implementation template and its usage.

First of all, let’s define what a Singleton pattern is:

...the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects…. (Wikipedia)

Pattern implementation

This is my singleton implementation class:

#import "MySingletonClass.h"

@implementation MySingletonClass{
    int iLocalAttribute;
}

-(id) init{
    if([super init]){
        iLocalAttribute=5;
    }
    
    return self;
}

+ (MySingletonClass*)sharedInstance
{
    static MySingletonClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MySingletonClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

-(int) giveMe5{
    iLocalAttribute+=5;
    return iLocalAttribute;
}

@end

I have added a local attribute (iLocalAttribute), for showing how to handle them, at the beginning I had to create them as static and for having access to them I had also to create static methods, but in a few lines I will explain how to avoid that.

The key point is the sharedInstance method:

  1. Declare a static variable to hold the instance of the class, ensuring it’s always available, but inside of  sharedInstance method context.
  2.  dispatch_once_t which ensures that the initialization code executes only once.
  3. Instance of MySingletonClass.
  4. Finally return the instance class.

Finally I have created a simple function that updates the local attribute and returns its value. As you can see neither the attribute nor the method are static.

This is the header class:

#import <Foundation/Foundation.h>

@interface MySingletonClass : NSObject

+ (MySingletonClass*)sharedInstance;
-(int) giveMe5;

@end

 

Pattern usage

This is my singleton implementation class:

   NSLog(@"%d",[[MySingletonClass sharedInstance] giveMe5]);

 

 

Integrating FontAwesome on watchkit

The aim of this post is integrating FontAwesome on watchkit extension target. Font Awesome gives you scalable vector icons. This font has many advantages. First, a would dare to say that you will find the icon that you were looking for in its catalog. Second, that if you do not need more than one color, instead of placing an image resource you will be placing a character. Could y0u  figure it out how much space are you saving up?. And third, that you will not have problem on scaling because it is a vector image.

The base project

For setup the base project just follow the instructions from a previous post. You have to add the 3 necessary files for integrating font awesome, at the end of this post you will find the link to the project on GitHub.

Integrating FontAwesome on watchkit

 

And be sure that NSString+FontAwesome.m file is ready for the following targets.

targetsase

 

For both targets, be sure that:

1. In project properties>watchkitFontAweSome extension>BuildPhases>Copy Bundle Resources is included FontAwesome.ttf.

addfonttotarge

 

2. Add the following key array in the Info.plist file:

Fonts provided by application > Item 0 String FontAwesome.ttf

infoplist

 

You could also edit the source code and add the following xml snippet:

    <key>UIAppFonts</key>
    <array>
        <string>FontAwesome.ttf</string>
    </array>

 Repeat the two steps for the other target.

Let’s code

Add a text label in the storyboard where we will print some icon with the new font:

interfacecontro

 

Link the label to an IBOutlet in InterfaceController.m

iboutlet2

Add the following snippet for adding some text to the label:

#import "NSString+FontAwesome.h"

...
- (void)willActivate {
    // This method is called when watch view controller is about to be visible to user
    
    //Setup button texts
    NSString *cellText = [NSString stringWithFormat:@"%@ upload", [NSString fontAwesomeIconStringForIconIdentifier:@"fa-cloud-upload"]];
    [self.lblText setText:cellText];
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ resto", [NSString fontAwesomeIconStringForIconIdentifier:@"fa-cloud-upload"]]];
    [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:kFontAwesomeFamilyName size:30] range:NSMakeRange(0, 1)];
    [self.lblText setAttributedText:attributedString];
    
    
    
    
    NSLog(@"%@ will activate", self);
}

In my case I have decided to put it on the willActivate method from InterfaceController.m. Basically what I am doing here is setting an attributed text, where fa-cloud-upload is the name of the icon that I am interested in showing. Finally, I am setting FontAwesome for the first character of the string, the rest of the string is presented with the default font.

Run the target extension.

targetextension

 

 

If you did not missed any step you should have to see the following in the simulator:

demofont

As you can see the fa-cloud-upload symbol has been shown at the beginning of the text. You can also download this project from Github.

Image animations on Watchkit sdk

The aim of this post is just showing how to do a simple image animation. I have been investigating if it was possible to make animations in Watchkit using CALayer class, as in normal iPhone and iPad apps, but it has not been possible. The possibilities that provides UI in the Watchkit are very very poor, I figure it out that apple guys are fixing that.

The base project

For setup the base project just follow the instructions from a previous post. Add in the main scene the image that will hold the animation.

Image animations on Watchkit

Link the image to an IBOutlet.

IBOUTLETImage animations on Watchkit

 

Now we will add the images used for the animation:

Image animations on Watchkit

Add the following lines to the watch kit interface view controller:

- (void)willActivate {
    // This method is called when watch view controller is about to be visible to user
    
    [self.imgSpriteAnimation setImageNamed:@"dragon-"];
    [self.imgSpriteAnimation startAnimatingWithImagesInRange:NSMakeRange(0, 60) duration:1.0 repeatCount:0];
    
    NSLog(@"%@ will activate", self);
}

And Finally run the target:

Image animations on Watchkit

If the instructions were followed you should have to see something like this:

Image animations on Watchkit

 

If you had any doubt about what I have explained, you can find this project on Github.

Communication between Apple Watch and iPhone app

The aim of this post is to show a possible mechanism for implementing the communication between Apple Watch and iPhone app. After trying several methods: CoreData, NSKeyedUnarchiver and NSUserDefaults, I have decided to chose NSUserDefault because it was the most simplified one. I would recommend the other two just in case that you wanted to share bigs amounts of data.

The application that I am going to create will show in the watch screen the value of a counter, that is increased (or decreased) from the iPhone app. Before continuing, be sure that you are working with Xcode 6.2, otherwise you will not be able to create a watchkit extension.

Create a new Single View project

Create a new Single View Application project:

Communication between Apple Watch and iPhone app

Communication between Apple Watch and iPhone app

 

Go to project properties>Capabilites>App Group, turn it on and create a new group:

Communication between Apple Watch and iPhone app

 

In the iPhone app storyboard we will add another label and a stepper:

Communication between Apple Watch and iPhone app

 

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIStepper *stpCounter;
@property (weak, nonatomic) IBOutlet UILabel *lblCounter;
@end

Add an action method for the stepper and leave it in blank by the moment, we will fill it later.

Communication between Apple Watch and iPhone app

The watch kit extension

Go to File>New>Target…>iOS>Apple Watch

Communication between Apple Watch and iPhone app

Communication between Apple Watch and iPhone app

 

And go to project properties, select the target extension (E), select Capabilities, turn on App Groups and select the group that you created before:

Communication between Apple Watch and iPhone app

 

Now we will place the label in the watch kit storyboard that will show the value of the counter.

Communication between Apple Watch and iPhone app

...
@interface InterfaceController()
@property (weak, nonatomic) IBOutlet WKInterfaceLabel *lblCounter;
@end
...

 The common data

I have created a new group on top the project hierarchy and added a module called Model, that is where I will place the common data.

Communication between Apple Watch and iPhone app

 

VERY IMPORTANT: Be sure that those files are assigned for both targets:

Communication between Apple Watch and iPhone app

 

Now is time to fill the stepper action method that we have created previously and do not forget the #import:

...
#import "Model.h"
...
- (IBAction)stpValueChanged:(id)sender {
    [self.lblCounter setText:[[NSString alloc] initWithFormat:@"%f",[(UIStepper*)sender value]]];
    [Model setCounter:[[[NSNumber alloc]initWithDouble:[(UIStepper*)sender value]] intValue]];
}
...

Now let make an stop in the path for checking if stepper is updating the counter. Select watchkitCounter target and any iPhone simulator and press the play button for running the app in the iPhone:

Communication between Apple Watch and iPhone app

 

Click on the stepper for assuring that label updates with counter value:

Communication between Apple Watch and iPhone app

 

Next step is to fill in the watch kit extension interface controller:

#import "InterfaceController.h"
#import "Model.h"

...

- (instancetype)initWithContext:(id)context {
    self = [super initWithContext:context];
    if (self){
        
        // Initialize variables here.
        // Configure interface objects here.
        NSLog(@"%@ initWithContext", self);
        
        [self.lblCounter setText:[[NSString alloc] initWithFormat:@"%d",[Model getCounter]]];
        
        [NSTimer scheduledTimerWithTimeInterval:0.5
                                         target:self
                                       selector:@selector(refreshValue)
                                       userInfo:nil
                                        repeats:YES];
        
    }
    return self;
}

...

-(void) refreshValue{
    int iCounter=[Model getCounter];
   
    [self.lblCounter setText:[[NSString alloc] initWithFormat:@"%d",iCounter]];

    
}

@end

 

I have initialised the label when the form is loaded and program a timer for pulling the data. Finally build and execute the target watchkitCounter Watch App:

Communication between Apple Watch and iPhone app

 

Once the simulator is on you will see that the app is not running, this is normal. Be sure that apple watch simulator is also on screen, if does not go to iOS Simulator>Hardware>External Displays>Apple Watch (and re-run):

Communication between Apple Watch and iPhone app

 

Do not get nervous, if you see blank screen on watch kit simulator, on my computer (Mac-mini 16GB+SSD) takes almost 10 seconds for starting up. Once is on, you will see that watch-simulator refreshes the value of the counter, but the iPhone simulator does not start up the iPhone app, next step is select the iPhone app play with the stepper and observe how counter in the watch-simulator is being updated.

Communication between Apple Watch and iPhone app

 

And that is all!. In case that you had any doubt or something were not properly explained, you can download the demo project from here. I hope that this post would be useful and clarified your doubts, please feel free to send me any comment or amend.

 

A simplified framework creation tutorial

The aim of this post is provide a simplified framework creation tutorial. This post is targeted to those who want to create a static library (framework) in iOS and never did it before.

Getting started

Start off by creating a new Cocoa Touch Static Library project.

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

Next step is add some basic code to the library. This is the header file:

#import <Foundation/Foundation.h>

@interface SimplifiedFramework : NSObject

-(NSString*) helloWorld;

@end

… And that the implementation:

#import "SimplifiedFramework.h"

@implementation SimplifiedFramework

-(NSString*) helloWorld{
    
    return @"Hello World!!!";
}

@end

 

A simplified framework creation tutorial

 

The framework (library) has not been generated yet, you will see the libSimplifiedFramework.a in red.

This is an important issue, before compiling select the target SimplifiedFramework and the device iOS Device. Otherwise it will appear the message that says that compilation is successful but the library binary will not be generated.

A simplified framework creation tutorial

 

For generating the library binary, go to Xcode menu Product>Archive

A simplified framework creation tutorial

Now you should have to see that library is in black, that means that library has been successfully created.

A simplified framework creation tutorial

Universal libraries

Reached to that point the library is generated, but for a concrete platform. The target now is generate a multi-platform library. For doing that you have to create a new target

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

 

Select universalSimplifiedFramework target and in its project options add a new build phase.

A simplified framework creation tutorial

 

Now is time to add the script that will generate the multiplatform library, this script is extracted from another article that explains with more detail how to create a library.

# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# Step 1. Build Device and Simulator versions
xcodebuild -target SimplifiedFramework ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target SimplifiedFramework -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"

# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"

Replace in Step 1, SimplifiedFramework by your project name.

A simplified framework creation tutorial

 

For building just select Product>Archive from Xcode menu:

A simplified framework creation tutorial

 

And check in the logs if all was fine.

A simplified framework creation tutorial

Client app

So as to check if the proper if all the process was carried on well, we will create a new app that will use the library. For doing that we will add a new target:

Go to Xcode menu and select File > New > Target :

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

 

A simplified framework creation tutorial

 

 

Once the app has been created, it is time to setup the project options that the app is going to use the library:

 

A simplified framework creation tutorial

 

Select SimplifiedApp target and in General section, unfold Linked Frameworks and Libraries and select add:

A simplified framework creation tutorial

A simplified framework creation tutorial

 

The following code will call the function defined in the library. Place that code in the view controller class:

#import "ViewController.h"
#import "SimplifiedFramework.h"

@interface ViewController ()
...
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    SimplifiedFramework *aFramework = [[SimplifiedFramework alloc]init];
    NSLog(@"%@",aFramework.helloWorld);
}

And run the app target for any device, in my case I have used iPhone6 device.

A simplified framework creation tutorial

As you can see in the last screen shot the client library app is calling a function from the library without major problems.

Conclusion

As I said at the beginning of the post, this is a simplified vision of how to create a library. From that point you can find very interesting articles about how to create frameworks in Xcode, like:

Ernesto GarcíaCreating a static Librfary in iOS Tutorial.

Sam DaviesHow to Create a Framework for iOS

 

Disable fullscreen mode on MPMoviePlayerController

The aim of this post is explain how to disable fullscreen mode  on MPMoviePlayerController. From the beginning you could think that there would be a flag to control that, but the reality is quite different. Since apple guys do not put hands on it, the rest we will have to deal with workarounds like this one.

The problem

My problem was that I wanted to embed a movie player in a scene, but movie player showed the fullscreen button mode. The aim of my scene was allow to play a movie in a part of the scene. Googling about this matter I found that this problem was known, but none of the solutions given worked fine to me, that’s why I want to report my personal solution.

The solution.

The solution consists in two independent actions. The first one is track all Movie player subviews, and once found the one that contains the fullscreen button view just hide it.

Add this chunk of code in the place where you initialise your player:

....
//Because we have to wait until controllers are shown
[self performSelector:@selector(hideFullscreenButton) withObject:self afterDelay:0.5];
...

The call must be deferred because until the movie player is not presented, its sub collection of views is not built.

As movie player view is a tree of subviews, the unique I had to track this structure by using a recursive call:

 
-(void) hideFullscreenButton{
    //Hide full screen mode button
    [self hideFullscreenSubview:movieClip.view.subviews];
 }

-(void) hideFullscreenSubview:(NSArray*)arr{
        for(UIView *v in arr){
            if([v.subviews count]>0)
                [self hideFullscreenSubview:v.subviews];
            else
            if(v.frame.origin.x==975 ){
                v.hidden=TRUE;
            }
        }
    }

A clarification, movieclip is an instance of MPMoviePlayerController. Since there is no identifier tag for the view I had to check its properties to know which view I had to hide. In my case was the view coordinates, it does not sound professional solution, but after days breaking stones I did not something better.

The second one is overwrite tap actions on movie player, because doble tap does a full screen. Also add the following chunk of code in the place where you initalise the movie player.

...
    movieClip.controlStyle = MPMovieControlStyleEmbedded;

    //Disable tap for not allowing that movie control set on a full screen mode.
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:@selector(doSingleTap)];
    singleTap.numberOfTapsRequired = 1;
    [movieClip.view addGestureRecognizer:singleTap];

    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:@selector(doDoubleTap)];
    doubleTap.numberOfTapsRequired = 2;
    [movieClip.view addGestureRecognizer:doubleTap];
    [singleTap requireGestureRecognizerToFail:doubleTap];
...

And its selector methods:

    -(void) doSingleTap{
        //DO NOTHING!!!
    }

    -(void) doDoubleTap{
        //DO NOTHING!!!
    }

… for doing nothing.

If all was implemented as described, you should have to see that it has disappeared fullscreen icon and double tapping on video does not do anything at all.

Disable fullscreen mode on MPMoviePlayerController
Disable fullscreen mode on MPMoviePlayerController

This solution is also explained in Stackoverflow .

Location services problem in iOS 8

Location services problem in iOS 8

We will create an app that will fix the location services problem found in iOS 8. In the latest release iOS, some developers found that released apps that used location services stop working.

The sample project

Lets create a new  single view application  project.

Single view application template project for Location services problem in iOS 8

One of the key points for fixing the location services problem in iOS 8 is add one of the two new keys in YourApp-Info.plist file. Open the file as source code and paste the following chunk of xml code.

NSLocationAlwaysUsageDescription
Your message

or

NSLocationWhenInUseUsageDescription
Your message

Info-plist file for fixing Location services problem in iOS 8

Then in the view controller class header: import Corelocation header; define that the class will implement CLLocationManager delegate protocol and define an attribute for handling the device location

#import 

@interface ViewController : UIViewController 

@property (nonatomic,strong) CLLocationManager *locationManager;

In the view controller implementation class add the #define:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

In the view ViewDidLoad method add the following snippet:

//In ViewDidLoad
[self statLocationManager];

Add the method startUpdationLocation:

-(void)statLocationManager
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    
    if(IS_OS_8_OR_LATER) {
        [self.locationManager requestAlwaysAuthorization];
        
        // Commented out because in this example I have not used NSLocationWhenInUseUsageDescription
        //    [self.locationManager requestWhenInUseAuthorization];
    }   

     [self.locationManager startUpdatingLocation];
}

And finally implement the protocol method:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *newLocation = [locations lastObject];
    CLLocation *oldLocation;
    if (locations.count > 1) {
        oldLocation = [locations objectAtIndex:locations.count-2];
    } else {
        oldLocation = nil;
    }
    NSLog(@"didUpdateToLocation %@ from %@", newLocation, oldLocation);
}

If all was set properly didUpdateLocations callback should be called, this is the test that you can succeed with the location services problem in iOS 8:

debugging didUpdateLocations for fixing Location services problem in iOS 8

On the target device

And finally last, but not least be sure that the location services are enabled for your app in the device. Select Settigs >Privacy > Location Services and be sure that your app has this services as Always or While Using.

Some times location services problem in iOS 8, is just that the settings of your app were not properly right.

IPphone_iOS_8_Location_Service maximize-your-iphones-battery-life-ios-8.w654

 

Your can find more information about that issue here.