iOS8 when to alloc init CLLocationManager to call requestWhenInUseAuthorization? - objective-c

When i try to alloc init my CLLocationManager inside the getter of it i do not get the pop up request for location autorization. But when i put inside of my viewDidLoad it does work.
My code is looking like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init]; //when i put this here it works
self.locationManager.delegate = self;
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if(![CLLocationManager authorizationStatus])
{
[self.locationManager requestWhenInUseAuthorization];
}
self.mapView.showsUserLocation = YES;
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
}
But when i do the alloc init like this it does not work:
-(CLLocationManager *)locationManager
{
if(_locationManager) _locationManager = [[CLLocationManager alloc]init];
return _locationManager;
}
Can anyone explain to me why that is?

Because you have a logical error in your accessor method:
- (CLLocationManager *)locationManager
{
if(_locationManager == nil) _locationManager = [[CLLocationManager alloc] init];
return _locationManager;
}

Related

how to get the new latitudes and longitudes while moving Using Xcode

I am developing an App that records the latitude and longitudes for every 10mts and save them in server , so far I am able to get the current location of the person but the values are not changing, I used timers too
below is my code
// FamilyTrackerViewController.m
// FamilyTracker
//
// Created by Osmosys on 03/02/15.
// Copyright (c) 2015 Osmosys. All rights reserved.
//
#import "FamilyTrackerViewController.h"
#interface FamilyTrackerViewController ()
#end
#implementation FamilyTrackerViewController
#synthesize CLController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)viewDidAppear:(BOOL)animated:(BOOL)animated
{
CLController = [[OSMGPSLocationTrackingDelegate alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
_txtMobileNumber.delegate=self;
double score = xxxxxxxx429;
// NSString *str=#"xxxxxx429";
//[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithString:str] forKey:#"HIGHSCORE"];
// str=[[[NSUserDefaults standardUserDefaults] objectForKey:#"HIGHSCORE"] stringValue];
// score = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HIGHSCORE"] doubleValue];
_txtMobileNumber.text= #"XXXXXX429";
#pragma mark NextPrevios Methods
UIToolbar *objToolbar=[[UIToolbar alloc]init];
// objToolbar.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
// [objToolbar setBackgroundImage:[UIImage imageNamed:#"navigations_iPhone.png"] forToolbarPosition:UIToolbarPositionBottom barMetrics:UIBarMetricsDefault];
// [objToolbar insertSubview:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"navigations_iPhone.png"]] atIndex:0];
// objToolbar.barStyle = UIBarStyleBlack;
UIBarButtonItem *objBarbtndone=[[UIBarButtonItem alloc]init];
// objBarbtndone.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
objBarbtndone.style=UIBarButtonItemStyleBordered;
objBarbtndone.title=#"Done";
objBarbtndone.target=self;
objBarbtndone.action=#selector(btnBarDone);
UIBarButtonItem *objBarbtnPre=[[UIBarButtonItem alloc]init];
objBarbtnPre.title=#"Previous";
// objBarbtnPre.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
objBarbtnPre.style=UIBarButtonItemStyleBordered;
objBarbtnPre.target=self;
objBarbtnPre.action=#selector(btnBarPre);
UIBarButtonItem *objBarbtnNext=[[UIBarButtonItem alloc]init];
// objBarbtnNext.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
objBarbtnNext.style=UIBarButtonItemStyleBordered;
objToolbar.frame=CGRectMake(0, 0, 320, 44);
objBarbtnNext.title=#"Next";
objBarbtnNext.target=self;
objBarbtnNext.action=#selector(btnBtnNxt);
if([[UIDevice currentDevice].systemVersion floatValue]<7.0)
{
objBarbtnNext.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
objBarbtnPre.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
objBarbtndone.tintColor = [UIColor colorWithRed:136.0/255.0 green:6.0/255.0 blue:1.0/255.0 alpha:1.0];
}
UIBarButtonItem *objBarbtnSpace= [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
objToolbar.items=[NSArray arrayWithObjects:objBarbtnPre,objBarbtnNext,objBarbtnSpace,objBarbtndone, nil];
_txtMobileNumber.inputAccessoryView=objToolbar;
//CLController = [[OSMGPSLocationTrackingDelegate alloc] init];
//CLController.delegate = self;
//[CLController.locMgr startUpdatingLocation];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:2.0];
[locationManager startUpdatingLocation];
[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(useLocation) userInfo:nil repeats:YES];
}
-(void)useLocation{
NSLog(#"%#",[locationManager location]);
//CLController = [[OSMGPSLocationTrackingDelegate alloc] init];
// CLController.delegate = self;
// [CLController.locMgr startUpdatingLocation];
locationManager1 = [[CLLocationManager alloc] init];
[locationManager1 setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager1 setDelegate:self];
[locationManager1 setDistanceFilter:2.0];
[locationManager1 startUpdatingLocation];
_lbllogitudes.text= [NSString localizedStringWithFormat:#"%.18f",locationManager1.location.coordinate.longitude];
_lblLatitudes.text= [NSString localizedStringWithFormat:#"%.18f",locationManager1.location.coordinate.latitude];
[locationManager1 stopUpdatingLocation];
}
-(void)btnBarDone
{
[_txtMobileNumber resignFirstResponder];
}
//Loading the GPS location data to the apps loclable string
-(void)locationUpdate:(CLLocation *)location
{
locLabel= [location description];
_lbllogitudes.text= [NSString localizedStringWithFormat:#"%.15f",location.coordinate.longitude];
_lblLatitudes.text= [NSString localizedStringWithFormat:#"%.15f",location.coordinate.latitude];
// _lbllogitudes.text= [NSString localizedStringWithFormat:#"%f",location.coordinate.longitude];
// _lblLatitudes.text= [NSString localizedStringWithFormat:#"%f",location.coordinate.latitude];
}
//If any error occurs.
- (void)locationError:(NSError *)error {
locLabel = [error description];
//[self.GPSOutput setText:locLabel];
}
//Closing the GPS device and service.
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//Stoping the GPS data
[CLController.locMgr stopUpdatingLocation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
you should use the CLLocationManager's delegate:
locationManager:didUpdateLocations:
you will get an array of CLLocation, just extract your current coordinate from its last object.
You don't need timer, the delegate will automatically send location updates to you.

infowindow not displaying with marker in didTapAtCoordinate method

i am trying to show infowindow and marker both simultaneously.
code
-(void)set_markerOnMap:(double)lat longitude:(double)lon{
GMSMarker *marker = [[GMSMarker alloc] init];
marker.title = #"Location selected";
marker.position = CLLocationCoordinate2DMake(lat, lon);
marker.snippet = #"Testing";
marker.icon=[UIImage imageNamed:#"red-pin.png"];
marker.map = self.MyMapView;
[self.MyMapView setSelectedMarker:marker];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self set_markerOnMap:21.214894 longitude:72.88087];
self.MyMapView.delegate=self;
}
above code is working fine and its showing both infowindow and marker together.
but my problem is when i called set_markerOnMap method from didTapAtCoordinate instead of viewDidLoad it does not work and only marker is shown.
code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.MyMapView.delegate=self;
}
- (void) mapView: (GMSMapView *) mapView
didTapAtCoordinate: (CLLocationCoordinate2D) coordinate{
[self set_markerOnMap:21.214894 longitude:72.88087];
}
anyone can help me where i am wrong?
See if this works...
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self set_markerOnMap:21.214894 longitude:72.88087];
}];
So the short term answer, as hinted by i2Fluffy, is the following:
#implementation ViewController {
GMSMarker *tapMarker;
}
- (void)viewDidLoad {
[super viewDidLoad];
GMSMapView *mapView = (GMSMapView*)self.view;
mapView.delegate = self;
CLLocationCoordinate2D sydney = CLLocationCoordinate2DMake(-33.868, 151.2086);
mapView.camera = [GMSCameraPosition cameraWithTarget:sydney zoom:8];
tapMarker = [GMSMarker markerWithPosition:sydney];
tapMarker.title = #"Tap Marker";
tapMarker.map = (GMSMapView*)self.view;
}
-(void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
NSLog(#"Tap at (%g,%g)", coordinate.latitude, coordinate.longitude);
tapMarker.position = coordinate;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[((GMSMapView*)self.view) setSelectedMarker:tapMarker];
}];
}
#end
The longer term answer is that this is a bug (gmaps-api-issues/7222) and I'll work with engineering to get this fixed.
Thanks for the report! =)

Can I initiate an ivar indirectly?

I'm trying to initiate my ivar like this:
Declared like this in h-file
#interface MyClass: {
UITextView *_myTextView;
}
then created like this in the m-file
- (id)init {
self = [super init];
if(self) {
[self initTextView:_myTextView];
}
return self;
}
- (void)initTextView:(UITextView *)textView {
textView = [[UITextView alloc] init];
...
}
_myTextView will still be nil afterwards. Why is that and what should I do it to make it work? I've got ARC enabled.
[EDIT]
This works. Thanks all!
- (id)init {
self = [super init];
if (self) {
_textView1 = [self createTextView];
_textView2 = [self createTextView];
_textView3 = [self createTextView];
}
return self;
}
- (UITextView *)createTextView {
UITextView *textView = [[UITextView alloc] init];
...
return textView;
}
You need to always refer to instance variables using:
self.textView = [[UITextView alloc] init];
Also use a name other than initTextView as methods starting with init have special meaning in Objective-C.
If you want to use the same code to initialize multiple text view controls, then use code like this:
- (UITextView *)createTextView
{
UITextView *textView = [[UITextView alloc] init];
textView.something = whatever;
...
return textView;
}
And then use it like this:
- (id)init {
self = [super init];
if(self)
{
self.textView1 = [self createTextView];
self.textView2 = [self createTextView];
...
self.textViewN = [self createTextView];
}
}
In [self initTextView:_myTextView]; you pass the current value of _myTextView (which is nil) to your initTextView: method. To set the instance variable, you need a pointer to a pointer.
- (id)init {
self = [super init];
if (self) {
[self setupTextView:&_myTextView];
}
return self;
}
- (void)setupTextView:(UITextView * __strong *)textView {
*textView = [[UITextView alloc] init];
...
}
I also renamed the initTextView: method to setupTextView, as methods starting with init are expected to behave like other init methods in ARC.
- (id)init {
self = [super init];
if(self) {
[self initTextView];
}
}
- (void)initTextView{
_myTextView = [[UITextView alloc] init];
...
}
if you want to call initTextView for several text views , you can code like this :
- (id)init {
self = [super init];
if(self) {
_myTextView = [[UITextView alloc] init];
[self initTextView:_myTextView];
}
}
- (void)initTextView:(UITextView *)textView{
//setup the textView
...
}

popViewControllerAnimated affects viewwillappear?

I have two classes. lets say A,B Classes. from A class pushviewController is called, then B class will appear. Then here is the problem .when i call popviewcontrolleranimated method from B class it is going back to A, but then both class`s viewwillappear method is being called. so anyone can tell me what is going on in here. i am stuck!.
Below is the A class.
#implementation ShakeViewController
- (id) init {
if (self = [super init]) {
movieName = #"04";
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
[self.view setBackgroundColor:[UIColor whiteColor]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"shake_it.png"]];
[self.view addSubview:imageView];
[imageView release];
nextController = [[OtsugeViewController alloc] init];
}
return self;
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
const float violence = 1.2;
static BOOL beenhere;
BOOL shake = FALSE;
if (beenhere) return;
beenhere = TRUE;
if (acceleration.x > violence || acceleration.x < (-1* violence))
shake = TRUE;
if (acceleration.y > violence || acceleration.y < (-1* violence))
shake = TRUE;
if (acceleration.z > violence || acceleration.z < (-1* violence))
shake = TRUE;
if (shake && mPlayerPushed) {
[self playSound:#"suzu"];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"noVib"] == NO) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
[[UIAccelerometer sharedAccelerometer] setDelegate:nil];
[self presentModalViewController:mMoviePlayer animated:YES];
[self play];
mPlayerPushed = YES;
}
beenhere = false;
}
- (void)toNext {
NSLog(#"ShakeViewController:toNext");
[self.navigationController pushViewController:nextController animated:NO];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(#"Shake:viewWillAppear");
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:0.5];
}
- (void)dealloc {
[super dealloc];
}
#end
here is B class
#implementation OtsugeViewController
- (id) init {
if (self = [super init]) {
movieName = #"03";
self.view = [[[OtsugeView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
}
return self;
}
- (void) toNext {
NSLog(#"OtsugeViewController:toNext");
[self.navigationController popViewControllerAnimated:NO];
}
- (void) toToppage
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
[self.navigationController popToRootViewControllerAnimated:NO];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Screen touch Otsuge View");
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil
otherButtonTitles:#"Retry", #"Main Menu", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
actionSheet.cancelButtonIndex = 0;
[actionSheet showInView:self.view];
[actionSheet release];
}
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex: (NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0: // Retry
[self presentModalViewController:mMoviePlayer animated:YES];
[self play];
break;
case 1: // Main Menu
[self toToppage];
break;
case 2: // Cancel
break;
default:
break;
}
}
- (void) viewWillAppear:(BOOL)animated {
mMoviePlayer.moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
[self playSound:#"taiko_1"];
NSLog(#"Otsuge:viewWillAppear");
[(OtsugeView *)self.view renewImageView];
[super viewWillAppear:animated];
}
- (void) viewDidAppear:(BOOL)animated{
NSLog(#"Otsuge:viewDidAppear");
[super viewDidAppear:animated];
}
- (void) dealloc {
[super dealloc];
}
#end
It's normal. View will appear is called each time a view will appear. If you want to call a method only when the view appears for the first time use -viewdidload because in a view controller each view that is in the stack is kept in memory but those you pop get deallocated.

How to check if geolocation is enabled on iPhone?

How to check if localization is enable on iPhone?
I need to check if geolocation is enable in viewDidLoad method.
This is my viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
// 1. Check connection
[self performSelector:#selector(checkConnection)];
// 2. Loader (activity indicator) ...
progressViewController = [[ProgressViewController alloc] initWithNibName:#"ProgressViewController" bundle:nil];
[self.view addSubview:progressViewController.view];
// 3. Active geolocation
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[self startGps];
// 4. Data tableView
NSMutableArray *arrEvents = [[NSMutableArray alloc] init];
[[ListaEventiSingleton sharedListaEventi] setArrEvents:arrEvents];
[arrEvents release];
// 5. remove loader (activity indicator)
[progressViewController.view removeFromSuperview];
}
//delegate localization
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if (newLocation.horizontalAccuracy < 0) {
locality = #"Non riesco a localizzarti..\n Refresha!";
}
else {
CLLocationCoordinate2D here = newLocation.coordinate;
latitudine = [NSString stringWithFormat:#"%f", here.latitude];
longitudine = [NSString stringWithFormat:#"%f", here.longitude];
[self getAddressFromGmaps];
[self stopGps];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(stopUpdatingLocalizzazione) object:nil];
}
labelLocality.text = locality;
// 4. Load data for the table view
[self performSelectorOnMainThread:#selector(loadEvents) withObject:nil waitUntilDone:YES];
[tableViewEvents reloadData];
// 5. remove activity indicator
[progressViewController.view removeFromSuperview];
}
I think you want [CLLocationManager locationServicesEnabled].