Skip to main content

Overview

The RadarDelegate protocol allows you to receive callbacks for location updates, events, errors, and debug logs on the client side. All methods are optional. To set a delegate, use:
Radar.setDelegate(self)
[Radar setDelegate:self];

Protocol Declaration

protocol RadarDelegate: NSObjectProtocol
@protocol RadarDelegate <NSObject>
@optional

Methods

All delegate methods are optional.

didReceiveEvents(_:user:)

func didReceiveEvents(_ events: [RadarEvent], user: RadarUser?)
- (void)didReceiveEvents:(NSArray<RadarEvent *> *)events user:(RadarUser *)user;
Tells the delegate that events were received.
events
Array<RadarEvent>
required
The events received.
user
RadarUser
The user, if any.

Example

func didReceiveEvents(_ events: [RadarEvent], user: RadarUser?) {
    for event in events {
        print("Received event: \(event.type)")
        
        if event.type == .userEnteredGeofence {
            print("User entered geofence: \(event.geofence?.description ?? "")")
        } else if event.type == .userEnteredPlace {
            print("User entered place: \(event.place?.name ?? "")")
        }
    }
    
    if let user = user {
        print("User location: \(user.location?.coordinate.latitude ?? 0), \(user.location?.coordinate.longitude ?? 0)")
    }
}
- (void)didReceiveEvents:(NSArray<RadarEvent *> *)events user:(RadarUser *)user {
    for (RadarEvent *event in events) {
        NSLog(@"Received event: %ld", (long)event.type);
        
        if (event.type == RadarEventTypeUserEnteredGeofence) {
            NSLog(@"User entered geofence: %@", event.geofence.description);
        } else if (event.type == RadarEventTypeUserEnteredPlace) {
            NSLog(@"User entered place: %@", event.place.name);
        }
    }
    
    if (user) {
        NSLog(@"User location: %f, %f", user.location.coordinate.latitude, user.location.coordinate.longitude);
    }
}

didUpdateLocation(_:user:)

func didUpdateLocation(_ location: CLLocation, user: RadarUser)
- (void)didUpdateLocation:(CLLocation *)location user:(RadarUser *)user;
Tells the delegate that the current user’s location was updated and synced to the server.
location
CLLocation
required
The location.
user
RadarUser
required
The current user.

Example

func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
    print("Location updated: \(location.coordinate.latitude), \(location.coordinate.longitude)")
    print("User geofences: \(user.geofences?.count ?? 0)")
    print("User place: \(user.place?.name ?? "none")")
}
- (void)didUpdateLocation:(CLLocation *)location user:(RadarUser *)user {
    NSLog(@"Location updated: %f, %f", location.coordinate.latitude, location.coordinate.longitude);
    NSLog(@"User geofences: %lu", (unsigned long)user.geofences.count);
    NSLog(@"User place: %@", user.place.name ?: @"none");
}

didUpdateClientLocation(_:stopped:source:)

func didUpdateClientLocation(_ location: CLLocation, stopped: Bool, source: RadarLocationSource)
- (void)didUpdateClientLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarLocationSource)source;
Tells the delegate that the client’s location was updated but not necessarily synced to the server. To receive only server-synced location updates and user state, use didUpdateLocation:user: instead.
location
CLLocation
required
The location.
stopped
Bool
required
A boolean indicating whether the client is stopped.
source
RadarLocationSource
required
The source of the location.

Example

func didUpdateClientLocation(_ location: CLLocation, stopped: Bool, source: RadarLocationSource) {
    print("Client location updated: \(location.coordinate.latitude), \(location.coordinate.longitude)")
    print("Stopped: \(stopped)")
    print("Source: \(Radar.stringForLocationSource(source))")
}
- (void)didUpdateClientLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarLocationSource)source {
    NSLog(@"Client location updated: %f, %f", location.coordinate.latitude, location.coordinate.longitude);
    NSLog(@"Stopped: %d", stopped);
    NSLog(@"Source: %@", [Radar stringForLocationSource:source]);
}

didFail(status:)

func didFail(status: RadarStatus)
- (void)didFailWithStatus:(RadarStatus)status;
Tells the delegate that a request failed.
status
RadarStatus
required
The status.

Example

func didFail(status: RadarStatus) {
    print("Request failed: \(Radar.stringForStatus(status))")
    
    switch status {
    case .errorPermissions:
        print("Location permissions not granted")
    case .errorLocation:
        print("Location services error or timeout")
    case .errorNetwork:
        print("Network error or timeout")
    default:
        break
    }
}
- (void)didFailWithStatus:(RadarStatus)status {
    NSLog(@"Request failed: %@", [Radar stringForStatus:status]);
    
    switch (status) {
        case RadarStatusErrorPermissions:
            NSLog(@"Location permissions not granted");
            break;
        case RadarStatusErrorLocation:
            NSLog(@"Location services error or timeout");
            break;
        case RadarStatusErrorNetwork:
            NSLog(@"Network error or timeout");
            break;
        default:
            break;
    }
}

didLog(message:)

func didLog(message: String)
- (void)didLogMessage:(NSString *)message;
Tells the delegate that a debug log message was received.
message
String
required
The message.

Example

func didLog(message: String) {
    print("Radar log: \(message)")
}
- (void)didLogMessage:(NSString *)message {
    NSLog(@"Radar log: %@", message);
}

Implementation Example

Here’s a complete example of implementing RadarDelegate:
class LocationManager: NSObject, RadarDelegate {
    
    func setupRadar() {
        Radar.initialize(publishableKey: "prj_test_pk_...")
        Radar.setDelegate(self)
        Radar.setLogLevel(.info)
    }
    
    // MARK: - RadarDelegate
    
    func didReceiveEvents(_ events: [RadarEvent], user: RadarUser?) {
        for event in events {
            print("Event: \(event.type) at \(event.createdAt)")
            
            // Handle specific event types
            switch event.type {
            case .userEnteredGeofence:
                if let geofence = event.geofence {
                    handleGeofenceEntry(geofence)
                }
            case .userExitedGeofence:
                if let geofence = event.geofence {
                    handleGeofenceExit(geofence)
                }
            case .userEnteredPlace:
                if let place = event.place {
                    handlePlaceEntry(place)
                }
            default:
                break
            }
        }
    }
    
    func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
        print("Location synced to server: \(location.coordinate)")
        
        // Access user context
        if let geofences = user.geofences {
            print("Currently in \(geofences.count) geofences")
        }
        
        if let place = user.place {
            print("Currently at: \(place.name)")
        }
    }
    
    func didUpdateClientLocation(_ location: CLLocation, stopped: Bool, source: RadarLocationSource) {
        print("Client location: \(location.coordinate), stopped: \(stopped)")
    }
    
    func didFail(status: RadarStatus) {
        print("Radar error: \(Radar.stringForStatus(status))")
        
        // Handle errors appropriately
        if status == .errorPermissions {
            // Prompt user to grant location permissions
            promptForLocationPermissions()
        }
    }
    
    func didLog(message: String) {
        // Send to your logging system if needed
        print("[Radar] \(message)")
    }
    
    // MARK: - Helper Methods
    
    private func handleGeofenceEntry(_ geofence: RadarGeofence) {
        print("Entered geofence: \(geofence.description)")
    }
    
    private func handleGeofenceExit(_ geofence: RadarGeofence) {
        print("Exited geofence: \(geofence.description)")
    }
    
    private func handlePlaceEntry(_ place: RadarPlace) {
        print("Entered place: \(place.name)")
    }
    
    private func promptForLocationPermissions() {
        // Your implementation
    }
}
@interface LocationManager () <RadarDelegate>
@end

@implementation LocationManager

- (void)setupRadar {
    [Radar initializeWithPublishableKey:@"prj_test_pk_..."];
    [Radar setDelegate:self];
    [Radar setLogLevel:RadarLogLevelInfo];
}

#pragma mark - RadarDelegate

- (void)didReceiveEvents:(NSArray<RadarEvent *> *)events user:(RadarUser *)user {
    for (RadarEvent *event in events) {
        NSLog(@"Event: %ld at %@", (long)event.type, event.createdAt);
        
        // Handle specific event types
        switch (event.type) {
            case RadarEventTypeUserEnteredGeofence:
                if (event.geofence) {
                    [self handleGeofenceEntry:event.geofence];
                }
                break;
            case RadarEventTypeUserExitedGeofence:
                if (event.geofence) {
                    [self handleGeofenceExit:event.geofence];
                }
                break;
            case RadarEventTypeUserEnteredPlace:
                if (event.place) {
                    [self handlePlaceEntry:event.place];
                }
                break;
            default:
                break;
        }
    }
}

- (void)didUpdateLocation:(CLLocation *)location user:(RadarUser *)user {
    NSLog(@"Location synced to server: %f, %f", location.coordinate.latitude, location.coordinate.longitude);
    
    // Access user context
    if (user.geofences) {
        NSLog(@"Currently in %lu geofences", (unsigned long)user.geofences.count);
    }
    
    if (user.place) {
        NSLog(@"Currently at: %@", user.place.name);
    }
}

- (void)didUpdateClientLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarLocationSource)source {
    NSLog(@"Client location: %f, %f, stopped: %d", location.coordinate.latitude, location.coordinate.longitude, stopped);
}

- (void)didFailWithStatus:(RadarStatus)status {
    NSLog(@"Radar error: %@", [Radar stringForStatus:status]);
    
    // Handle errors appropriately
    if (status == RadarStatusErrorPermissions) {
        // Prompt user to grant location permissions
        [self promptForLocationPermissions];
    }
}

- (void)didLogMessage:(NSString *)message {
    // Send to your logging system if needed
    NSLog(@"[Radar] %@", message);
}

#pragma mark - Helper Methods

- (void)handleGeofenceEntry:(RadarGeofence *)geofence {
    NSLog(@"Entered geofence: %@", geofence.description);
}

- (void)handleGeofenceExit:(RadarGeofence *)geofence {
    NSLog(@"Exited geofence: %@", geofence.description);
}

- (void)handlePlaceEntry:(RadarPlace *)place {
    NSLog(@"Entered place: %@", place.name);
}

- (void)promptForLocationPermissions {
    // Your implementation
}

@end

See Also

Build docs developers (and LLMs) love