iOS Question Geofencing - Trying to port RSProximityAlert to iOS - Help with ObjC Code

Discussion in 'iOS Questions' started by henrywood, Apr 25, 2015.

  1. henrywood

    henrywood Active Member Licensed User

    Hey again !

    This time I am trying to "port" the excellent RSProximityAlert for B4A to iOS. RSProximityAlert will allow for multiple geo fences to be defined.

    Could someone take a look please ?
    Comments about my questions are in the code but my main question is about this line:
    (self._locmanager).object
    And the line
    Private locManager As LocationManager

    Is this the correct way to make an instance of CLLocationManager ? I would like the instance to be a singleton ?

    For reference about the RSProximityAlert B4A version, please see: http://www.b4x.com/android/forum/threads/rsproximityalert-enter-or-exit-surrounding-area.36021/

    This is my code thus far:

    Code:
    'Class module
    Sub Class_Globals
       
    Private Module As Object
       
    Private EventPrefix As String = ""
       
    Private locManager As LocationManager

    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize(TargetModule As Object, EventPfx As String)

       Module = TargetModule
       EventPrefix = EventPfx

       
    Dim no As NativeObject = Me

       
    If no.RunMethod("checkLocationManagerInternal:"Null).AsBoolean = False Then
         
    Return
       
    End If

       no.RunMethod(
    "initInternal:"Null)

    End Sub

    #IF B4i
    Type PendingIntent(EventID As Long)
    #End If

    #IF OBJC
    #import <Foundation/Foundation.h>       // Do I need this line ?
    #import <CoreLocation/CoreLocation.h>     // Do I need this line ?

    - (CLRegion*)getRegion:(double)lat :(double)lng :(double)rad :(NSString*)id
    {
      NSString *identifier = id;
      CLLocationDegrees latitude = lat;
      CLLocationDegrees longitude =lng;
      CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
      CLLocationDistance regionRadius = rad;

      if(regionRadius > (self._locmanager).object.maximumRegionMonitoringDistance)  // Is this correct syntax ?
      {
      regionRadius = (self._locmanager).object.maximumRegionMonitoringDistance;     // // Is this correct syntax ?
      }

      NSString *version = [[UIDevice currentDevice] systemVersion];
      CLRegion * region =nil;

      if([version floatValue] >= 7.0f) //for iOS7
      {
      region =  [[CLCircularRegion alloc] initWithCenter:centerCoordinate
      radius:regionRadius
      identifier:identifier];
      }
      else // Below iOs 7
      {
      region = [[CLRegion alloc] initCircularRegionWithCenter:centerCoordinate
      radius:regionRadius
      identifier:identifier];
      }
      return  region;
    }

    -(void) initInternal
    {
       (self._locmanager).object = [[CLLocationManager alloc] init];
       (self._locmanager).object.delegate = self;
       (self._locmanager).object.desiredAccuracy = kCLLocationAccuracyBest;

    }
    -(void) showMessage:(NSString *) message
    {
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Geofence"
      message:message
      delegate:self
      cancelButtonTitle:@"Cancel"
      otherButtonTitles:Nil, nil];

      alertView.alertViewStyle = UIAlertViewStyleDefault;

      [alertView show];
    }

    -(BOOL) checkLocationManagerInternal
    {
      if(![CLLocationManager locationServicesEnabled])
      {
      [self showMessage:@"You need to enable Location Services"];
      return FALSE;
      }
      if(![CLLocationManager isMonitoringAvailableForClass:self.class])
      {
      [self showMessage:@"Region monitoring is not available for this Class"];
      return FALSE;
      }
      if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied ||
      [CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted  )
      {
      [self showMessage:@"You need to authorize Location Services for the APP"];
      return FALSE;
      }

      return TRUE;
    }
    -(NSString*) addGeofence:(double)latitude :(double)longitude :(double)radius :(NSString*)pointID
    {
      CLRegion *region = [self getRegion:latitude lng:longitude rad:radius id:pointID];
      [(self._locmanager).object startMonitoringForRegion:region];
       return pointID;
    }

    -(void) removeGeofence:(NSString*)pointID
    {
      NSArray *monitoredRegions = [(self._locmanager).object.monitoredRegions allObjects];

      for(CLRegion *region in monitoredRegions) {

         if ([region.identifier isEqualToString:pointID])
         {
         [(self._locmanager).object stopMonitoringForRegion:region];
         }
       }

    }
    -(void) clearGeofences
    {
      NSArray *monitoredRegions = [(self._locmanager).object.monitoredRegions allObjects];

      for(CLRegion *region in monitoredRegions) {
      [(self._locmanager).object stopMonitoringForRegion:region];
      }
    }

    //Helper Functions.
    - (NSNumber*)calculateDistanceInMetersBetweenCoord:(CLLocationCoordinate2D)coord1 coord:(CLLocationCoordinate2D)coord2 {
      NSInteger nRadius = 6371; // Earth's radius in Kilometers
      double latDiff = (coord2.latitude - coord1.latitude) * (M_PI/180);
      double lonDiff = (coord2.longitude - coord1.longitude) * (M_PI/180);
      double lat1InRadians = coord1.latitude * (M_PI/180);
      double lat2InRadians = coord2.latitude * (M_PI/180);
      double nA = pow ( sin(latDiff/2), 2 ) + cos(lat1InRadians) * cos(lat2InRadians) * pow ( sin(lonDiff/2), 2 );
      double nC = 2 * atan2( sqrt(nA), sqrt( 1 - nA ));
      double nD = nRadius * nC;
      // convert to meters
      return @(nD*1000);
    }

    /*
      Delegate Methods
    */

    - (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
    {
      if(state == CLRegionStateInside)
      {
      NSLog(@"##Entered Region - %@", region.identifier);
         // Raise event in B4i
         [self.bi raiseEvent:nil event:@"proximity_entered:" params:@[@(region.identifier)]];
      }
      else if(state == CLRegionStateOutside)
      {
      NSLog(@"##Exited Region - %@", region.identifier);
         // Raise event in B4i
         [self.bi raiseEvent:nil event:@"proximity_exited:" params:@[@(region.identifier)]];
      }
      else{
      NSLog(@"##Unknown state  Region - %@", region.identifier);
      }
    }
    - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
    {
      NSLog(@"Started monitoring %@ region", region.identifier);
    }
    - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
      NSLog(@"Entered Region - %@", region.identifier);

         // Raise event in B4i
         [self.bi raiseEvent:nil event:@"proximity_entered:" params:@[@(region.identifier)]];
    }

    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
      NSLog(@"Exited Region - %@", region.identifier);

         // Raise event in B4i
         [self.bi raiseEvent:nil event:@"proximity_exited:" params:@[@(region.identifier)]];
    }

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
      static BOOL firstTime=TRUE;

      if(firstTime)
      {
      firstTime = FALSE;
      NSSet *monitoredRegions = manager.monitoredRegions;
     
      if(monitoredRegions)
      {
      [monitoredRegions enumerateObjectsUsingBlock:^(CLRegion *region,BOOL *stop)
      {
      NSString *identifer = region.identifier;
      CLLocationCoordinate2D centerCoords =region.center;
      CLLocationCoordinate2D currentCoords= CLLocationCoordinate2DMake(newLocation.coordinate.latitude,newLocation.coordinate.longitude);
      CLLocationDistance radius = region.radius;

      NSNumber *currentLocationDistance =[self calculateDistanceInMetersBetweenCoord:currentCoords coord:centerCoords];
      if([currentLocationDistance floatValue] < radius)
      {
      NSLog(@"Invoking didEnterRegion Manually for region: %@",identifer);

      //stop Monitoring Region temporarily
      [(self._locmanager).object stopMonitoringForRegion:region];

      [(self._locmanager).object:locationManager didEnterRegion:region];
      //start Monitoing Region
      [(self._locmanager).object startMonitoringForRegion:region];
      }
      }];
      }
      //Stop Location Updation, we dont need it now.
      [(self._locmanager).object stopUpdatingLocation];

      }
    }

    #END IF

    Private Sub proximity_exited(EventID As String)

       
    Dim p As PendingIntent

       
    Dim foo As Long = EventID
       p.EventID = foo

       
    If SubExists(Module, EventPrefix & "_Exited") = True Then
         
    CallSub2(Module, EventPrefix & "_Exited", p)
       
    End If

    End Sub

    Private Sub proximity_entered(EventID As String)

       
    Dim p As PendingIntent

       
    Dim foo As Long = EventID
       p.EventID = foo

       
    If SubExists(Module, EventPrefix & "_Entered") = True Then
         
    CallSub2(Module, EventPrefix & "_Entered", p)
       
    End If

    End Sub

    Public Sub AddProximityAlert (   Longitude As Double, Latitude As Double, Radius As Float, _
                     Expiration 
    As Long, EventID As Long, RequestCode As Int) As PendingIntent

       
    Dim e As String = EventID             
       
    Dim p As PendingIntent
       
    Dim no As NativeObject = Me
       
    Dim foo As String = no.RunMethod("addGeofence::::"Array As Object(Latitude, Longitude, Radius, e))
       
    Dim bar As Long = foo
       p.EventID = bar
       
    Return p
                 
    End Sub

    Public Sub RemoveProximityAlert (intent As PendingIntent)

       
    Dim foo As String = intent.EventID
       
    Dim no As NativeObject = Me
       no.RunMethod(
    "removeGeofence:"Array As Object(foo))

    End Sub

    Public Sub RemoveAllGeofences

       
    Dim no As NativeObject = Me
       no.RunMethod(
    "clearGeofences:"Null)

    End Sub
     
    Last edited: Apr 26, 2015
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice