using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AddressBookUI; using CoreLocation; namespace Xamarin.Forms.Maps.iOS { internal class GeocoderBackend { public static void Register() { Geocoder.GetPositionsForAddressAsyncFunc = GetPositionsForAddressAsync; Geocoder.GetAddressesForPositionFuncAsync = GetAddressesForPositionAsync; } static Task> GetAddressesForPositionAsync(Position position) { var location = new CLLocation(position.Latitude, position.Longitude); var geocoder = new CLGeocoder(); var source = new TaskCompletionSource>(); geocoder.ReverseGeocodeLocation(location, (placemarks, error) => { if (placemarks == null) placemarks = new CLPlacemark[0]; IEnumerable addresses = placemarks.Select(p => ABAddressFormatting.ToString(p.AddressDictionary, false)); source.SetResult(addresses); }); return source.Task; } static Task> GetPositionsForAddressAsync(string address) { var geocoder = new CLGeocoder(); var source = new TaskCompletionSource>(); geocoder.GeocodeAddress(address, (placemarks, error) => { if (placemarks == null) placemarks = new CLPlacemark[0]; IEnumerable positions = placemarks.Select(p => new Position(p.Location.Coordinate.Latitude, p.Location.Coordinate.Longitude)); source.SetResult(positions); }); return source.Task; } } }