Геолокация и карты в Swift: CoreLocation и MapKit для iOS/macOS

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Геолокация и карты в Swift: обзор CoreLocation и MapKit

Разработка приложений для iOS и macOS часто требует работы с географическими данными и визуализацией карт. В экосистеме Apple для этих целей существуют два мощных фреймворка: CoreLocation (для определения местоположения, геокодирования и регионов мониторинга) и MapKit (для отображения карт, добавления аннотаций и построения маршрутов). В этой статье мы подробно разберём их возможности и приведём практические примеры на Swift.

1. CoreLocation: получение координат устройства

CoreLocation предоставляет доступ к аппаратным средствам определения местоположения: GPS, Wi-Fi и сотовым сетям. Для начала работы необходимо импортировать фреймворк и запросить разрешение у пользователя.

Настройка разрешений

В файл Info.plist добавьте ключи:

  • NSLocationWhenInUseUsageDescription — для использования приложения в активном режиме
  • NSLocationAlwaysAndWhenInUseUsageDescription — для фонового мониторинга

Пример получения текущего местоположения

import CoreLocation

class LocationManager: NSObject, CLLocationManagerDelegate {
    private let manager = CLLocationManager()
    
    override init() {
        super.init()
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    func requestPermission() {
        manager.requestWhenInUseAuthorization()
    }
    
    func startUpdating() {
        manager.startUpdatingLocation()
    }
    
    // MARK: - Delegate
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        print("Широта: \(location.coordinate.latitude), Долгота: \(location.coordinate.longitude)")
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Ошибка: \(error.localizedDescription)")
    }
}

2. MapKit: отображение карт и аннотации

MapKit позволяет встраивать карты Apple Maps в приложение. Основной класс — MKMapView. Рассмотрим базовую настройку и добавление меток.

Создание карты в коде

import MapKit
import SwiftUI

struct MapView: UIViewRepresentable {
    @Binding var region: MKCoordinateRegion
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        return mapView
    }
    
    func updateUIView(_ uiView: MKMapView, context: Context) {
        uiView.setRegion(region, animated: true)
    }
    
    // Coordinator для обработки событий
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView
        init(_ parent: MapView) { self.parent = parent }
    }
}

Добавление аннотации (пин на карте)

import MapKit

class CustomAnnotation: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?
    
    init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
    }
}

// Использование:
let annotation = CustomAnnotation(
    coordinate: CLLocationCoordinate2D(latitude: 55.7558, longitude: 37.6173),
    title: "Москва",
    subtitle: "Красная площадь"
)
mapView.addAnnotation(annotation)

3. Геокодирование: преобразование адреса в координаты

Класс CLGeocoder позволяет переводить текстовый адрес в координаты (прямое геокодирование) и наоборот (обратное).

import CoreLocation

let geocoder = CLGeocoder()
geocoder.geocodeAddressString("Москва, Кремль") { placemarks, error in
    guard let placemark = placemarks?.first,
          let location = placemark.location else { return }
    print("Координаты: \(location.coordinate)")
}

// Обратное геокодирование:
let location = CLLocation(latitude: 55.7558, longitude: 37.6173)
geocoder.reverseGeocodeLocation(location) { placemarks, error in
    guard let placemark = placemarks?.first else { return }
    print("Адрес: \(placemark.name ?? ""), \(placemark.locality ?? "")")
}

4. Построение маршрутов с MKDirections

MapKit поддерживает запрос маршрутов для автомобиля, пешехода и общественного транспорта. Используйте MKDirectionsRequest и MKDirections.

import MapKit

func calculateRoute(from source: MKMapItem, to destination: MKMapItem) {
    let request = MKDirections.Request()
    request.source = source
    request.destination = destination
    request.transportType = .automobile
    
    let directions =                    

Рекомендаций