XCode4.1 & CLLocationManager


#1

Just installed Lion/XCode4.1 and the Whereami application no longer runs in the simulator.
I get the message, “server did not accept client registration”

more info here: devforums.apple.com/message/492073


#2

Yeah, it’s a bug. A pretty crappy bug, I might add. The solution in the mean time is to add this to the top of your WhereamiAppDelegate.m file (after the imports, but before @implementation WhereamiAppDelegate):

@implementation CLLocationManager (TemporaryHack)

- (void)hackLocationFix
{
    CLLocation *location = [[CLLocation alloc] initWithLatitude:42 longitude:-50];
    [[self delegate] locationManager:self didUpdateToLocation:location fromLocation:nil];     
}

- (void)startUpdatingLocation
{
    [self performSelector:@selector(hackLocationFix) withObject:nil afterDelay:0.1];
}

@end

#3

Before I added this code, my iPhone would just “locate” me at 1 Infinite Loop, Cupertino. It still does the same even after adding this code to the top of my WhereamiAppDelegate.m file.


#4

Thanks Joe for this hack! I remember reading during the introduction your warning to those who did not enroll for the full $99/year Apple Dev license as it would not allow you to run apps on the iPhone even for testing purposes (no cert).

So far all the apps run great in the simulator and then I hit chapter 4 and the Log just kept printing that same annoying error. I figured it was because I was using a simulator and not an actual iPhone so I assumed as long as no other errors were being thrown I should be ok (the app didn’t crash btw I just checked the logs).

Glad I check the forums after each chapter before moving on. I was able to patch this in my code. I incorporate reading the forum posts for each chapter along with the challenges and the for the more curious sections. Great work on making this stuff easy to understand!

BTW, jmstone, this code is for those running the simulator. Since you are running this on your iPhone it is most likely not needed.


#5

I second that - thanks for the hack! After finishing out the chapter I went back to the “Heading” challenge. Using Joe’s location hack as a template I added a few lines to let the location stuff work with the simulator. Was this necessary, or is there a better way to handle it?

[code]- (void)hackHeadingFix
{
NSString *heading = [NSString stringWithString:@“Somewhere that direction-ish!”];
[[self delegate] locationManager:self didUpdateHeading:(id)heading];
}

  • (void)startUpdatingHeading
    {
    [self performSelector:@selector(hackHeadingFix) withObject:nil afterDelay:0.1];
    }[/code]

#6

bgstech, did you receive a heading output when you compiled and ran the code? I didn’t see an NSLog entry for printing to screen. I tried to complete the challenge though I did not try to institute a “hack” as you did. I called startUpdatingHeading and used an NSLog command and nothing printed.

I could have tried a hack, instead I went on. I think I am going to just invest the $99 and be done with it! If my future app will involve any of this I am never going to know during test unless I launch it on an iOS device.


#7

Guys I am still having issues even after the hack fix. Here is my source:

.m:

#import “WhereamiAppDelegate.h”
@implementation CLLocationManager (TemporaryHack)

  • (void)hackLocationFix
    {
    CLLocation *location = [[CLLocation alloc] initWithLatitude:42 longitude:-50];
    [[self delegate] locationManager:self didUpdateToLocation:location fromLocation:nil];
    }

  • (void)startUpdatingLocation
    {
    [self performSelector:@selector(hackLocationFix) withObject:nil afterDelay:0.1];
    }
    @end
    @implementation WhereamiAppDelegate

@synthesize window = _window;

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    //Create location manager object
    locationManager = [[CLLocationManager alloc] init];

    //There will be a warning from this line of code. Ignore it for now.
    [locationManager setDelegate:self];

    //we want all results from the location manager
    [locationManager setDistanceFilter:kCLDistanceFilterNone];

    // and we want it to be as accurate as possible
    // regardless of how much time/ battery it takes
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    //tell our manager to start looking for its location immediately.
    [locationManager startUpdatingLocation];
    [[self window] makeKeyAndVisible];
    return YES;
    }
    -(void)locationManager:(CLLocationManager *)manager
    didUpdateLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
    {
    NSLog(@"%@", newLocation);
    }

-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(@“Could not find location :%@”,error);
}

  • (void)applicationWillResignActive:(UIApplication )application
    {
    /

    Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    */
    }

  • (void)applicationDidEnterBackground:(UIApplication )application
    {
    /

    Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    */
    }

  • (void)applicationWillEnterForeground:(UIApplication )application
    {
    /

    Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    */
    }

  • (void)applicationDidBecomeActive:(UIApplication )application
    {
    /

    Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    */
    }

  • (void)applicationWillTerminate:(UIApplication )application
    {
    /

    Called when the application is about to terminate.
    Save data if appropriate.
    See also applicationDidEnterBackground:.
    */
    }

  • (void)dealloc
    {
    [_window release];
    [super dealloc];
    }

@end

.h:

//
// WhereamiAppDelegate.h
// Whereami
//
// Created by Erik Pilgrim on 8/19/11.
// Copyright 2011 MyCompanyName. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface WhereamiAppDelegate : NSObject
{
CLLocationManager *locationManager;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

And here is the Error:

2011-08-20 17:51:01.611 Whereami[7313:b603] -[WhereamiAppDelegate locationManager:didUpdateToLocation:fromLocation:]: unrecognized selector sent to instance 0xa127a30
2011-08-20 17:51:01.613 Whereami[7313:b603] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[WhereamiAppDelegate locationManager:didUpdateToLocation:fromLocation:]: unrecognized selector sent to instance 0xa127a30’
*** Call stack at first throw:
(
0 CoreFoundation 0x00e385a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f8c313 objc_exception_throw + 44
2 CoreFoundation 0x00e3a0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00da9966 forwarding + 966
4 CoreFoundation 0x00da9522 _CF_forwarding_prep_0 + 50
5 Whereami 0x000021d5 -[CLLocationManager(TemporaryHack) hackLocationFix] + 197
6 Foundation 0x0081179e __NSFireDelayedPerform + 441
7 CoreFoundation 0x00e198c3 CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 19
8 CoreFoundation 0x00e1ae74 __CFRunLoopDoTimer + 1220
9 CoreFoundation 0x00d772c9 __CFRunLoopRun + 1817
10 CoreFoundation 0x00d76840 CFRunLoopRunSpecific + 208
11 CoreFoundation 0x00d76761 CFRunLoopRunInMode + 97
12 GraphicsServices 0x01a451c4 GSEventRunModal + 217
13 GraphicsServices 0x01a45289 GSEventRun + 115
14 UIKit 0x00098c93 UIApplicationMain + 1160
15 Whereami 0x000020d9 main + 121
16 Whereami 0x00002055 start + 53
)
terminate called throwing an exceptionsharedlibrary apply-load-rules all
(gdb)

What do you think?


#8
  1. It’s easier to read code that’s copy-and-pasted into ‘Code’ tags (using the button right above the text field where the post is entered) since it doesn’t lose the indentation.

  2. Unless I’m mistaken (and I could well be), the hackHeadingFix has a memory leak. The location reference is obtained via new, alloc, or copy (+alloc here) so the app owns it but it’s neither released nor autoreleased.

  3. In pilgrimtech’s case, there are two issues. The smaller one is that the heading file never says it’s implementing the CLLocationManagerDelegate protocol. The bigger issue is that the implementation was spelled incorrectly. The error message is spot-on: the routine -locationManager:didUpdateToLocation:fromLocation: doesn’t exist. (Look closely at the name where you think it’s defined.)


#9

D’OH

Thank you for looking at the code for me, Fresh Set of eyes always helps.

I misspelled the didUpdateToLocation by not putting the ‘To’ in…

Thanks again.


#10

Might I suggest this instead:

CLLocation *location = [[CLLocation alloc] initWithLatitude:37.331689 longitude:-122.030731];

Since the default location in the next chapter takes you to Apple HQ, this should roughly match up with it.


#11

Lion 10.7.1 and Xcode 4.1

Testing on Simulator.

This worked for me. Thanks.

[quote=“JoeConway”]Yeah, it’s a bug. A pretty crappy bug, I might add. The solution in the mean time is to add this to the top of your WhereamiAppDelegate.m file (after the imports, but before @implementation WhereamiAppDelegate):

[code]
@implementation CLLocationManager (TemporaryHack)

  • (void)hackLocationFix
    {
    CLLocation *location = [[CLLocation alloc] initWithLatitude:42 longitude:-50];
    [[self delegate] locationManager:self didUpdateToLocation:location fromLocation:nil];
    }

  • (void)startUpdatingLocation
    {
    [self performSelector:@selector(hackLocationFix) withObject:nil afterDelay:0.1];
    }

@end
[/code][/quote]


#12

hi,

I am running the Whereami app on the iPhone 4.3 simulator. I added the temporaryHack as described in the fix and received this message

2011-10-05 22:14:51.523 Whereami[915:b603] Could not find location: <+33.56000000, +118.24000000> +/- 0.00m (speed -1.00 mps / course -1.00) @ 10/5/11 10:14:51 PM Eastern Daylight Time
Terminating in response to SpringBoard’s termination.

So is this the correct output I should get ?

Any help is appreciated
Cheers
David


#13

The fix from Joe Conway worked for me. thanks. :smiley: