Connect with us

Разработка

Оптимизируем обновление местоположения с помощью CLLocationUpdate в Swift

Новый, современный и упрощенный API для получения местоположений от Apple.

Фото аватара

Опубликовано

/

     
     

На WWDC 23 Apple значительно улучшила процесс обновления местоположения, представив класс CLLocationUpdate. Этот новый класс использует возможности современного Swift Concurrency, упрощая получение и управление данными о местоположении в ваших приложениях.

Что нового?

  • Раньше для получения данных о местоположении требовались сложные методы-делегаты и обратные вызовы, что делало наш код менее читабельным и неорганизованным.
  • Класс CLLocationUpdate упрощает этот процесс, предоставляя асинхронный подход, использующий функции параллелизма Swift.
  • Это означает, что теперь мы можем использовать синтаксис async/await для управления обновлениями местоположения, что делает наш код чище и читабельнее.
  • Кроме того, он автоматически приостанавливает/возобновляет обновление местоположения в зависимости от того, движется пользователь или неподвижен.

Почему стоит использовать CLLocationUpdate

  • Упрощенный код: синтаксис async/await делает код чище и проще для понимания и тестирования, чем традиционные методы с делегатами и колбеками.
  • Улучшенная читаемость: код становится организованным и читабельным и помещает все компоненты в одно место, что позволяет больше сосредоточиться на фактической логике обработки местоположения.
  • Обработка ошибок: поскольку мы можем использовать async/await в этом методе, мы можем использовать блок try/catch внутри цикла для простой обработки ошибок.
  • Поддержка параллелизма: поскольку местоположение предоставляется в виде AsyncSequence, мы можем интегрировать его с другими асинхронными операциями в нашем приложении.
  • Эффективность использования аккумулятора: поскольку функция обеспечивает автоматическую паузу/возобновление обновления местоположения в зависимости от того, движется пользователь или неподвижен, она также способствует увеличению времени автономной работы.

Как использовать CLLocationUpdate

Использование класса CLLocationUpdate для обновления местоположения требует выполнения следующих шагов:

  1. Импортируйте CoreLocation.
  2. Затем вызовите статическую фабричную функцию .liveUpdates(), предоставляемую классом CLLocationUpdate, чтобы получить обновления в виде последовательности AsyncSequence. Эта последовательность может быть итерирована напрямую с помощью for/try/await для получения CLLocationUpdate в замыкании.
  3. Теперь используйте CLLocationUpdate, полученный в замыкании, чтобы получить местоположение, обратившись к его свойству location.
import CoreLocation

func startLocationUpdates() {
    // Take location permissions before
    Task {
        do {
            let updates = CLLocationUpdate.liveUpdates()
            for try await update in updates {
                print ("Current Location is \(update.location)")
                
                // To stop updates break out of the for loop
                if update.isStationary {
                    break
                }
            }
        } catch {
            debugPrint("Some Error Occured")
        }
    }
}

Как это работает за кулисами?

Оптимизируем обновление местоположения с помощью CLLocationUpdate в Swift

  1. В новом классе CLLocationUpdate у нас есть статическая функция .liveUpdates() . Она возвращает последовательность AsyncSequence под названием Updates, которую можно напрямую итерировать с помощью цикла for/try/await.
  2. Updates при итерации с помощью цикла for/try/await дает CLLocationUpdate, содержащий местоположение типа CLLocation и булевский флаг isStationary для управления автоматическими паузами и возобновлениями.
public struct CLLocationUpdate : Sendable {
   public let location : CLLocation? // nil if no location is available
   public let isStationary : Bool // true if device becomes stationary
}
  1. Мы также можем передать функции .liveUpdates() аргумент типа LiveConfiguration , который является перечислением. Он используется в качестве маркера типа активности, на которую вы ориентируетесь при запросе местоположения.
public enum LiveConfiguration {
   case default
   case automotiveNavigation
   case otherNavigation
   case fitness
   case airborne
}

Добавление фильтра расстояний при обновлении

Мы также можем отфильтровать только те места, которые удовлетворяют нашему минимальному расстоянию. Чтобы добавить эту логику, нам нужно добавить фильтр в нашу функцию .liveUpdates().

private var previousLocation: CLLocation? = nil
private var distanceThreshold: CLLocationDistance = 0.0

...

let locationUpdates = CLLocationUpdate.liveUpdates(.fitness).filter { [weak self] update in
                    guard let self else { return false }
                    guard let previousLocation = self.previousLocation else {
                        self.previousLocation = update.location
                        return true
                    }
                    let distanceMoved = update.location?.distance(from: previousLocation)
                    if distanceMoved ?? 0.0 >= distanceThreshold || update.isStationary {
                        self.previousLocation = update.location
                        return true
                    }
                    return false
                }

....

Как получать обновления местоположения в фоновом режиме

Мы можем получать обновления местоположения в фоновом режиме двумя способами.

1. Live Activity

  • Live Activity отображает актуальную информацию из вашего приложения, позволяя людям сразу же увидеть ход выполнения действия, события или задачи.
  • Пока Live Activity остается активной, приложение может получать обновления без дополнительных настроек.

2. CLBackgroundActivitySession

  • Многие приложения не имеют Live Activity. В этом случае мы можем использовать CLBackgroundActivitySession.
  • Она не только обеспечивает обновление местоположения в фоновом режиме, но и помогает отслеживать такие события, как геозонирование, с помощью CLMonitor.
  • Для использования CLBackgroundActivitySession нам нужно инстанцировать его объект, чтобы начать новую сессию.
  • Также необходимо убедиться в том, что мы удерживаем объект, поскольку его удаление автоматически аннулирует сессию, что может привести к прекращению доступа приложения к фоновому получению данных о местоположении.
  • После инстанцирования объекта мы присваиваем его любой глобальной переменной, чтобы он не мог быть деаллоцирован даже в случае завершения скоупа.
  • Когда мы захотим прекратить обновление местоположения, мы можем просто вызвать .invalidate() для свойства, в котором мы разместили CLBackgroundActivitySession.
// CLBackgroundActivitySession in action
import CoreLocation

private var backgroundActivity: CLBackgroundActivitySession?

func startLocationUpdates() {
    // Take background location permissions before
    Task {
        do {
            // Assign the CLBackgroundActivitySession to global var
            self.backgroundActivity = CLBackgroundActivitySession()
            
            let updates = CLLocationUpdate.liveUpdates()
            for try await update in updates {
             ...
            }
        } catch {
            debugPrint("Some Error Occured")
        }
    }
}

func stopBackgroundLocation() {
    // to stop the background updates
    self.backgroundActivity?.invalidate()
}

Жизненный цикл приложения

1. Переход из фонового состояния в приостановленное

Оптимизируем обновление местоположения с помощью CLLocationUpdate в Swift

  • Как уже говорилось, этот новый класс может предоставлять обновления местоположения в фоновом режиме и приостанавливать обновление, когда пользователь неподвижен.
  • Когда приложение находится в фоновом режиме, а обновления местоположения не запускаются, оно может перейти из фонового состояния в приостановленное (это также может быть связано с нехваткой ресурсов).
  • Интересно то, что класс CLLLocationUpdate не может оставлять приложение в приостановленном состоянии.
  • Как только обновления местоположения станут доступны, он отменит приостановку приложения и перейдет обратно в фоновое состояние. А нам не нужно писать никакой код для продолжения обновления местоположения.

2. Что делать, если приложение завершено

Оптимизируем обновление местоположения с помощью CLLocationUpdate в Swift

  • CLLocationUpdate может восстановить приложение, даже если оно завершено и не запущено. Он начнет предоставлять обновления местоположения, как только они станут доступны, и приложение будет перезапущено в фоновом режиме.
  • В этом случае приложение перейдет из завершенного в работающее в фоновом режиме.
  • Но когда приложение будет завершено, нам нужно выполнить несколько шагов, чтобы запустить обновления местоположения.
  • Во-первых, нужно вызвать CLLocationUpdate.liveUpdates(). Также нам нужно воссоздать CLBackgroundActivitySession.
  • Когда приложение находится в фоновом режиме и ему нужно продолжать получать обновления местоположения, оно может присоединиться к существующей CLBackgroundActivitySession. Пересоздав CLBackgroundActivitySession, приложение может подключиться к уже запущенному сеансу, гарантируя, что фоновые обновления местоположения будут поступать без перерыва.
  • Чтобы приложение могло повторно подключиться к существующей CLBackgroundActivitySession при запуске в фоновом режиме, воссоздание необходимых объектов должно быть помещено в метод, который выполняется во время фонового запуска приложения. Одним из подходящих мест является метод didFinishLaunchingWithOptions делегата приложения, который вызывается, когда приложение завершает запуск, независимо от того, было ли оно запущеноявно или в фоновом режиме.

Вывод

Оптимизируем обновление местоположения с помощью CLLocationUpdate в Swift

Демонстрация получения обновлений местоположения с помощью класса CLLocationUpdate

Заключение

Класс CLLocationUpdate, представленный на WWDC 23, это значительный шаг вперед для разработчиков, работающих с данными о местоположении в Swift. Используя современные функции параллелизма, он упрощает процесс получения и управления обновлениями местоположения, что приводит к созданию более чистого, читабельного и эффективного кода. Примите этот новый подход и оптимизируйте свои приложения на основе данных о местоположении в Swift!

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Advertisement

Наши партнеры:

LEGALBET

Мобильные приложения для ставок на спорт
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: