I am developing an compass application for iphone 3GS. I have used CoreLocation framework for
the compass method I have used...
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
...method for getting the heading.
My question is how to get a value like "315° NW, 90° E,140° SE" without moving the iphone.
I do not have 3GS iphone so, if anybody has some ideas, please help.
Thank you.
I use this snippet just before the #implementation of the class where I need my fake heading and location data.
#if (TARGET_IPHONE_SIMULATOR)
#interface MyHeading : CLHeading
-(CLLocationDirection) magneticHeading;
-(CLLocationDirection) trueHeading;
#end
#implementation MyHeading
-(CLLocationDirection) magneticHeading { return 90; }
-(CLLocationDirection) trueHeading { return 91; }
#end
#implementation CLLocationManager (TemporaryLocationFix)
- (void)locationFix {
CLLocation *location = [[CLLocation alloc] initWithLatitude:55.932 longitude:12.321];
[[self delegate] locationManager:self didUpdateToLocation:location fromLocation:nil];
id heading = [[MyHeading alloc] init];
[[self delegate] locationManager:self didUpdateHeading: heading];
}
-(void)startUpdatingHeading {
[self performSelector:#selector(locationFix) withObject:nil afterDelay:0.1];
}
- (void)startUpdatingLocation {
[self performSelector:#selector(locationFix) withObject:nil afterDelay:0.1];
}
#end
#endif
Related
I was really hesitant to post a fourth question on this subject, but triple-checked everything according to previous answers and still get bad results.
Problem: CLLocationManager does not call didEnterRegion in iOS6.
Setup: iOS6.
Here is the code with all the functions relevant to CLLocationManager
myMapViewController.h
#interface FirstViewController : UIViewController <UIApplicationDelegate,CLLocationManagerDelegate, MKMapViewDelegate, UISearchBarDelegate,RKObjectLoaderDelegate >
{
/* variables */
}
#property (strong, nonatomic) CLLocationManager *locationManager;
myMapViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
/* other initialization code */
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter: kCLLocationAccuracyBest];
[locationManager setDesiredAccuracy: kCLLocationAccuracyBest];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
/* other application code */
Step* step = [_steps lastObject];
CLRegion *tmpReg = [[CLRegion alloc] initCircularRegionWithCenter:step.start_location.coordinate radius:1000 identifier: [step.start_locationLat stringValue] ];
[locationManager startMonitoringForRegion:tmpReg];
NSLog(#"Setting region with latitude %f", tmpReg.center.latitude);
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region{
NSLog(#"Monitoring region with latitude %f", region.center.latitude);
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#"ENTERED REGION!");
}
}
- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(#"EXITED REGION!");
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
NSLog(#"Region monitoring failed with error: %#", [error localizedDescription]);
}
Application runs with zero warnings and here is the log:
2012-12-02 19:31:41.449 myApp[5695:c07] Setting region with latitude 37.785690
2012-12-02 19:31:41.506 myApp[5695:c07] Monitoring region with latitude 37.785690
Have you entered the region? You question doesn't actually say that you are moving your device in and out of the region you are monitoring, or simulating that movement via Xcode.
you did not forget to put [locationManager startUpdatingLocation]; ??
I want to get users current location. Here is my code
// In LoginViewController.h
#interface LoginViewController : UIViewController <UserLocationDelegate,UIAlertViewDelegate> {
CLLocation *usersLocation;
}
#property (nonatomic,strong) CLLocation *usersCurrentLocation;
#end
// In LoginViewController.m
#implementation LoginViewController
#synthesize usersCurrentLocation;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.usersCurrentLocation = nil;
[self currentLocationOfUser];
}
-(void)currentLocationOfUser {
UserLocation *userLocation = [[UserLocation alloc]init];//UserLocation];
userLocation.delegate = self;
[userLocation getCurrentLocationOfUser];
}
#pragma mark - User Location Delegate Methods
- (void)locationUpdate:(CLLocation *)location
{
self.usersCurrentLocation = location;
NSLog(#"Latitude:- %.6f",self.usersCurrentLocation.coordinate.latitude);
NSLog(#"Longitude:- %.6f",self.usersCurrentLocation.coordinate.longitude);
}
- (void)locationError:(NSString *)errorMsg
{
[Common showAlertWithTitle:#"Error" andMessage:errorMsg];
}
// In UserLocation.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol UserLocationDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSString *)errorMsg;
#end
#interface UserLocation : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
__weak id<UserLocationDelegate>delegate;
}
#property (nonatomic,strong) CLLocationManager *locationManager;
#property (nonatomic,weak) id<UserLocationDelegate>delegate;
-(id)initUserLocation;
-(void)getCurrentLocationOfUser;
#end
// In UserLocation.m
#import "UserLocation.h"
#implementation UserLocation
#synthesize locationManager;
#synthesize delegate;
#synthesize geoCodingDelegate;
-(id)initUserLocation
{
if (self == [super init]) {
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
}
return self;
}
-(void)getCurrentLocationOfUser {
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
if ([CLLocationManager locationServicesEnabled]) {
//[self.locationManager startMonitoringSignificantLocationChanges];
[self performSelector:#selector(startLocationUpdate) withObject:nil afterDelay:2.0];
}
else {
if ([delegate respondsToSelector:#selector(locationError:)]) {
[self.delegate locationError:#"Please Turn On Location Services in Settings To Retrive User's Current Location"];
}
else {
[Common showAlertWithTitle:#"Error" andMessage:#"Please Turn On Location Services in Settings To Retrive User's Current Location"];
}
}
}
-(void)startLocationUpdate
{
[self.locationManager startMonitoringSignificantLocationChanges];
}
#pragma mark CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if ([delegate respondsToSelector:#selector(locationUpdate:)]) {
[delegate locationUpdate:newLocation];
}
}
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
if ([delegate respondsToSelector:#selector(locationError:)]) {
[delegate locationError:#"Some Error Occured While Retriving Users's Location"];
}
else {
[Common showAlertWithTitle:#"Error" andMessage:#"Some Error Occured While Retriving Users's Location"];
}
}
#end
But it is not returning any location update.
Also its not asking user permission to use location. My app is not listed in Location Services. How can I add my app in Location Serverices ?
What's worong in above code ?
I solved this problem by declaring UserLocation *userLocation in .h & writing property.
Since I am using ARC , its deallocating userLocation so I am not getting location updates.
OK the code is now working, but it still needs work. The values I get are "sticky", they are not stable (the magnetic North seems to move a bit every time I try to return to it), and I need to shake the device a bit in order to refresh/wake-up the values..
Game.h
#import <Foundation/Foundation.h>
#import "CoreLocation.h"
#interface Game : NSObject
<CLLocationManagerDelegate>
#property BOOL stopButtonPressed;
-(void) play;
#end
Game.m
#implementation Game
- (id) init
{
self = [super init];
self.stopButtonPressed = NO;
CLLocationManager *locationManager;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
return self;
}
-(void) play
{
[locationManager startUpdatingHeading];
while(!self.stopButtonPressed)
{
double degrees = locationManager.heading.magneticHeading;
int degreesRounded = (int)degrees;
NSLog(#"Degrees : %i", degreesRounded);
}
}
#end
MyViewController.m
#interface MyViewController()
{
Game *game;
}
#end
#implementation MyViewController
-(void) viewDidLoad
{
game = [[Game alloc] init];
}
- (IBAction)playPressed:(UIButton *)sender
{
[game performSelectorInBackground:#selector(play) withObject:nil];
}
- (IBAction)stopPressed:(UIButton *)sender
{
game.stopButtonPressed = YES;
}
#end
What am I doing wrong?
This code will block the thread, and if it's happening in the main thread, you will never get the button press.
CLLocationManager is an asynchronous mechanism. To work with it properly, you must provide a delegate which it will notify when updates to location are available (this can be self in most cases (where self is a viewController or similar). See CLLocationManagerDelegate docs
...
CLLocationManager *locationManager;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingHeading];
}
- (void)locationManager:manager didUpdateHeading:newHeading {
double degrees = newHeading.magneticHeading;
NSLog(#"Degrees : %F", degrees);
}
You should catch the CLLocationManager delegate methods instead of calling the properties directly: https://developer.apple.com/library/mac/#documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html#//apple_ref/occ/intf/CLLocationManagerDelegate
I am using corelocation framework. is it possible to fake current location for use in social network applications ? if yes then how ?
Please help.
THank you in advance.
:: Edited ::
I made code for that after surfing some more, it may be change using overriding methods of class CLLocationManager.
code like some bellow :
#interface MyHeading : CLHeading
-(CLLocationDirection) newHeading;
-(CLLocationDirection) new1Heading;
#end
#implementation MyHeading
-(CLLocationDirection) newHeading { return 55; }
-(CLLocationDirection) new1Heading { return 56; }
#end
#implementation CLLocationManager (LF)
- (void)setFLocation {
CLLocation *location = [[CLLocation alloc] initWithLatitude:40.778023 longitude:-73.981935];
[[self delegate] locationManager:self didUpdateToLocation:location fromLocation:nil];
id heading = [[MyHeading alloc] init];
[[self delegate] locationManager:self didUpdateHeading: heading];
}
-(void)startUpdatingHeading {
[self performSelector:#selector(setFLocation) withObject:nil afterDelay:0.1];
}
- (void)startUpdatingLocation {
[self performSelector:#selector(setFLocation) withObject:nil afterDelay:0.1];
}
#end
Thank you all for sharing.
Thanks again.
Give the following framework a try.
I'm implementing a CLLocationManager right as described in several tutorials.
Everything works fine up to the point where the LocationManager receives a second update. Then a memory leak occurs.
Instruments tells me, that the leaked objects are NSCFTimer, GeneralBlock-16 and NSCFSet
Any ideas?
Thanks for any help
[Edit]
After repeatingly starting and stopping the locationManager, the updated seem to come faster. This makes me think that the CLLocationManager initializes a new timer every time a location-update occurs... VERY strange...
And - so you don't need to read my comment - the app crashes after a while
[Edit]
Ok - I don't get it here's some code...
I'm using a separate class for the locationManager, as described here: http://www.vellios.com/2010/08/16/core-location-gps-tutorial/
locationManager.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol locationManagerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface locationManager : NSObject <CLLocationManagerDelegate>{
CLLocationManager *myLocationManager;
id delegate;
CLLocation *bestEffortAtLocation;
BOOL outOfRange;
}
#property (nonatomic, retain) CLLocationManager *myLocationManager;
#property (nonatomic, retain) CLLocation *bestEffortAtLocation;
#property (nonatomic, assign) id delegate;
#property (nonatomic, assign) BOOL outOfRange;
#end
locationManager.m
#import "locationManager.h"
#implementation locationManager
#synthesize myLocationManager;
#synthesize delegate;
#synthesize bestEffortAtLocation;
#synthesize outOfRange;
- (id) init {
self = [super init];
NSLog(#"initializing CLLocationManager");
if (self != nil) {
outOfRange = NO;
self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
self.myLocationManager.delegate = self;
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[self performSelector:#selector(stopUpdatingLocation:) withObject:#"Timed Out" afterDelay:100.0];
}else{
NSLog(#"Location Manager could not be initialized");
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if(outOfRange == NO){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(stopUpdatingLocation:) object:nil];
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
[self.delegate locationUpdate:newLocation];
}else{
[self.myLocationManager stopUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"error!!!!");
[self.myLocationManager stopUpdatingLocation];
[self.delegate locationError:error];
}
- (void)dealloc {
[myLocationManager release];
[bestEffortAtLocation release];
[super dealloc];
}
#end
then, in the main-class I call:
mainFile.h (exerpt)
#import "locationManager.h"
#interface mainFile : UIViewController <locationManagerDelegate , UIAlertViewDelegate>{
locationManager *locationController;
CLLocation *myLocation;
}
#end
mainFile.m (exerpt)
#import "locationManager.h"
#implementation mainFile
#synthesize locationController;
#synthesize myLocation;
- (void)locationError:(NSError *)error{
// Do alert-Stuff
}
- (void)locationUpdate:(CLLocation *)location {
// Do location-Stuff
}
- (void)viewDidLoad
{
[super viewDidLoad];
locationController = [[[locationManager alloc] init] autorelease];
locationController.delegate = self;
[locationController.myLocationManager startUpdatingLocation];
}
- (void)dealloc {
self.locationController = nil;
[locationController release];
}
#end
It's driving me kinda crazy :)
My advice is to not be obsessed with one-time memory leaks that the iOS itself generates. It does this in many places and the leaks are all pretty harmless.
Ah, a long dead problem, I love them.
locationController is an iVar, not a property, so when you create it in viewDidLoad, assigning it to _locationController doesn't take on ownership.
You've autoreleased the object, so next time around the event loop, the auto-release pool is drained and it is released.
You could fix it by making it a retain property ( which would fit with your locationManager = nil ), or getting rid of the auto-release, and using an explicit [locationManager release] in dealloc.
Try doing a Build and Analyze. I usually find memory leaks and other non-syntax errors that way.