startMonitoringLocationPushes of CLLocationManager is not returning

When I call startMonitoringLocationPushesWithCompletion, the completion "callback" is never executed.

This is what we have done to prepare for this service:

  1. We have the com.apple.developer.location.push in the entitlements file
  2. Our request to use the location push service has been approved
  3. We have enabled Location Push Service Extension in Certificates, Identifiers & Profiles of our app on developer.apple.com
  4. We have the push notification and location update capabilities
  5. The user has granted the app "Always" location access
  6. We have these purpose strings in our info.plist already: NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
  7. We have the automatically generated location push service extension

Here is the code that we use to test the service:

#import <React/RCTLog.h>
#import <CoreLocation/CoreLocation.h>
#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  if (@available(iOS 15.0, *)) {
    RCTLogInfo(@"Starting monitoring location pushes");
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    [locationManager startMonitoringLocationPushesWithCompletion:^(NSData * _Nullable token, NSError * _Nullable error) {
      RCTLogInfo(@"Completion called");
      if (token) {
        NSString *tokenString = [NSString stringWithFormat:@"%@", token];
        RCTLogInfo(@"Token: %@", tokenString);
      }
      if (error){
        RCTLogError(@"Error: %@", error);
      }
      RCTLogInfo(@"Completion ends %@ %@", token, error);
    }];
    RCTLogInfo(@"End monitoring location pushes");
  } else {
    RCTLogError(@"Incompatible iOS version");
  }
  return YES;
}

The only logs:

2022-03-29 18:38:02.736615+0100 ***[yyy] [native] Starting monitoring location pushes
2022-03-29 18:38:02.738087+0100 ***[yyy] [native] End monitoring location pushes
Answered by EricHo73 in 709135022

I don't know exactly how but it works after I put locationManager outside the @available block like this:

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if (@available(iOS 15.0, *)) {
  RCTLogInfo(@"Starting monitoring location pushes");
  [locationManager startMonitoringLocationPushesWithCompletion:^(NSData * _Nullable token, NSError * _Nullable error) {
    RCTLogInfo(@"Completion called");
    if (token) {
      NSString *tokenString = [NSString stringWithFormat:@"%@", token];
      RCTLogInfo(@"Token: %@", tokenString);
    }
    if (error){
      RCTLogError(@"Error: %@", error);
    }
    RCTLogInfo(@"Completion ends %@ %@", token, error);
  }];
  RCTLogInfo(@"End monitoring location pushes");
} else {
  RCTLogError(@"Incompatible iOS version");
}

Probably related to garbage collection?

P.S. As a react-native module you would also need to override methodQueue of RCTBridgeModule : (Swift)

extension MyModule {
  override var methodQueue: DispatchQueue {
    get {
      return DispatchQueue.main
    }
  }
  // ...
}
Accepted Answer

I don't know exactly how but it works after I put locationManager outside the @available block like this:

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if (@available(iOS 15.0, *)) {
  RCTLogInfo(@"Starting monitoring location pushes");
  [locationManager startMonitoringLocationPushesWithCompletion:^(NSData * _Nullable token, NSError * _Nullable error) {
    RCTLogInfo(@"Completion called");
    if (token) {
      NSString *tokenString = [NSString stringWithFormat:@"%@", token];
      RCTLogInfo(@"Token: %@", tokenString);
    }
    if (error){
      RCTLogError(@"Error: %@", error);
    }
    RCTLogInfo(@"Completion ends %@ %@", token, error);
  }];
  RCTLogInfo(@"End monitoring location pushes");
} else {
  RCTLogError(@"Incompatible iOS version");
}

Probably related to garbage collection?

P.S. As a react-native module you would also need to override methodQueue of RCTBridgeModule : (Swift)

extension MyModule {
  override var methodQueue: DispatchQueue {
    get {
      return DispatchQueue.main
    }
  }
  // ...
}
startMonitoringLocationPushes of CLLocationManager is not returning
 
 
Q