CoreLocation.CLLocationManager Class
Manages the delivery of location, region, and heading events to your application.

See Also: CLLocationManager Members

Syntax

[Foundation.Register("CLLocationManager", true)]
public class CLLocationManager : Foundation.NSObject

Remarks

Requesting Authorization

Starting with iOS 8, developers that want to request access to the location information must request permission from the user to do so before they can receive events. This is done by calling either the CLLocationManager.RequestWhenInUseAuthorization or the CLLocationManager.RequestAlwaysAuthorization methods. When these methods are invoked, the system will prompt the user for authorization, and if he grants it, the CLLocationManager.AuthorizationChanged event will be raised if set (or if you are using the Delegate idiom, the CLLocationManagerDelegate.AuthorizationChanged method will be invoked.

Additionally, developers must add one or both of the keys NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription in their app's info.plist. These keys are strings that can be used to describe why the app needs location access.

Developers should use an idiom like this:

c# Example

var manager = new CLLocationManager();
manager.AuthorizationChanged += (sender, args) => {
	Console.WriteLine ("Authorization changed to: {0}", args.Status);
};
if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
    manager.RequestWhenInUseAuthorization();

Tracking the device's location

The most common use-case for the CoreLocation.CLLocationManager is tracking the device while the application is in the foreground. (See also "Background Updating and Deferred Mode" below.)

Application developers may use either C#-style events or Apple's delegate-object pattern to track foreground location updating. For C#-style events, developers can use the CLLocationManager.LocationsUpdated event:

C# Example

var mgr = new CLLocationManager();
mgr.LocationsUpdated += (sender, e) => {
	foreach(var loc in e.Locations)
	{
		Console.WriteLine(loc);
	}
};
mgr.StartUpdatingLocation();
          

F# Example

let mgr = new CLLocationManager()
mgr.LocationsUpdated.Add( fun e ->
    e.Locations |> Seq.map Console.WriteLine |> ignore )
mgr.StartUpdatingLocations()          
          

While C#-style events are more concise, the CoreLocation.CLLocationManager must use the delegate-object pattern for certain behaviors (for instance, deferred updating), and it may be more consistent for an application to use the delegate-object pattern even when C#-style events are available. The delegate-object pattern consists of assigning a customized CoreLocation.CLLocationManagerDelegate object to the CLLocationManager.Delegate property of the CoreLocation.CLLocationManager:

C# Example

var mgr = new CLLocationManager();
mgr.Delegate = new MyLocationDelegate();
mgr.StartUpdatingLocation();
//...etc...

public class MyLocationDelegate : CLLocationManagerDelegate {
	public override void LocationsUpdated (CLLocationManager manager, CLLocation[] locations) {
		foreach(var loc in locations) {
			Console.WriteLine(loc);
		}
	}
}          
          

F# Example

let mgr = new CLLocationManager()
mgr.Delegate <- new MyLocationDelegate()
mgr.StartUpdatingLocation()
//...etc...

type MyLocationDelegate () = inherit CLLocationManagerDelegate()
    override this.LocationsUpdated ( manager : CLLocationManager, locations : CLLocation[] ) = 
        locations 
        |> Seq.map Console.WriteLine
        |> ignore          
          

Region monitoring (Geofencing)

The CoreLocation.CLLocationManager can track the device's entry and exit from geographical regions (geofences). A region will be a subtype of CoreLocation.CLRegion : either a CoreLocation.CLCircularRegion or a region associated with an iBeacon, of type CoreLocation.CLBeaconRegion.

CoreLocation.CLRegion identity should only be compared via the CoreLocation.CLRegion.Identifier property. Regions are monitored at the operating-system level and new CoreLocation.CLRegion objects with the specified CoreLocation.CLRegion.Identifier may be instantiated by the system when the device enters or exists an area; these CoreLocation.CLRegions will be different objects (myExpectedRegion != myReceivedRegion) but will have the same CoreLocation.CLRegion.Identifier (myExpectedRegion.Identifier.Equals(myReceivedRegion.Identifier, StringComparison.Ordinal)).

Application developers can use either C#-style events or Apple's delegate-object pattern:

C# Example

var rgn = new CLCircularRegion(new CLLocationCoordinate2D(latitude, longitude), 50, "target");
mgr = new CLLocationManager();
mgr.RegionEntered += (s,e) => Console.WriteLine("Entered region " + e.Region.Identifier);
mgr.RegionLeft += (s,e) => Console.WriteLine("Left region " + e.Region.Identifier);
mgr.StartMonitoring(rgn);
          

F# Example

let rgn = new CLCircularRegion(new CLLocationCoordinate2D(latitude, longitude), 50, "target")     
let mgr = new CLLocationManager()
mgr.RegionEntered.Add( fun e -> Console.WriteLine("Entered region " + e.Region.Identifier))
mgr.RegionLeft.Add( fun e -> Console.WriteLine("Left region " + e.Region.Identifier))
mgr.StartMonitoring(rgn)
          

C# Example

var rgn = new CLCircularRegion(new CLLocationCoordinate2D(latitude, longitude), 50, "target");
mgr = new CLLocationManager();
var del = new MyLocationDelegate();
mgr.Delegate = del;
mgr.StartMonitoring(rgn);
//...etc...

public class MyLocationDelegate : CLLocationManagerDelegate {
    public override void RegionEntered (CLLocationManager mgr, CLRegion rgn) {
        Console.WriteLine ("Entered region " + rgn.Identifier);
    }

    public override void RegionLeft (CLLocationManager mgr, CLRegion rgn) {
        Console.WriteLine ("Left region " + rgn.Identifier);
    }
}
       

F# Example

let rgn = new CLCircularRegion(new CLLocationCoordinate2D(latitude, longitude), 50, "target")
let mgr = new CLLocationManager()
mgr.Delegate <- new MyLocationDelegate()
mgr.StartMonitoring(rgn)
//...etc...

type MyLocationDelegate () = inherit CLLocationManagerDelegate()
    override this.RegionEntered ( mgr : CLLocationManager, rgn : CLRegion ) = 
        Console.WriteLine ("Entered region " + rgn.Identifier)

    override this.RegionLeft ( mgr : CLLocationManager, rgn : CLRegion ) =
        Console.WriteLine ("Left region " + rgn.Identifier)
        
        

iBeacon Ranging

In iOS 7, Apple introduced iBeacons, which combine region-processing using server and GPS services and nearby promixity ranging using Bluetooth Low-Energy (BLE) signaling.

Once within a CoreLocation.CLBeaconRegion (see previous section), applications may track "ranging" events relating to fine-grained changes in the distance between the device and nearby iBeacons. iBeacon ranging is primarily a function of radio signal strength, which can vary significantly based on environment, electrical noise, etc. Application developers should not attempt to estimate precise distances from the CLBeacon.Proximity or CLBeacon.RSSI properties.

Ranging is done with code similar to:

iBeacons also support "ranging" for determining physical proximity with a higher precision with the Foundation.CLBeacon.Proximity property. The following example shows how ranging should be used as a qualitative measure:

C# Example

locationManager.DidRangeBeacons += (lm, rangeEvents) => {
    switch(rangeEvents.Beacons[0].Proximity){
    case CLProximity.Far : 
        Console.WriteLine("You're getting colder!");
        break;
    case CLProximity.Near :
        Console.WriteLine("You're getting warmer!");
        break;
    case CLProximity.Immediate :
        Console.WriteLine("You're red hot!");
        break;

F# Example

locationManager.DidRangeBeacons.Add(fun rangeEvents ->
    let s = match rangeEvents.Beacons.[0].Proximity with
        | CLProximity.Far  -> "You're getting colder!"
        | CLProximity.Near -> "You're getting warmer!"
        | CLProximity.Immediate -> "You're red hot!"
        | CLProximity.Unknown -> "I can't tell"
        | _ -> raise(ArgumentOutOfRangeException("Unknown argument"))
    Console.WriteLine(s)   
)
locationManager.StartRangingBeacons(beaconRegion)       
        
Operation

Background Updating and Deferred Mode

Locations can be updated while the application is in the background. This requires that the info.plist be modified using either Xamarin Studio's visual editor:

Or by adding the key manually:

C# Example

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>            

Power consumption is an important consideration for all backgrounding scenarios. In the case of location data, GPS-enabled hardware may be able to record and cache accurate location but defer the delivery to the application for some amount of time. This "deferred mode" has several constraints:

If those conditions are satisfied, the application can request deferred delivery when backgrounded by calling the CLLocationManager.AllowDeferredLocationUpdatesUntil method.

Operation

Importance of Delegate object

Generally, when using Xamarin.iOS, developers can freely choose whether to use C# events or Apple-style "delegate objects" to react to object lifecycle events. Several CoreLocation.CLLocationManager methods, however, require the delegate-object pattern. For instance, CLLocationManager.AllowDeferredLocationUpdatesUntil will raise a runtime exception if the CLLocationManager.Delegate property is not set to an object whose class implements CLLocationManagerDelegate.LocationsUpdated method.

Related content

Requirements

Namespace: CoreLocation
Assembly: Xamarin.iOS (in Xamarin.iOS.dll)
Assembly Versions: 0.0.0.0