in my app i'm finding the beacons & want to calculate the Distance,here two days i struck with one problem that is in CCLocationManager delegate function returns empty beacons array.i tried the CBCentralManagerDelegate functions i get the list of beacons.in the didRangeBeacons method gives empty array help me. below is my code i tried
Code:
#interface ViewController ()<CBCentralManagerDelegate,CLLocationManagerDelegate>
{
NSMutableData *dat;
CLBeaconRegion *clBeconRegion;
CLLocationManager *locManager;
}
#property (strong,nonatomic) CBCentralManager *cbcManager;
- (IBAction)scanBtn:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
self.cbcManager=[[CBCentralManager alloc] initWithDelegate:self queue:nil];
locManager=[[CLLocationManager alloc] init];
locManager.delegate=self;
[self initRegion];
clBeconRegion.notifyEntryStateOnDisplay=YES;
[locManager requestAlwaysAuthorization];
[self locationManager:locManager didStartMonitoringForRegion:clBeconRegion];
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"List of peripheral %#",peripheral);
NSLog(#"List of advertisementData %# %#",advertisementData,RSSI);
}
-(void)initRegion{
NSUUID *uuid=[[NSUUID alloc]initWithUUIDString:#"XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"];
clBeconRegion=[[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:#"BluetoothExample"];
clBeconRegion.notifyEntryStateOnDisplay=YES;
clBeconRegion.notifyOnEntry=YES;
clBeconRegion.notifyOnExit=YES;
[locManager startMonitoringForRegion:clBeconRegion];
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(#"didConnectPeripheral");
[peripheral discoverServices:nil];
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region{
[locManager startRangingBeaconsInRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#"Entered Region");
[locManager startRangingBeaconsInRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(#"Exit Region");
[locManager stopRangingBeaconsInRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
NSLog(#"beacons %# last %#",beacons,[region proximityUUID]);
CLBeacon *beacon=[[CLBeacon alloc]init];
beacon=[beacons lastObject];
NSLog(#"min %# maj %#",beacon.minor,beacon.major);
}
- (IBAction)scanBtn:(id)sender
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.cbcManager scanForPeripheralsWithServices:nil options:options];
NSLog(#"scan clicked");
}
i'd fixed the NSLocationAlwaysUsageDescription info.plist.
i have a real beacon & ipad mini device.
this code is given in all beacon finding examples.help me what i did a mistake here.
A few points:
If you are not getting ranging callbacks, the ProximityUUID may be incorrect. Use an off the shelf beacon detector like Locate and verify you can detect the beacon and the ProximityUUID is what the CLBeaconRegion is set up to detect.
Verify you have obtained location permissions properly by going to Settings -> (your app name), and verifying Location is set to "always"
There is no need to use CoreBluetooth when detecting iBeacons. You should remove all lines with classes that have the CB prefix. While this code will give you a list of iBeacon Bluetooth devices nearby, it will not let you read the beacon identifiers. You must use CoreLocation to do that.
This method call is made by the CoreLocation framework, and should not be called manually. It should be removed:
[self locationManager:locManagerdidStartMonitoringForRegion:clBeconRegion];
Related
Hi everyone in my app i'm finding the iBeacons here the didExitRegion Method i called when i exit from the Region but the didEnterRegion method is not called when i entering the region.i fixed the background Refresh,remote notifications,location request always in info.plist
here is my code
- (void)viewDidLoad
{
[super viewDidLoad];
locManager=[[CLLocationManager alloc] init];
locManager.delegate=self;
[self initRegion];
if([locManager respondsToSelector:#selector(requestAlwaysAuthorization)])
{
[locManager requestAlwaysAuthorization];
}
// clBeconRegion.notifyOnEntry=YES;
clBeconRegion.notifyEntryStateOnDisplay=YES;
}
-(void)initRegion
{
NSUUID *uuid=[[NSUUID alloc]initWithUUIDString:UUID];
clBeconRegion=[[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:#"BeaconExample"];
// clBeconRegion=[[CLBeaconRegion alloc]initWithProximityUUID:uuid major:8983 minor:738
// identifier:#"aB"];
// clBeconRegion=[[CLBeaconRegion alloc]initWithProximityUUID:uuid major:8983 minor:728
// identifier:#"bB"];
clBeconRegion.notifyOnEntry=YES;
// clBeconRegion.notifyOnExit=YES;
clBeconRegion.notifyEntryStateOnDisplay=YES;
[locManager startMonitoringForRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region{
NSLog(#"didStartMonitoringFor Region");
// [locManager startRangingBeaconsInRegion:clBeconRegion];
[locManager requestStateForRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
switch (state) {
case CLRegionStateInside:
[locManager startRangingBeaconsInRegion:clBeconRegion];
NSLog(#"Region Inside");
break;
case CLRegionStateOutside:
// [locManager stopRangingBeaconsInRegion:clBeconRegion];
NSLog(#"Region OutSide %ld",(long)state);
case CLRegionStateUnknown:
default:
// stop ranging beacons, etc
NSLog(#"Region unknown %ld",(long)state);
}
}
-(void)locationManage:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#"Entered Region");
[locManager startRangingBeaconsInRegion:clBeconRegion];
CLBeaconRegion *reg=(CLBeaconRegion *)region;
[disObj login:[NSString stringWithFormat:#"%#", reg.major] :[NSString stringWithFormat:#"%#", reg.minor]];
NSString *enterRegion=[NSString stringWithFormat:#"You ENTERED a Region %#",reg.minor];
[self sendLocalNotificationWithMessage1:enterRegion];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
CLBeaconRegion *reg=(CLBeaconRegion *)region;
NSString *exit=[NSString stringWithFormat:#"You Exit a Region %#",reg.minor];
[self sendLocalNotificationWithMessage1:exit];
NSLog(#"Exit Region");
[locManager stopRangingBeaconsInRegion:clBeconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{}
Check didEnterRegion signature: you wrote locationManage not locationManager
I am using below code to get current lat long in iOS 8.
.h
#interface DirectionViewController : UIViewController<CLLocationManagerDelegate,GMSMapViewDelegate>
{
CLLocationManager *locationManager;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
.m
#synthesize locationManager;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
// Configure the new event with information from the location
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
NSLog(#"dLatitude : %#", latitude);
NSLog(#"dLongitude : %#",longitude);
But here, I am getting 0.00000 value for both latitude and longitude.
Can anybody help me here. How to get current lat long in iOS 8?
Thanks in advance!
AppDelegte.h
#interface AppDelegate : UIResponder <UIApplicationDelegate,CLLocationManagerDelegate>
{
CLLocation *currentLocation;
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (nonatomic, assign) CLLocationCoordinate2D currentLocationCoordinate;
Appdelget.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
locationManager = [[CLLocationManager alloc]init]; // initializing locationManager
locationManager.delegate = self; // we set the delegate of locationManager to self.
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // setting the accuracy
[locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CurrentLatitude=newLocation.coordinate.latitude;
CurrentLongitude=newLocation.coordinate.longitude;
NSLog(#"%f",CurrentLatitude);
NSLog(#"%f",CurrentLongitude);
[locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
.Plsit add
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
You're not using the proper method to get your coordinates.
once you call startUpdatingLocation, it calls the location manager methods (that you must implement in order for this to work).
There are two of them, [locationManager:didFailWithError:][1]
and [-locationManager:didUpdateLocations:][2]. You should have warnings asking you to add those methods in your .m, with the proper spelling if you haven't done it yet.
didUpdateLocation is called every X seconds and returns coordinates. You have to build your coordinate strings in this very specific method, where the coordinates are set.
From what I could gather,
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
Will give you an array of CLLocation objects containing the location data.
This array always contains at least one object representing the current location.
If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries.
The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.
This means you'll have to get the lastObject of that array for the most recent location.
Here is an example i've found on the web, for what the inside of that method could look. :
CLLocation *newLocation = [locations lastObject];
CLLocation *oldLocation;
if (locations.count > 1) {
oldLocation = [locations objectAtIndex:locations.count-2];
} else {
oldLocation = nil;
}
NSLog(#"didUpdateToLocation %# from %#", newLocation, oldLocation);
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0);
[regionsMapView setRegion:userLocation animated:YES];
Make sure to ask for the different permissions beforehand, and that you have them.
Also note that this method is only available since iOS5 and is different in the previous versions. Though it is very unlikely that you still support iOS5, I thought I should mention it.
I am trying to get the Location "Latitude & Longitude".
The steps which I did as follow:
In CurrentLocationViewController.m:
#implementation CurrentLocationViewController {
CLLocationManager *locationManager;
}
Then in CurrentLocationViewController.h
#import <CoreLocation/CoreLocation.h>
#interface CurrentLocationViewController : UIViewController <CLLocationManagerDelegate>
Back to In CurrentLocationViewController.m:
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
locationManager = [[CLLocationManager alloc] init];
}
return self;
}
- (IBAction)getLocation:(id)sender {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation !=nil) {
self.longitudeLabel.text = [NSString stringWithFormat:#"%0.8f", currentLocation.coordinate.longitude];
self.latitudeLabel.text = [NSString stringWithFormat:#"%0.8f", currentLocation.coordinate.latitude];
}
}
I put Break point on each methods, and even though, when I run the application, i got message in the Console: BSXPCMessage received error for message: Connection interrupted.
Any idea?
I got the same error message, still can't fix 'BSXPCMessage' error, but about the location part, I guess you're running iOS 7 version codes on iOS 8?
If so, try this:
Add [locationManager requestAlwaysAuthorization] or [locationManager requestWhenInUseAuthorization] above [locationManager startUpdatingLocation]
open Info.plist, add NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription into 'information property list' with a message
That's it, hope this can help you.
Getting the same error message when working with AVFoundation. Images and videos. It's not specific to what you do.
I am working with Map Kit in iOS 8 using Obj-C NOT SWIFT. I cannot get the device location it is set a 0.00, 0.00 and I am getting the error:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I have implemented: ( I have tried only one at a time and no luck )
if(IS_OS_8_OR_LATER) {
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
And in info.plist
NSLocationWhenInUseUsageDescription : App would like to use your location.
NSLocationAlwaysUsageDescription : App would like to use your location.
I do get prompted to allow the app to use my location but after I agree nothing changes. The location is being showed as 0.00, 0.00.
Code for displaying users location:
//Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
Mike.
**EDIT: View Answer Below.
I got it working. I've posted my code below to help anyone else having issues.
Here is my full code to get the MapKit Map View working in iOS 8.
In your AppName-Info.plist
Add a new row with the key name being:
NSLocationWhenInUseUsageDescription
Or
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
Enjoy!
--Mike
It's not written anywhere, but if your app starts with MapKit, you will still receive the error message "Trying to start MapKit location updates without prompting for location authorization" even after implementing MBarton's answer. To avoid it, you have to create a new view controller before the MapKit, and implement the location manager delegates there. I called it AuthorizationController.
So, in AuthorizationController.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MCIAuthorizationController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
And in AuthorizationController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Location manager
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
}
#pragma mark - Location Manager delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(#"didUpdateLocations: %#", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"Location manager error: %#", error.localizedDescription);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
[self performSegueWithIdentifier:#"startSegue" sender:self];
} else if (status == kCLAuthorizationStatusDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location services not authorized"
message:#"This app needs you to authorize locations services to work."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} else
NSLog(#"Wrong location status");
}
Try This One:
(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
Your code looks fine, though you do not need to call requestWhenInUseAuthorization and the other requestAlwaysAuthorization , choose one you need.
Code for displaying locations is just yet allocating locationManager, do not expect to get location data instantly.
you need to wait till delegate method gets called :
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
, then self.locationManager.location will also be set.
Further to Mikes answer, I found that using both [self.locationManager requestWhenInUseAuthorization]; and [self.locationManager requestAlwaysAuthorization]; as demonstrated in his code does not work. You should only use ONE.
I assume some further changes were made with a more recent/stable version of the API.
I had the same problem but adding these two line in plist file solved my problems
NSLocationWhenInUseUsageDescription
And
NSLocationAlwaysUsageDescription
NOTE : Must provide string description of both these values. You can use any of them in your controller file as below
self.locationManager= [[CLLocationManager alloc] init];
self.locationManager.delegate=self;
[self.locationManager requestAlwaysAuthorization];
You must implement CLLOcationManagerDelegate in your controller to access this functionality
To extend the accepted answer and if you create a sample project with just the above functionality, then apart from CoreLocation and Mapkit frameworks, you might need to add UIKit, Foundation and CoreGraphics framework manually as well in Xcode 6.
Actually, I am studying the CS193P Lecture 16, which is about location and map view, and I could not make the location manager work in iOS 8, applying what was in the video.
Looking at your answer, I could make it work.
The Info.plist was modified as described in the answers (I use the NSLocationWhenInUseUsageDescription).
In AddPhotoViewController.hn the define was added :
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
In AddPhotoViewController.m, the following code was added in ViewDidLoad (after self.image):
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
[self.locationManager requestWhenInUseAuthorization];
}
#endif
The authorization will be asked only once, the first time you launch the application.
The following was also added to AddPhotoViewController.h because it was not said in Lecture 16 :
#property (nonatomic) NSInteger locationErrorCode;
shouldPerformSegueWithIdentifier was modified to include else if (!self.location) :
else if (![self.titleTextField.text length])
{
[self alert:#"Title required"];
return NO;
}
else if (!self.location)
{
switch (self.locationErrorCode)
{
case kCLErrorLocationUnknown:
[self alert:#"Couldn't figure out where this photo was taken (yet)."]; break;
case kCLErrorDenied:
[self alert:#"Location Services disabled under Privacy in Settings application."]; break;
case kCLErrorNetwork:
[self alert:#"Can't figure out where this photo is being taken. Verify your connection to the network."]; break;
default:
[self alert:#"Cant figure out where this photo is being taken, sorry."]; break;
}
return NO;
}
else
{ // should check imageURL too to be sure we could write the file
return YES;
}
didFailWithError was added :
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
self.locationErrorCode = error.code;
}
I´m trying to pass the placemark locality from CLGeocoder to another class UILabel named cityLabel. The class with CLGeocoder named WXManager and the mainViewController named WXController. I have tried every way around to make it work, but I simply can´t get the city name passed to the cityLabel.
WXManager.h
#class WXManager;
#protocol WXManagerDelegate <NSObject>
- (void)WXManagerDidGeocodeCityName:(NSString *)cityName;
#end
#interface WXManager : NSObject <CLLocationManagerDelegate>
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
#end
WXManager.m
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if (self.isFirstUpdate) {
self.isFirstUpdate = NO;
return;
}
CLLocation *location = [locations lastObject];
if (location.horizontalAccuracy > 0) {
self.currentLocation = location;
[self.locationManager stopUpdatingLocation];}
CLGeocoder *fgeo = [[CLGeocoder alloc] init];
// Reverse Geocode a CLLocation to a CLPlacemark
[fgeo reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error){
if(!error){
for(CLPlacemark *placemark in placemarks){
self.cityName = [placemark locality];
[self.customDelegate WXManagerDidGeocodeCityName:self.cityName];
NSLog(#"city is %#",cityName); }
} else {
NSLog(#"There was a reverse geocoding error\n%#",
[error localizedDescription]);
}
}
];
}
WXController.h
#interface WXController : UIViewController
<WXManagerDelegate>
- (void)WXManagerDidGeocodeCityName:(NSString *)cityName;
#end
And at last in WXController.m where the problem seems to be, my method WXManagerDidGeocodeCityName wont get called. And I don´t know what´s wrong. Does anyone know how to make this method get called?
WXManager *cityName = [[WXManager alloc] init];
cityName.customDelegate = self;
#pragma mark - Custom Delegate Method
- (void)WXManagerDidGeocodeCityName:(NSString *)cityName
{
[self.cityLabel setText:cityName];
NSLog(#"cityName is %#", cityName);
NSLog(#"DidGetCalled");
}
The log doesnt get called so there´s got to be something missing somewhere.
Try this:
WXManager.h
#class WXManager;
#protocol WXManagerDelegate <NSObject>
- (void)WXManagerDidGeocodeCityName:(NSString *)cityName;
#end
#interface WXManager : NSObject <CLLocationManagerDelegate> {
id <WXManagerDelegate> customDelegate;
}
#property (retain)id customDelegate;
#end
WXController.h
#interface WXController : UIViewController <WXManagerDelegate>
//- (void)WXManagerDidGeocodeCityName:(NSString *)cityName;
#end
in WXManager.m you need initialize CLLocationManager:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
and everything will work out fine
I'm going to guess that cityName is weak, or has a custom setter/getter that clears/ignores the correct value.
Edit for clarification:
I was talking about your cityName here:
WXManager *cityName = [[WXManager alloc] init];
cityName.customDelegate = self;
I was assuming it would be assigned some property self.cityName later on.
If you don't, your self.customDelegate will become nil by the time the completion handler runs.
The method is not called? Or variable cityName equal nil?
If first - look for your delegate may be it equal nil.
If second - CLGeocoder work not correct.
Generally stroll debugger. Look at the variables. Quickly understand everything.
in WXManager.m you need initialize CLLocationManager:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; [self.locationManager
startUpdatingLocation];
and everything will work out fine