Опыт работы с фреймворком Core Location в iOS

Ответ

Да, работал с Core Location для решения задач, связанных с геолокацией.

Основные возможности фреймворка, которые использовал:

  • Запрос разрешений: requestWhenInUseAuthorization() и requestAlwaysAuthorization().
  • Получение текущего местоположения: Разовое или отслеживание с различной точностью (kCLLocationAccuracyBest).
  • Фоновое отслеживание: Включение allowsBackgroundLocationUpdates с соответствующей настройкой Capabilities проекта.
  • Геокодирование: Преобразование координат в адрес (прямое геокодирование) и адреса в координаты (обратное) с помощью CLGeocoder.
  • Мониторинг регионов: Отслеживание входа/выхода из заданной географической области (CLCircularRegion) с помощью startMonitoring(for:).

Пример базовой реализации менеджера локации:

import CoreLocation

class LocationService: NSObject, CLLocationManagerDelegate {
    static let shared = LocationService()
    private let locationManager = CLLocationManager()
    private var locationUpdateHandler: ((CLLocation) -> Void)?

    private override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
    }

    // Запрос локации однократно
    func requestCurrentLocation(completion: @escaping (CLLocation) -> Void) {
        self.locationUpdateHandler = { location in
            completion(location)
            self.locationUpdateHandler = nil // Останавливаем после получения
            self.locationManager.stopUpdatingLocation()
        }
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }

    // CLLocationManagerDelegate
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let latestLocation = locations.last else { return }
        locationUpdateHandler?(latestLocation)
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Location update failed: (error.localizedDescription)")
    }
}

Важные аспекты: Всегда необходимо учитывать оптимизацию энергопотребления (использовать activityType), корректно обрабатывать ошибки и статусы разрешений, а также предоставлять понятное описание использования локации в Info.plist (NSLocationWhenInUseUsageDescription).

Ответ 18+ 🔞

Да ты посмотри, какой у нас тут специалист по геолокации объявился! Работал с Core Location, говорит. Ну, ясен пень, кто ж с ним не работал-то, этот фреймворк — как соседский алкаш, вечно лезет со своими координатами, но без него нихуя не сделаешь.

Ну и что этот ваш Core Location умеет, кроме как батарейку сосать?

  • Выпрашивать разрешения: Как нищий под дверью: «Можно я тут немножко понахожусь?» (requestWhenInUseAuthorization()) или «А можно я за тобой навсегда, как призрак, буду ходить?» (requestAlwaysAuthorization()). Без этих криков в Info.plist тебе просто пизда — приложение крашнется, и пользователь даже не поймёт, в чём дело.
  • Тыкать пальцем в карту: Найти, где ты сейчас стоишь. Можно один раз ткнуть (kCLLocationAccuracyBest), а можно включить режим преследования, как в шпионском триллере, и следить за каждой твоей жопой.
  • Работать в фоне: Включил allowsBackgroundLocationUpdates, настроил Capabilities — и всё, твое приложение теперь как жучок в кармане, тихонько стучит на сервер, где ты похавал шаурму. Главное — не переборщить, а то пользователь тебя снесёт, потому что телефон к вечеру превращается в кирпич.
  • Переводить с языка координат на человеческий: Это ж CLGeocoder — волшебник, блядь. Сказал ему «55.7558, 37.6173», а он тебе в ответ: «Да это ж, сука, Москва, Красная площадь, нахуй!». И наоборот, пишешь «Берлин, блядь», а он тебе координаты бункера Гитлера подкидывает. Ну, почти.
  • Следить за границами: Вот это вообще отдельная песня. Создал CLCircularRegion вокруг офиса — и всё, как только пересёк периметр, тебе пушка: «Добро пожаловать на каторгу, раб!». Или наоборот: «Ура, свободен!». startMonitoring(for:) — и ты уже почти Большой Брат.

Вот, смотри, как обычно это всё в коде выглядит, если не выёбываться:

import CoreLocation

class LocationService: NSObject, CLLocationManagerDelegate {
    static let shared = LocationService()
    private let locationManager = CLLocationManager()
    private var locationUpdateHandler: ((CLLocation) -> Void)?

    private override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
    }

    // Запрос локации однократно
    func requestCurrentLocation(completion: @escaping (CLLocation) -> Void) {
        self.locationUpdateHandler = { location in
            completion(location)
            self.locationUpdateHandler = nil // Останавливаем после получения
            self.locationManager.stopUpdatingLocation()
        }
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }

    // CLLocationManagerDelegate
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let latestLocation = locations.last else { return }
        locationUpdateHandler?(latestLocation)
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Location update failed: (error.localizedDescription)")
    }
}

А теперь, блядь, самое важное, что все просрать могут:

Энергопотребление, ёпта! Не тычь kCLLocationAccuracyBest просто так, если тебе нужно только понять, в каком городе чел сидит. Выбери activityType — пешеход, авто или поезд. Обрабатывай ошибки, а то пользователь в самолёте или в бункере, а у тебя приложение в истерике: «ГДЕ Я, БЛЯДЬ?». И самое главное — в Info.plist напиши человеческим языком, нахуя тебе доступ к локации. Не «Для улучшения опыта», а честно: «Чтобы показать ближайшие шаурмичные, сука». А то доверия ебать ноль будет.