-1

Im trying to get the current user location on the map view and have it be zoomed in on. This my code-

 #import "WhereamiAppDelegate.h"
 #import "WhereamiViewController.h"


  @implementation WhereamiAppDelegate

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[WhereamiViewController alloc] initWithNibName:@"WhereamiViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}

@interface WhereamiViewController : UIViewController<CLLocationManagerDelegate,MKMapViewDelegate,UITextFieldDelegate>
 {

//@public RootObject *rootObj;
  CLLocationManager *locationManager;

 IBOutlet MKMapView *worldView;
 IBOutlet UIActivityIndicatorView *activityIndicator;
 IBOutlet UITextField *locationTitleField;
 }
-(IBAction)buttonDidGetPressed:(id)sender;
-(BOOL)textFieldShouldReturn:(UITextField *)textField;
-(void)findLocation;
-(void)foundLocation:(CLLocation *)loc;
@end

@implementation WhereamiViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
   NSLog(@"%@", NSStringFromSelector(_cmd));
   if (self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    // rootObj= [[RootObject alloc] init];//RootObject initialised
    // NSLog(@"RootObject–– %@",rootObj);
     locationManager= [[CLLocationManager alloc] init];

     [locationManager setDelegate:self];//self is Whereamicontroller. The delegate pointer is of type id<CLLocationManagerDelegate> and is an ivar of CLLocationManager.
     [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

 }
 return self;
}

-(void) viewDidLoad{
  NSLog(@"%@",NSStringFromSelector(_cmd));
  worldView.showsUserLocation=YES;
}

-(void)mapViewWillStartLocatingUser:(MKMapView *)mapView{
    NSLog(@"%@", NSStringFromSelector(_cmd));
 }
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
   NSLog(@"%@",NSStringFromSelector(_cmd));

   CLLocationCoordinate2D centerCoordinate= [userLocation coordinate]; //get the coordinate of current location.
   NSLog(@"%@ (%f, %f)",userLocation.location,centerCoordinate.latitude,centerCoordinate.longitude);
   MKCoordinateSpan span= MKCoordinateSpanMake(250, 250);//Structure members
   MKCoordinateRegion mapPortionToDisplay= MKCoordinateRegionMakeWithDistance(centerCoordinate, span.latitudeDelta, span.longitudeDelta);//span.latitudeDelta=250 and span.longitudeDelta=250

   [worldView setRegion:mapPortionToDisplay animated:YES];
//        [worldView setRegion:mapPortionToDisplay];

   [worldView regionThatFits:mapPortionToDisplay];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //CLLocationManagerDelegate method implementation
  NSLog(@"%@", NSStringFromSelector(_cmd));
//    NSTimeInterval t0=[[locations lastObject] timeIntervalSinceNow];
NSLog(@"current location–– %@",(CLLocation *)[locations lastObject]);  
 }

Following is the output-

2017-08-25 22:16:19.178 Whereami2[1601:758525] initWithNibName:bundle:

2017-08-25 22:16:19.294 Whereami2[1601:758525] viewDidLoad

2017-08-25 22:16:20.607 Whereami2[1601:758525] mapViewWillStartLocatingUser:

From the above lines, its clearly seen that mapView:didUpdateUserLocation: message did not get passed to map view's delegate at all. Same is the case with locationManager:didUpdateLocations:. The showsUserLocations property is supposed to send CLLocationManager's delegate, a viewcontroller (which is the same as MKMapView's delegate), this message also in its implementation. Is it not?

rahulbsb
  • 115
  • 12
  • can you show your locationManager declaration?, and how are you initializing your ViewController? – Reinier Melian Aug 25 '17 at 17:06
  • @interface WhereamiViewController : UIViewController { CLLocationManager *locationManager; IBOutlet MKMapView *worldView; IBOutlet UIActivityIndicatorView *activityIndicator; IBOutlet UITextField *locationTitleField; } This is my viewcontroller which conforms to both the protocols pertaining to this question – rahulbsb Aug 25 '17 at 17:11
  • add this line in your viewDidLoad NSLog(@"%@",locationManager) and let me know what prints – Reinier Melian Aug 25 '17 at 17:13
  • If your controller doesn't have a strong reference to the location manager it's probably nil – Frankie Aug 25 '17 at 17:14
  • @ Reinier Melian . The object is alive. The locationManager ivar is a strong reference pointer. – rahulbsb Aug 25 '17 at 17:20
  • @Frankie Isn't the delegate pointer supposed to be weak by default? Why should one care about locationManager, in the above code? – rahulbsb Aug 25 '17 at 17:29
  • The locationManager's reference to the delegate should be weak. The controllers reference to the locationManager should be strong. – Frankie Aug 25 '17 at 17:43
  • Try using @property (nonatomic, strong) in the interface to create the locationManger var – Frankie Aug 25 '17 at 17:45
  • @rahulbsb move this line [locationManager setDelegate:self];/ to your viewDidLoad method and let me know – Reinier Melian Aug 25 '17 at 17:47
  • @ Reinier Melian Moved the line inside viewDidLoad. No change – rahulbsb Aug 25 '17 at 18:05
  • @Frankie That is why I did not declare locationManager ivar as weak. – rahulbsb Aug 25 '17 at 18:09

1 Answers1

1

You've declared locationManager as an instance variable without synthesizing it's getters and setters. It's probably being deallocated. Just make it a property:

@interface WhereamiViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

As for the worldView, I don't see where you're setting something like worldView.delegate = self

Frankie
  • 11,508
  • 5
  • 53
  • 60
  • I had done this step earlier in the XIB file by control-dragging a connection from MKMapView to file's owner (Whereamiviewcontroller) and setting its delegate ivar to point to the same, there and then. – rahulbsb Aug 25 '17 at 18:54
  • I tried running on a test device also. No difference. What do I do with this? – rahulbsb Aug 25 '17 at 19:21
  • Hold on a sec.. I just NSLogged worldView.delegate in one of the view controller methods. It turned out to be NULL. But how is this possible? It have had the delegate pointer of MKMapView object pointed to Whereamiviewcontroller in the XIB file. – rahulbsb Aug 25 '17 at 19:53
  • 1
    Not sure, make sure your controller's `worldView` outlet is connected? – Frankie Aug 25 '17 at 20:00
  • I connected the worldView ivar to the MKMapView in the XIB file. Somehow the earlier connection between the two had disappeared, leaving behind an open dot symbol in the side gutter beside the variable in the interface file. I redid it. Rebuilt the project and ran it. Still no change. The worldView.delegate didn't return NULL on NSLogging this time though, since MKMapView object now had a strong pointer (worldView). – rahulbsb Aug 26 '17 at 15:36
  • Thanks man for your help. I figured out the reason. This was a 4 year old Xcode project that i was modernizing. There were some additions i needed to do in Info.plist file in order for it to work. I had to add a privacy (location) key in it and send requestWhenInUseAuthorization message to the locationManager after setting up the viewcontroller as the delegate. – rahulbsb Sep 02 '17 at 12:45