WWDC Quick Look 💓 By SwiftGGTeam
Discover streamlined location updates

Discover streamlined location updates

元の動画を見る

ハイライト

iOS 17で導入されたコアロケーションCLLocationUpdateクラスでは 1 行を使用しますfor try awaitこのコードは従来のデリゲート モードを置き換え、Swift 同時実行をネイティブにサポートし、電力を節約するための自動一時停止/再開メカニズムが組み込まれています。

主要内容

以前は、位置情報の更新を取得するには、次のような大量のコードを記述する必要がありました。CLLocationManager、デリゲートの設定、実装didUpdateLocations、手動呼び出しstartUpdatingLocation()そしてstopUpdatingLocation()。コードは複数のメソッドに分散しており、状態管理は複雑で、バックグラウンドのキープアライブと電力の最適化を自分で処理する必要があります。

アップルが今年発売CLLocationUpdate、すべてを 1 行のコードに圧縮します。を返しますAsyncSequence、直接使用しますfor try await移動することで位置情報の最新情報を取得できます。デリゲートは必要なく、手動での開始と停止も必要なく、コードは分散コールバックから線形逐次ロジックに変わります。

さらに重要なのは、自動一時停止/再開です。デバイスが一定期間静止していると、システムは自動的にアップデートを一時停止し、isStationary == trueマーク。デバイスを再度移動すると自動的に再開します。これにより、開発者が自分で休止状態を判断する手間が省け、バックグラウンドでのウェイクアップの回数も減ります。

背景シーンも簡略化されています。アプリにライブ アクティビティがある場合、バックグラウンドでの位置情報の更新が自動的に有効になります。そうでない場合は作成してくださいCLBackgroundActivitySessionバックグラウンド機能を維持することができ、システムは青色の位置インジケーターバーを表示してユーザーに知らせます。

詳細

CLLocationUpdate の基本的な使用法

(00:27) 位置情報の更新に必要なコードは 1 行だけになりました。

import CoreLocation

for try await update in CLLocationUpdate.liveUpdates() {
    print("My current location: \(update.location)")
}

キーポイント:

  • CLLocationUpdate.liveUpdates()戻るAsyncSequence、サポートfor try await- それぞれupdate含むlocation: CLLocation?そしてisStationary: Bool
  • locationのためにnil現在利用可能な場所がないことを示します。これは、更新の停止とは異なります。 -isStationaryのためにtrueデバイスが静止している場合は、次のことができます。breakループから抜け出して更新を停止する

デフォルト構成を使用する

04:41liveUpdates()オプションを受け入れるLiveConfigurationパラメータ:

for try await update in CLLocationUpdate.liveUpdates(.fitness) {
    print("Location: \(update.location)")
}

LiveConfiguration次のプリセットが含まれています。 -.default—デフォルト設定 -.automotiveNavigation— カーナビ -.otherNavigation— その他のナビゲーション -.fitness— スポーツとフィットネス -.airborne— 航空

これらは古いものに対応しますCLActivityType、同じ位置精度エクスペリエンスを得るには、移行中に対応する構成を選択します。

AsyncSequence のフィルタリング機能

(03:17) が返されましたUpdatesはいAsyncSequence、フィルタリング操作を直接使用できます。

let fastUpdate = try await CLLocationUpdate.liveUpdates()
    .first { update in
        guard let speed = update.location?.speed else { return false }
        return speed > 200  // 200 米/秒,约 447 英里/小时
    }

キーポイント:

  • firstフィルタリング操作は条件が一致するまでブロックされます
  • マッチング成功後AsyncSequence自動的に終了するため、手動で停止する必要はありません
  • に基づいてhorizontalAccuracyフィルタリングには注意してください、長時間マッチングできない可能性があります

バックグラウンドでの位置情報の更新

(06:04) 最良の方法は、ライブ アクティビティを使用することです。ライブ アクティビティがアクティブである限り、アプリは追加の構成を行わなくても、バックグラウンドで位置情報の更新を受信できます。

ライブアクティビティがない場合は、を使用しますCLBackgroundActivitySession

class LocationManager {
    var backgroundActivity: CLBackgroundActivitySession?

    func startBackgroundUpdates() {
        // 必须赋值给属性,不能用局部变量
        backgroundActivity = CLBackgroundActivitySession()

        Task {
            for try await update in CLLocationUpdate.liveUpdates() {
                print("Location: \(update.location)")
                if update.isStationary {
                    break
                }
            }
        }
    }

    func stop() {
        backgroundActivity?.invalidate()
        backgroundActivity = nil
    }
}

キーポイント:

  • CLBackgroundActivitySession参照を保持する必要があります。dealloc は自動的に無効化します
  • アプリUIBackgroundModesまだ含める必要があるlocation- 新しいセッションはフォアグラウンドからのみ開始でき、既存のセッションはバックグラウンドでのみ再参加できます。

自動一時停止と再開

(09:19) デバイスが静止している場合、システムは自動的に更新を一時停止します。

  1. デバイスが長時間静止したままになる → 自動一時停止がトリガーされます 2.送信isStationary = true更新、場所は nil ではありません
  2. デバイスを再度移動 → 自動復帰 4.送信isStationary = false位置情報の配信を継続するためのアップデート

これにより、アプリ自体が静止状態を判断する必要がなくなり、冗長な位置データの処理が回避されます。

アプリのライフサイクルとリカバリ

(10:39) バックグラウンド実行中に、アプリは次の状態の間で切り替わる場合があります。

  • フォアグラウンド動作→バックグラウンド動作:通常遷移
  • バックグラウンドで実行 → ハング: アップデートを配信できない場合に自動的に発生します
  • 一時停止→バックグラウンド: アップデートが利用可能になると自動的に再開されます。アクションは必要ありません。
  • バックグラウンドでの実行/ハング → 終了: クラッシュ、ユーザーのシャットダウン、またはシステムのリソースのリサイクル

アプリが終了した後、位置情報の更新が利用可能になると、システムはバックグラウンドでアプリを自動的に起動します。現時点で必要なのは、application(_:didFinishLaunchingWithOptions:)復興中期liveUpdates()そしてCLBackgroundActivitySession

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 重建后台 session(这是 rejoin,不是新建)
    backgroundActivity = CLBackgroundActivitySession()

    Task {
        for try await update in CLLocationUpdate.liveUpdates() {
            handleLocationUpdate(update)
        }
    }
    return true
}

キーポイント:

  • リビルド操作はバックグラウンド起動を受信した直後に実行する必要があります。
  • バックエンドの再構築CLBackgroundActivitySessionはい、バックグラウンド起動の制限に従って既存のセッションに再参加します。

重要ポイント

1.スポーツ追跡アプリのバッテリー最適化

  • やるべきこと: を使用しますCLLocationUpdate古いものを交換するCLLocationManagerデリゲートモード
  • 実行する価値がある理由: 自動一時停止/再開メカニズムにより、デバイスが停止しているときに電力消費が停止するため、非アクティブ検出ロジックを自分で作成する必要がなくなります。
  • 開始方法:locationManager.startUpdatingLocation()と置き換えますfor try await update in CLLocationUpdate.liveUpdates(.fitness)

2.テイクアウト/タクシー配車のリアルタイムの位置情報共有

  • やるべきこと: ライダー/ドライバーのターミナルにライブ アクティビティを追加して調整しますCLLocationUpdateリアルタイムで位置情報を報告
  • 実行する価値がある理由: ライブ アクティビティを使用すると、設定なしでバックグラウンドで位置情報の更新を有効にすることができ、ユーザーはいつでもロック画面で配信の進行状況を確認できます。
  • 開始方法: まず Live Activity (ActivityKit を参照) を実装し、それからフォアグラウンドで直接開始します。CLLocationUpdate.liveUpdates()

3.ジオフェンシング + 位置追跡の組み合わせシナリオ

  • やるべきこと: を使用しますCLMonitorジオフェンス イベントを監視するには、次を使用します。CLLocationUpdateフェンスに入った後の詳細な軌跡を追跡します
  • 実行する価値がある理由: 2 つの組み合わせにより、「いつ到着したか」と「その地域で何をしたか」を正確に知ることができます。
  • 開始方法: まず、「Meet Core Location Monitor」セッションを見て理解してください。CLMonitor、そして重ね合わせますCLLocationUpdate

4.エクササイズの記録を自動的に一時停止します

  • 何をすべきか: エクスプロイトisStationaryユーザーが休憩のために立ち止まったことを自動的に検出し、録音を一時停止してプロンプトを表示します
  • 実行する価値がある理由: 以前は、速度のしきい値とタイマーを自分で管理する必要がありましたが、現在はシステムが静的な状態を直接提供します。
  • 開始方法:for try awaitチェックインループupdate.isStationary、のためにtrue録音が一時停止され、「一時停止中」と表示されます。

関連セッション

コメント

GitHub Issues · utterances