Skip to content

Commit

Permalink
New API-Design: There is now a separate LocationManager that acts as …
Browse files Browse the repository at this point in the history
…the CLLocationManagerDelegate
  • Loading branch information
myell0w committed Feb 6, 2011
1 parent 389bbc8 commit 092bde3
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 110 deletions.
1 change: 1 addition & 0 deletions MTLocateMe.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
#import "MTLocateMeButton.h"
#import "MTLocationDefines.h"
#import "MTLocationFunctions.h"
#import "MTLocationManager.h"
8 changes: 3 additions & 5 deletions MTLocateMeBarButtonItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,19 @@
#import "MTLocationDefines.h"

@class MTLocateMeButton;
@protocol MTLocateMeButtonDelegate;


@interface MTLocateMeBarButtonItem : UIBarButtonItem <CLLocationManagerDelegate> {
@interface MTLocateMeBarButtonItem : UIBarButtonItem {
MTLocateMeButton *locateMeButton_;
CLLocationManager *locationManager_;
}

@property (nonatomic, assign) MTLocationStatus locationStatus;
@property (nonatomic, assign) BOOL headingEnabled;
@property (nonatomic, readonly) CLLocationManager *locationManager;
@property (nonatomic, assign) id<MTLocateMeButtonDelegate> delegate;


- (id)initWithLocationStatus:(MTLocationStatus)locationStatus;
// if you pass in a locationManager the button acts as it's delegate and sends Notifications when location changes
- (id)initWithLocationStatus:(MTLocationStatus)locationStatus locationManager:(CLLocationManager *)locationManager;

- (void)setLocationStatus:(MTLocationStatus)locationStatus animated:(BOOL)animated;

Expand Down
120 changes: 51 additions & 69 deletions MTLocateMeBarButtonItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ @interface MTLocateMeBarButtonItem ()

@property (nonatomic, retain) MTLocateMeButton *locateMeButton;

- (void)locationManagerDidUpdateToLocationFromLocation:(NSNotification *)notification;
- (void)locationManagerDidUpdateHeading:(NSNotification *)notification;
- (void)locationManagerDidFail:(NSNotification *)notification;

@end


@implementation MTLocateMeBarButtonItem

@synthesize locateMeButton = locateMeButton_;
@synthesize headingEnabled = headingEnabled_;
@synthesize locationManager = locationManager_;


////////////////////////////////////////////////////////////////////////
Expand All @@ -41,33 +44,43 @@ @implementation MTLocateMeBarButtonItem
////////////////////////////////////////////////////////////////////////

// the designated initializer
- (id)initWithLocationStatus:(MTLocationStatus)locationStatus locationManager:(CLLocationManager *)locationManager {
- (id)initWithLocationStatus:(MTLocationStatus)locationStatus {
locateMeButton_ = [[MTLocateMeButton alloc] initWithFrame:CGRectZero];

if ((self = [super initWithCustomView:locateMeButton_])) {
locateMeButton_.locationStatus = locationStatus;
locateMeButton_.locationManager = locationManager;
// pass is nil for locationManager if you don't want to use it
locationManager_ = [locationManager retain];
locationManager_.delegate = self;

// begin listening to location update notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(locationManagerDidUpdateToLocationFromLocation:)
name:kMTLocationManagerDidUpdateToLocationFromLocation
object:nil];
// begin listening to heading update notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(locationManagerDidUpdateHeading:)
name:kMTLocationManagerDidUpdateHeading
object:nil];
// begin listening to heading update notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(locationManagerDidFail:)
name:kMTLocationManagerDidFailWithError
object:nil];
}

return self;
}

- (id)initWithLocationStatus:(MTLocationStatus)locationStatus {
return [self initWithLocationStatus:locationStatus locationManager:nil];
}

// The designated initializer of the base-class
- (id)initWithCustomView:(UIView *)customView {
return [self initWithLocationStatus:MTLocationStatusIdle];
}

- (void)dealloc {
// end listening to location update notifications
[[NSNotificationCenter defaultCenter] removeObserver:self];

[locateMeButton_ release], locateMeButton_ = nil;
[locationManager_ release], locationManager_ = nil;


[super dealloc];
}

Expand Down Expand Up @@ -100,17 +113,25 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvent
[self.locateMeButton addTarget:target action:action forControlEvents:controlEvents];
}

- (void)setDelegate:(id<MTLocateMeButtonDelegate>)delegate {
self.locateMeButton.delegate = delegate;
}

- (id<MTLocateMeButtonDelegate>)delegate {
return self.locateMeButton.delegate;
}


////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark locationManager Delegate
#pragma mark Location Manager Notifications
////////////////////////////////////////////////////////////////////////

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
newLocation, @"newLocation",
oldLocation, @"oldLocation", nil];

// only set new location status if we are currently not receiving heading updates
- (void)locationManagerDidUpdateToLocationFromLocation:(NSNotification *)notification {
CLLocation *newLocation = [notification.userInfo valueForKey:@"newLocation"];

// only set new location status if we are currently not receiving heading updates
if (self.locationStatus != MTLocationStatusReceivingHeadingUpdates) {
// if horizontal accuracy is below our threshold update status
if (newLocation.horizontalAccuracy < kMTLocationMinimumHorizontalAccuracy) {
Expand All @@ -119,59 +140,20 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLoca
[self setLocationStatus:MTLocationStatusSearching animated:YES];
}
}

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidUpdateToLocationFromLocation object:self userInfo:userInfo];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
error, @"error", nil];

[self setLocationStatus:MTLocationStatusIdle animated:YES];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidFailWithError object:self userInfo:userInfo];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
newHeading, @"newHeading", nil];

[self setLocationStatus:MTLocationStatusReceivingHeadingUpdates animated:YES];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidUpdateHeading object:self userInfo:userInfo];
}

- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager {
return YES;
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
region, @"region", nil];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidEnterRegion object:self userInfo:userInfo];
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
region, @"region", nil];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidExitRegion object:self userInfo:userInfo];
- (void)locationManagerDidUpdateHeading:(NSNotification *)notification {
CLHeading *newHeading = [notification.userInfo valueForKey:@"newHeading"];

if (newHeading.headingAccuracy > 0) {
[self setLocationStatus:MTLocationStatusReceivingHeadingUpdates animated:YES];
} else {
[self setLocationStatus:MTLocationStatusReceivingLocationUpdates animated:YES];
}
}

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
region, @"region",
error, @"error", nil];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerMonitoringDidFailForRegion object:self userInfo:userInfo];
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: manager, @"locationManager",
[NSNumber numberWithInt:status], @"status", nil];

[[NSNotificationCenter defaultCenter] postNotificationName:kMTLocationManagerDidChangeAuthorizationStatus object:self userInfo:userInfo];
- (void)locationManagerDidFail:(NSNotification *)notification {
[self setLocationStatus:MTLocationStatusIdle animated:YES];
}


Expand Down
16 changes: 16 additions & 0 deletions MTLocateMeBarButtonItem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
39CFA14312FA267100B859F9 /* MTLocationFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 39CFA14112FA267100B859F9 /* MTLocationFunctions.h */; };
39CFA14412FA267100B859F9 /* MTLocationFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 39CFA14212FA267100B859F9 /* MTLocationFunctions.m */; };
39CFA15E12FA29F000B859F9 /* MTLocateMe.h in Headers */ = {isa = PBXBuildFile; fileRef = 39CFA15D12FA29F000B859F9 /* MTLocateMe.h */; };
39E47D1312FF41D100649F01 /* MTLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 39E47D1112FF41D100649F01 /* MTLocationManager.h */; };
39E47D1412FF41D100649F01 /* MTLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 39E47D1212FF41D100649F01 /* MTLocationManager.m */; };
AA747D9F0F9514B9006C5449 /* MTLocateMeBarButtonItem_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* MTLocateMeBarButtonItem_Prefix.pch */; };
AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
/* End PBXBuildFile section */
Expand All @@ -38,6 +40,8 @@
39CFA14112FA267100B859F9 /* MTLocationFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLocationFunctions.h; sourceTree = "<group>"; };
39CFA14212FA267100B859F9 /* MTLocationFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLocationFunctions.m; sourceTree = "<group>"; };
39CFA15D12FA29F000B859F9 /* MTLocateMe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLocateMe.h; sourceTree = "<group>"; };
39E47D1112FF41D100649F01 /* MTLocationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLocationManager.h; sourceTree = "<group>"; };
39E47D1212FF41D100649F01 /* MTLocationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLocationManager.m; sourceTree = "<group>"; };
AA747D9E0F9514B9006C5449 /* MTLocateMeBarButtonItem_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLocateMeBarButtonItem_Prefix.pch; sourceTree = SOURCE_ROOT; };
AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
D2AAC07E0554694100DB518D /* libMTLocateMeBarButtonItem.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMTLocateMeBarButtonItem.a; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -88,6 +92,7 @@
08FB77AEFE84172EC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
39E47D1012FF41A000649F01 /* Delegation */,
39CFA14712FA268F00B859F9 /* Buttons */,
39CFA14612FA268500B859F9 /* Utils */,
39CFA15D12FA29F000B859F9 /* MTLocateMe.h */,
Expand Down Expand Up @@ -139,6 +144,15 @@
name = Buttons;
sourceTree = "<group>";
};
39E47D1012FF41A000649F01 /* Delegation */ = {
isa = PBXGroup;
children = (
39E47D1112FF41D100649F01 /* MTLocationManager.h */,
39E47D1212FF41D100649F01 /* MTLocationManager.m */,
);
name = Delegation;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand All @@ -152,6 +166,7 @@
39382D7E12E9B6400012007D /* MTLocationDefines.h in Headers */,
39CFA14312FA267100B859F9 /* MTLocationFunctions.h in Headers */,
39CFA15E12FA29F000B859F9 /* MTLocateMe.h in Headers */,
39E47D1312FF41D100649F01 /* MTLocationManager.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -208,6 +223,7 @@
39382D7B12E9B6400012007D /* MTLocateMeBarButtonItem.m in Sources */,
39382D7D12E9B6400012007D /* MTLocateMeButton.m in Sources */,
39CFA14412FA267100B859F9 /* MTLocationFunctions.m in Sources */,
39E47D1412FF41D100649F01 /* MTLocationManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
14 changes: 13 additions & 1 deletion MTLocateMeButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#import <CoreLocation/CoreLocation.h>
#import "MTLocationDefines.h"

@protocol MTLocateMeButtonDelegate;


@interface MTLocateMeButton : UIButton {
// Current Location-State of the Button
Expand All @@ -34,13 +36,23 @@
UIView *activeSubview_;

BOOL headingEnabled_;
CLLocationManager *locationManager_;

id<MTLocateMeButtonDelegate> delegate_;
}

@property (nonatomic, assign) MTLocationStatus locationStatus;
@property (nonatomic, assign) BOOL headingEnabled;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, assign) id<MTLocateMeButtonDelegate> delegate;

- (void)setLocationStatus:(MTLocationStatus)locationStatus animated:(BOOL)animated;

@end



@protocol MTLocateMeButtonDelegate <NSObject>

- (void)locateMeButton:(MTLocateMeButton *)locateMeButton didChangeLocationStatus:(MTLocationStatus)locationStatus;

@end
36 changes: 4 additions & 32 deletions MTLocateMeButton.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ @implementation MTLocateMeButton
@synthesize imageViewFrame = imageViewFrame_;
@synthesize activeSubview = activeSubview_;
@synthesize locationManager = locationManager_;
@synthesize delegate = delegate_;


////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -114,6 +115,7 @@ - (id)initWithFrame:(CGRect)frame {
}

- (void)dealloc {
delegate_ = nil;
[activityIndicator_ release], activityIndicator_ = nil;
[imageView_ release], imageView_ = nil;
[locationManager_ release], locationManager_ = nil;
Expand Down Expand Up @@ -261,38 +263,8 @@ - (void)locationStatusToggled:(id)sender {
// update to new location status
[self setLocationStatus:newLocationStatus animated:YES];

// check new status after status-toggle
// and update locationManager accordingly
switch(newLocationStatus) {
// if we are currently idle, stop updates
case MTLocationStatusIdle:
//NSLog(@"Stopped updating");
[self.locationManager stopUpdatingLocation];
[self.locationManager stopUpdatingHeading];
break;

// if we are currently searching, start updating location
case MTLocationStatusSearching:
//NSLog(@"Start updating location");
[self.locationManager startUpdatingLocation];
[self.locationManager stopUpdatingHeading];
break;

// if we are already receiving updates
case MTLocationStatusReceivingLocationUpdates:
//NSLog(@"Start updating location");
[self.locationManager startUpdatingLocation];
[self.locationManager stopUpdatingHeading];
break;

// if we are currently receiving heading updates, start updating heading
case MTLocationStatusReceivingHeadingUpdates:
//NSLog(@"start updating heading");
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
break;

}
// call delegate
[self.delegate locateMeButton:self didChangeLocationStatus:newLocationStatus];
}

// sets a view to a smaller frame, used for animation
Expand Down
Loading

0 comments on commit 092bde3

Please sign in to comment.