Search code examples
iosobjective-cwebviewcllocationmanagerviewwillappear

How to get location at AppDelegate, and pass the lat and long to another VC and load webview


Edited

I have managed to get a current location by using this. After that I am trying to pass lat and long as a string to another method that loads a webview. A problem is every time I load this VC, it doesn't call a following method

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 

and straight away jump to the following method.

-(void)viewWillAppear:(BOOL)animated

How do I get a location first and store it an variables, pass them to another method as a string, append a string and pass it to NSURL and load a webview?

Is a lat and long retained? How do I retain it throughout my project?

What happens when I click on other tab controller and click back on this VC. Does a lat and long be refreshed again?

- (void)viewDidLoad
{
    [super viewDidLoad];

    geocoder = [[CLGeocoder alloc] init];
    if (locationManager == nil)
    {
        locationManager = [[CLLocationManager alloc] init];
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
        locationManager.delegate = self;
        [locationManager requestAlwaysAuthorization];
    }

    [locationManager startUpdatingLocation];

    dtDate = [[NSMutableArray alloc] init];
    self.currentPageIndex = 0;
    self.hasAppearedFlag = NO;

}

//=== It doesn't call a following method first. 
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

    CLLocation *newLocation = [locations lastObject];

    [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {

        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            latitude = [NSString stringWithFormat:@"%f",newLocation.coordinate.latitude];
            longitude = [NSString stringWithFormat:@"%f",newLocation.coordinate.longitude];
            state = placemark.administrativeArea;
            country = placemark.country;

            NSLog(@"This is the latitude%@", latitude);
            NSLog(@"This is the longitude%@", longitude);

        } else {
            NSLog(@"This is the error debug%@", error.debugDescription);
        }
    }];

    // Turn off the location manager to save power.
    [manager stopUpdatingLocation];

        //*** It will start loading this part below
        [self setupSegmentButtons];
        NSDate *now = [NSDate date];
        NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"dd/MM/YYYY"];
        NSString *dateString = [dateFormatter stringFromDate:now];

        [self LoadClasses:dateString];
        self.hasAppearedFlag = YES;
}

- (void)locationManager:(CLLocationManager *)manager
   didFailWithError:(NSError *)error
{
    NSLog(@"Cannot find the location.");
}

//=== Load webview

- (void)LoadClasses : (NSString *)sDate{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    sMemCode = [defaults objectForKey:@"txtMemCode"];

    NSLog(@"Load Class This is the memCode:%@", sMemCode);
    NSLog(@"Load Class This is the latitude:%@", latitude);
    NSLog(@"Load Class This is the longitude:%@", longitude);

    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    sURL = appDelegate.gURL;
    sURL = [sURL stringByAppendingString:@"/apps/class.asp?"];
    sURL = [sURL stringByAppendingString:@"memCode="];
    sURL = [sURL stringByAppendingString:sMemCode];
    sURL = [sURL stringByAppendingString:@"&dtpClass="];
    sURL = [sURL stringByAppendingString:sDate];
    sURL = [sURL stringByAppendingString:@"&lat="];
    sURL = [sURL stringByAppendingString:latitude];
    sURL = [sURL stringByAppendingString:@"&long="];
    sURL = [sURL stringByAppendingString:longitude];

    NSLog(@" The sURL to load for the current page : %@ ", sURL);

    NSURL *url = [NSURL URLWithString:sURL];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [webView loadRequest:urlRequest];
    [webView setDelegate:(id<UIWebViewDelegate>)self];

}

Solution

 I have put the `Location Delegates` to `AppDelegates` 

AppDelegates.h

 #import <UIKit/UIKit.h>
 #import<CoreLocation/CoreLocation.h>

 @interface AppDelegate : UIResponder <UIApplicationDelegate>{
CLLocationManager *locationManager;

}

@property (nonatomic, strong) NSString *slatitude;
@property (nonatomic, strong) NSString *slongitude;

@end

AppDelegates.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//--- Get current location ---
if (locationManager == nil)
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    locationManager.delegate = self;

    //-- Pop up authrorization to use current location ---
    [locationManager requestAlwaysAuthorization];
}

[locationManager startUpdatingLocation];
}

- (void)locationManager: (CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation: (CLLocation *)oldLocation
{

float latitude = newLocation.coordinate.latitude;
slatitude = [NSString stringWithFormat:@"%f",latitude];
float longitude = newLocation.coordinate.longitude;
slongitude = [NSString stringWithFormat:@"%f", longitude];

NSLog(@"App:This is the latitude%@", slatitude);
NSLog(@"App:This is the longitude%@", slongitude);

}

- (void)locationManager:(CLLocationManager *)manager
   didFailWithError:(NSError *)error
{
    NSLog(@"Cannot find the location.");
}

In any VC,


 appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

latitude = appDelegate.slatitude;
longitude = appDelegate.slongitude;

Solution

  • I would suggest you move your code of Location Delegates to your Appdelegate File, so that it registers and keeps updating to the location delegate methods,

    You can either make two property variabled from your appdelegate file and keep updating them as the delegate is called or make a getter or setter method something like this:

    @interface AppDelegate : UIResponder<UILocationDelegate>{
     CLLocationManager * locationManager;
    }
    @property (nonatomic, strong) NSString *lattitude;
    @property (nonatomic, strong) NSString *longitude;
    
    @end
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
     if (locationManager == nil)
        {
            locationManager = [[CLLocationManager alloc] init];
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
            locationManager.delegate = self;
            [locationManager requestAlwaysAuthorization];
        }
    
        [locationManager startUpdatingLocation];
    }
    

    and then Implement the location delegate method here itself as

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
          if (error == nil && [placemarks count] > 0) {
                placemark = [placemarks lastObject];
                self.latitude = [NSString stringWithFormat:@"%f",newLocation.coordinate.latitude];
                self.longitude = [NSString stringWithFormat:@"%f",newLocation.coordinate.longitude];
                state = placemark.administrativeArea;
                country = placemark.country;
    
                NSLog(@"This is the latitude%@", latitude);
                NSLog(@"This is the longitude%@", longitude);
    
            }
    
    }
    
    - (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error
    {
        NSLog(@"Cannot find the location.");
    }
    

    Late you can access this from your ViewController as

    - (void)viewDidAppear:(BOOL)animated {
    AppDelegate* appdelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    
    NSString *lat = appdelegate.lattitude;
    NSString *long = appdelegate.longitude;
    
    }
    

    In this manner even if you switch tab bars or change controllers, you will still have the latest locations.