CLLocationManager startMonitoringSignificantLocationChanges doesn't work - objective-c

I want my application to get location updates even if it's terminated I tried to sign up for location changes using SignificantLocationChanges but I seems that I'm not getting any updates.
In my AppDelegate.m I have the following setup:
#interface AppDelegate () <RCTBridgeDelegate, CLLocationManagerDelegate>
#property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
#property (nonatomic, strong) CLLocationManager* locationManager;
#property BOOL didShowLocationUpdateNotification;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
/// other setup
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
switch(status) {
case kCLAuthorizationStatusNotDetermined:
NSLog(#"locationManagerDidChangeAuthorization - kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"locationManagerDidChangeAuthorization - kCLAuthorizationStatusRestricted");
break;
case kCLAuthorizationStatusDenied:
NSLog(#"locationManagerDidChangeAuthorization - kCLAuthorizationStatusDenied");
break;
case kCLAuthorizationStatusAuthorizedAlways:
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(#"locationManagerDidChangeAuthorization - kCLAuthorizationStatusAuthorizedWhenInUse");
break;
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
NSLog(#"didUpdateLocation");
NSLog(#"Locations %#", locations);
}
I have the following Background Modes enabled:
I also have those keys in my info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your location is required to track your journeys. By selecting ALWAYS your journeys will record automatically.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Your location is required to track your journeys. </string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is required to track your journeys. WARNING: Journeys will not automatically record with 'When In Use' selected</string>
And yet, after I terminate the app, it never wakes up again even though I changed my location drastically.
What else am I mussing here?
I'm testing it on iPhone 11 with iOS 15.

Related

didUpdateLocations is not called in ios 9.3.2

didUpdateLocations is never called, instead didFailWithError is called with denied code kCLErrorDenied.
Here are the things that i did:
#import "ViewController.h"
#import CoreLocation;
#interface ViewController () <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
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];
}
[self.locationManager startUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
{
NSLog(#"update");
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(nonnull NSError *)error
{
NSLog(#"error");
}
#end
Inserted NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription to the info.plist of the app. Enabled Background Modes in Capabilities with Location updates selected. Get help from the very famous blog post. I receive Location Access Request popup and allow the app to access location.
But i couldnt managed to get location updates. It works in IPAD with IOS 8 but not work at ipad with IOS version 9.3.2. How can i make location updates work in IOS 9.3.2?
trying following thing may resolve your issue:
go to settings and reset your location services
reset your network settings
restarting the simulator
also, if you have Scheme/Edit Scheme/Options/Allow Location Simulation checked but don't have a default location set.
Add NSLocationAlwaysUsageDescription to your plist as type string if using Always authorization. Also, do the same for NSLocationWhenInUseUsageDescription same way if using WhenInUse authorization.
For detail check answers here:
didFailWithError: Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
and IOS 9 Error Domain=kCLErrorDomain Code=0 "(null)"

CLLocationManager works with ARC?

All I'm trying to do is get the current position of the User, and show on the map of my app, so I am using CLLocationManager class, as anybody can see below:
ViewController.h
import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MeuPrimeiroViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>{
IBOutlet MKMapView *mapView;
}
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
ViewController.m
-(void)viewDidAppear:(BOOL)animated{
//Lendo as coordenadas com o core location
if ([CLLocationManager locationServicesEnabled]) {
NSLog(#"CLLocationManager locationServicesEnabled == ON");
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}else{
NSLog(#"CLLocationManager locationServicesEnabled == OFF");
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
CLLocationDistance altitude = newLocation.altitude;
CLLocationDegrees latitude = newLocation.coordinate.latitude;
CLLocationDegrees longitude = newLocation.coordinate.longitude;
NSLog(#"Altitude, Latitude, Longitude: %f, %f, %f",altitude,latitude,longitude);
MKCoordinateRegion coordenada = {{0.0,0.0}, {0.0,0.0}};
coordenada.center.latitude = latitude;
coordenada.center.longitude = longitude;
[mapView setRegion:coordenada animated:YES];
//Calculando distancias
CLLocationDistance distancia = [newLocation distanceFromLocation:oldLocation];
NSLog(#"Distancia em metros : %f",distancia);
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"Error: %#",[error description]);
}
The problem with this code is that my methods of CLLocationManager class not being called, I did some research on the internet over a possible problem related to the ARC, but none of them worked, any suggestions?
iOS 8 changed 2 things that make this not work as it did before
On iOS 8, you need to call requestWhenInUseAuthorization or requestAlwaysAuthorization before calling startUpdatingLocation
You MUST provide a location usage description corresponding to what type of authorization you are requesting in the Info.plist (either NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription). You should also continue to provide the value for the old pre-iOS 8 key (NSLocationUsageDescription) as a fallback for older versions of iOS.
All I'm trying to do is get the current position of the User, and show on the map of my app
You do not need any of that in order to put the user's location on a map. Just tell the map to track the user's location. In iOS 8 you do need user authorization to do this, and for that you do need a location manager. But these two lines of code are sufficient (this is Swift but I'm sure you can translate):
self.locman.requestWhenInUseAuthorization()
self.map.userTrackingMode = .Follow

Using CLLocationManager on iOS Simulator to find latitude and longitude [duplicate]

This question already has answers here:
Location Services not working in iOS 8
(26 answers)
Closed 8 years ago.
I am trying to create an application that opens with a map using MKMapView, and then by creating a delegate to CLLocationManger find the current location of the user.
I have posted my code below. The problem that I am having right now is that that although the map does appear when opening the this the simulator it does not give a position or a new heading from the NSLog that should be passing the latitude and longitude.
I am new to Objective - C and App Development, does anyone see if I am missing some of the protocol for CLLocationManger? Thanks for all your help.
Sorry the code is a little sloppy, pasted it in quickly.
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController () <CLLocationManagerDelegate>
#property (nonatomic,strong)CLLocationManager * myLocationManger;
#property (nonatomic,strong) IBOutlet MKMapView *myMapView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"insdie view did load");
// Setting the map to be big as the view
self.myMapView =[[MKMapView alloc]init];
//Initial Property to Map
self.myMapView =[[MKMapView alloc] init];
//Set type to Standard
self.myMapView.mapType = MKMapTypeStandard;
//Set Mask for AutoReszing
self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
//Add the View!
[self.view addSubview:self.myMapView];
///*Now lets Use my CLLocation Manager to Locate the iPhone's Posistion*////
//Chekcs if Location Services are Enabled
if ([CLLocationManager locationServicesEnabled]) {
self.myLocationManger = [[CLLocationManager alloc] init];
self.myLocationManger.delegate = self;
[self.myLocationManger startUpdatingLocation];
}
else{
//Location Services are available we will need software to ask to turn this On
//The user is SOL if they refuse to turn on Location Services
NSLog(#"Location Services not enabled");
}
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
//This method will show us that we recieved the new location
NSLog(#"Latitude = %f",newLocation.coordinate.latitude );
NSLog(#"Longitude =%f",newLocation.coordinate.longitude);
}
-(void)locationManager:(CLLocationManager *)manager
didFinishDeferredUpdatesWithError:(NSError *)error{
NSLog(#"Error with Updating");
}
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
//Failed to recieve user's location
NSLog(#"failed to recived user's locatio");
}
I found that in the new iOS 8, you need two keys added to the Plist. This article explains the process beautifuly.
http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

Why does UILocalNotification with region not fire?

I have followed the example given in the WWDC 2014 session "What's New in iOS Notifications" to set up a UILocalNotification delivery when a region's boundary is crossed.
However, my notification never fires on device nor simulator running iOS beta 3. The notification works fine when I tested using a fireDate instead of a region (not both at same time-- that's not allowed).
I have set NSLocationWhenInUseUsageDescription in my Info.plist.
Here is my Obj-C code:
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#interface ViewController () <CLLocationManagerDelegate>
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation *notifLocation;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// test points at Apple HQ
self.notifLocation = [[CLLocation alloc] initWithLatitude:37.331741 longitude:-122.030333];
[self setupLocationMonitoring];
}
- (void) setupLocationMonitoring
{
if (self.locationManager == nil) {
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 10; // meters
// iOS 8+ request authorization to track the user’s location
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
- (void)registerLocationNotification
{
UILocalNotification *locNotification = [[UILocalNotification alloc] init];
locNotification.alertBody = #"Hello!";
// doesn't work
locNotification.regionTriggersOnce = NO;
locNotification.region = [[CLCircularRegion alloc] initWithCenter:self.notifLocation.coordinate radius:50 identifier:#"PlaceName"];
// works:
// locNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
UIApplication *application = [UIApplication sharedApplication];
[application cancelAllLocalNotifications];
[application scheduleLocalNotification:locNotification];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
// check status to see if we’re authorized
BOOL canUseLocationNotifications = (status == kCLAuthorizationStatusAuthorizedWhenInUse);
if (canUseLocationNotifications) {
[self registerLocationNotification];
}
}
#end
Note: this question is about iOS 8's new Location Notifications, not about region monitoring on older versions of iOS.
Your code works fine for me. Here are the steps on iPhone Simulator:
1) Open Simulator app and choose the following option from the top menu Debug -> Location -> Custom Location and put there the coordinates as you have in code: (37.331741, -122.030333)
2) Run your Xcode project on iPhone Simulator
3) Background the app
4) Open the same top menu item Debug -> Location but change it from Custom Location to Freeway Drive or City Run. Play with City Run/ Freeway Drive and Custom Location
I see the notification when I follow these steps. Looks like it doesn't work in case appropriate coordinate is a starting one but it works when the coordinate changes to appropriate from some others.

Applications are expected to have a root view controller at the end of application launch wait_fences: failed to receive reply: 10004003

when i launch my application in iphone emulator, it goes without any problem. If i launch on device it will crash as still as i open it. But when i launch emulator it says that problem:
Applications are expected to have a root view controller at the end of application launch
wait_fences: failed to receive reply: 10004003
What can i do?
This is my application delegate:
.h :
#import <UIKit/UIKit.h>
#class TrovaChiaviViewController;
#interface TrovaChiaviAppDelegate : NSObject <UIApplicationDelegate>
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet TrovaChiaviViewController *viewController;
#end
and this is .m
#import "TrovaChiaviAppDelegate.h"
#import "TrovaChiaviViewController.h"
#implementation TrovaChiaviAppDelegate
#synthesize window = _window;
#synthesize viewController = _viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[application release];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
#end
I don't see where you are setting your viewController property, add
self.viewController = [[[TrovaChiaviViewController alloc] initWithNibName:#"TrovaChiaviViewController" bundle:nil] autorelease];
before
self.window.rootViewController = self.viewController;
I just had this issue when I was changing the application from iPhone only to iPad. The error message "Applications are expected to have a root view controller at the end of application launch" was happening because in the application-info plist, there was an entry specifying a nib file for MainWindow when I was no longer using a nib.
Although this is an older thread, I thought I'd contribute. Sometimes I select a template when creating new projects. There were two cases when I created empty projects. In both of these cases, I encountered the same problem.
Refer to this link.
http://www.mumuen.com/2011/09/applications-are-expected-to-have-root.html
In my case, the key was that I had failed to allocate space for both my window and root controller.