WWDC Quick Look 💓 By SwiftGGTeam
Power down: Improve battery consumption

Power down: Improve battery consumption

元の動画を見る

ハイライト

Apple のソフトウェア電力消費チームは、バッテリーの最適化を 4 つの実行可能なアクションに分類しています。ダーク モードのサポート、アニメーション フレーム レートの確認、バックグラウンドの場所とオーディオ セッションの終了、および緊急でない作業のシステムへの延期です。

主要内容

ユーザーがアプリを開いたとき、最初にそのアプリが使用する CPU の量を尋ねることはありません。ユーザーは、電話機が熱くなってすぐに電力が失われると感じるだけで、その後電話機の電源を切ります。

このセッションの入り口は簡単です。アプリは機能を提供しますが、機能はバッテリーを消費します。Apple ソフトウェア消費電力チームは、システム コンポーネントの消費電力を長年研究してきました。ここでは、開発者が直接制御できる 4 種類の変更を紹介します (00:37)。

最初の種類の変化は画面上で発生します。OLED デバイスでは、各ピクセルが個別に電力を消費し、暗いコンテンツは明るいコンテンツよりも消費電力が少なくなります。フード トラックの例では、大面積の背景が暗い色に切り替わった後、ディスプレイの消費電力を最大 70% 節約できると Apple は推定しています (02:24)。

2 番目のタイプの変化はアニメーションで発生します。ProMotion デバイスでは、画面のリフレッシュ レートは、アプリ内の最高フレーム レートのアニメーションの影響を受けます。メイン コンテンツには 30 fps のみが必要ですが、二次スクロール テキストが 60 fps に達すると、画面全体が 60 fps に引き伸ばされます。この例では、この 2 番目のアニメーションを 30fps まで遅くすると、バッテリー消費を最大 20% 節約できます (05:42)。

3 番目のタイプの変更は舞台裏で発生します。位置情報サービスと音声サービスはバックグラウンドで実行され続け、デバイスをアクティブな状態に保ちます。アプリはユーザーには見えませんが、システムは依然として電力を使用しています。セッションの原則は、システムが使用されていないときに終了するように明確に指示することです (09:21)。

4 番目のタイプの変更は、スケジュール設定で発生します。機械学習、バックアップ、テレメトリのアップロード、次のエピソードのダウンロードは、すべてすぐに行う必要はありません。デバイスが充電中、Wi-Fi に接続中、または適切な時間帯になるまでこの作業を延期すると、バッテリーの競合を減らすことができます (13:18)。

詳細

ダークモードを使用して OLED ディスプレイの消費電力を削減する

(01:24) OLED スクリーンでは、暗いピクセルほど必要な電力が少なくなります。多くの場合、ディスプレイはシステムの電力消費の最大の原因であるため、明るい色の背景が大きいアプリはダーク モードの恩恵を受ける可能性が最も高くなります。

ネイティブ アプリのアプローチは、ハードコーディングされた色を避け、代わりに動的な色を使用することで、システムがライト モードとダーク モードの間で正しい背景、テキスト、画像リソースを切り替えることができるようにすることです (03:18)。

// 概念示例:用动态颜色代替硬编码浅色背景
view.backgroundColor = UIColor.systemBackground
label.textColor = UIColor.label

キーポイント:

  • UIColor.systemBackgroundシステムの外観に応じて変化し、ダークモードでは暗い背景に変わります。
  • UIColor.label同じ動的な色により、ライト モードでもダーク モードでもテキストを読みやすく保ちます。
  • このコードは、セッションの [コード] タブの元のスニペットではなく、トランスクリプトにある「動的カラーを使用して背景、画像、テキストをサポートする」という概念例に基づいています。

(04:00) Web コンテンツも個別に処理されます。Safari は Web ページを自動的に暗くしません。Web ページにはステートメントが必要ですcolor-scheme、スタイル変数を使用して色を管理します。

:root {
  color-scheme: light dark;
  --page-background: Canvas;
  --page-text: CanvasText;
}

body {
  background: var(--page-background);
  color: var(--page-text);
}

キーポイント:

  • color-scheme: light darkデフォルトのテキスト、背景、フォーム コントロール、スクロール バーをシステムの外観に合わせます。
  • CanvasそしてCanvasTextこれはシステム カラーであり、現在の配色に応じて変更されます。
  • var(--page-background)そしてvar(--page-text)色を変数にグループ化して、異なるモードに異なる値を提供します。
  • この CSS はトランスクリプトに基づいていますcolor-schemeおよびスタイルシート変数の概念的な例。

インストゥルメントを使用して、高すぎるセカンダリ アニメーション フレーム レートを見つける

(05:11) リフレッシュ レートが高いと、消費電力が増加します。多くの場合、問題は二次的な要素にあります。メイン コンテンツは 30 fps しか必要としませんが、コーナーの装飾アニメーションは 60 fps で更新されます。

Apple は、Instruments の CoreAnimation FPS インストルメントを使用して、最初にタイムラインを確認し、必要なフレーム レートを超えるフレーム レートでレンダリングされる要素がメイン プロセスに存在するかどうかを確認することを推奨しています (06:36)。カスタム アニメーションで使用する場合CADisplayLink、システムにフレームレート範囲を与えることができます。

// Create a display link

func createDisplayLink() {
   let displayLink = CADisplayLink(target: self, selector: #selector(step))

    // Configure your desired refresh rate by calling preferredFrameRateRange
    displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: 10,
                                                           maximum: 60,
                                                           preferred: 30)

// then activate your CADisplayLink by adding it to the main runloop.
    displayLink.add(to: .current, forMode: .defaultRunLoopMode)
}

キーポイント:

  • CADisplayLink(target:selector:)表示更新と同期するタイマーを作成します。
  • #selector(step)各更新時に実行されるカスタム アニメーション ロジックを指します。
  • preferredFrameRateRange最小、最大、および優先フレーム レートをシステムに伝えます。
  • minimum: 10必要に応じてシステムが 10fps まで低下できることを示します。
  • maximum: 60このアニメーションが 60fps を超える必要がないことを示します。
  • preferred: 30コンテンツを表現するための理想的なフレーム レートは 30fps です。
  • add(to:forMode:)現在の実行ループに表示リンクを追加すると、アニメーションは更新コールバックの受信を開始します。

バックグラウンドの位置と音声: 終了したら停止します

(09:49) バックグラウンドでの位置情報により、デバイスはその位置を継続的にストリーミングします。session は、location セッションが必要なくなったときに呼び出す必要があることを明示的に示しています。stopUpdatingLocation()

// 概念示例:后台定位任务结束后停止位置更新
locationManager.stopUpdatingLocation()

キーポイント:

  • locationManagerあなたのものですCLLocationManager例。
  • stopUpdatingLocation()アプリが表示されていないときのバッテリーの消費を避けるために、永続的な位置情報の更新を終了します。
  • このコードは、トランスクリプトで直接言及されている API 呼び出しに対応します。

(10:25) トラブルシューティング方法は段階的に使用されます。開発時には、Xcode の CPU、ネットワーク、場所、エネルギー タイムラインのゲージを確認してください。MetricKitはテスト段階で使用されますcumulativeBackgroundLocationTime1 日にバックグラウンド位置を使用した累積時間を表示します。iOS 16 以降、ユーザーは現在位置情報サービスを使用しているアプリをコントロール センターで確認することもできます。

オーディオも同じ原理に従います。ユーザーが再生を停止した後、アプリはサウンドを一時停止するだけでなく、オーディオ ハードウェアのアイドリングを避けるためにオーディオ エンジンも停止または一時停止する必要があります (12:03)。

// 概念示例:让 AVAudioEngine 空闲后自动关闭音频硬件
audioEngine.autoShutdownEnabled = true

キーポイント:

  • audioEngineはいAVAudioEngine例。
  • autoShutdownEnabled有効にすると、オーディオ エンジンはアイドル ステータスを検出し続けます。
  • 一定期間アイドル状態が続くと、システムはオーディオ ハードウェアをオフにします。オーディオ ソースが再びアクティブになると、動的に再びオンになります。
  • watchOS では自動シャットダウンが必須です。

緊急でない作業はシステムのスケジュールに任せる

(13:37) セッションでは、延期できる作業を機械学習タスク、分析のアップロード、バックアップの 3 つのカテゴリに分類します。これらはユーザーの現在の操作に直接対応するものではなく、システムに任せてより適切な時間を選択することができます。

BGProcessingTaskデータベースのクリーニング、バックアップ、機械学習トレーニングなどの長期的な処理タスクに適しています。リクエストの作成時にタスク ID を指定し、外部電源またはネットワークが必要かどうかを示します。システムは適切なウィンドウでアプリを起動し、数分間バックグラウンドで実行します (14:22)。

// 概念示例:提交一个可延后的长时间处理任务
let request = BGProcessingTaskRequest(identifier: "com.app.cleanup")
request.requiresExternalPower = true
request.requiresNetworkConnectivity = false
try BGTaskScheduler.shared.submit(request)

キーポイント:

  • BGProcessingTaskRequest長期的なバックグラウンド処理リクエストを表します。
  • identifierアプリによって登録されたバックグラウンド タスク識別子と一致している必要があります。
  • requiresExternalPowerこのジョブが充電中に実行するのに適していることをシステムに伝えます。
  • requiresNetworkConnectivityこのジョブがネットワークに依存するかどうかをシステムに伝えます。
  • submitスケジュールのためにリクエストをシステムに送信します。具体的な実行時間はシステムによって決定されます。
  • このコードは、トランスクリプト内の BGProcessingTaskRequest、外部電源、およびネットワーク要件の概念的な例に基づいています。

(15:12) 遅延可能なネットワーク タスクはバックグラウンドを使用しますURLSession任意のフラグを追加します。システムは、デバイスがプラグインされて Wi-Fi に接続されているなど、より良い条件下で実行でき、ネットワーク業務がシステムに引き渡された後は、アプリを常に実行する必要はありません。

// Set up background URL session 
let config = URLSessionConfiguration.background(withIdentifier: "com.app.attachments") 
let session = URLSession(configuration: config, delegate: ..., delegateQueue: ...) 

// Set discretionary 
config.isDiscretionary = true

// Set timeout intervals
config.timeoutIntervalForResource = 24 * 60 * 60 
config.timeoutIntervalForRequest = 60 

// Create request and task 
var request = URLRequest(url: url) 
request.addValue("...", forHTTPHeaderField: "...") 
let task = session.downloadTask(with: request) 

// Set time window of two hours
task.earliestBeginDate = Date(timeIntervalSinceNow: 2 * 60 * 60) 

// Set workload size 
task.countOfBytesClientExpectsToSend = 160 
task.countOfBytesClientExpectsToReceive = 4096 

task.resume()

キーポイント:

  • URLSessionConfiguration.background(withIdentifier:)バックグラウンド URL セッション構成を作成します。
  • URLSession(configuration:delegate:delegateQueue:)この構成でセッションを作成します。
  • isDiscretionary = trueネットワーク トランザクションがシステムによってより適切な時期に延期される可能性があることを示します。
  • timeoutIntervalForResource無制限のダウンロードを避けるために、リソース全体の転送の最大時間を制限します。
  • timeoutIntervalForRequest1 つのリクエストの待ち時間を制限します。
  • URLRequest(url:)ダウンロードリクエストを作成します。
  • downloadTask(with:)バックグラウンドダウンロードタスクを作成します。
  • earliestBeginDate再起動する前に 2 時間待つようにシステムに指示することもできます。
  • countOfBytesClientExpectsToSendそしてcountOfBytesClientExpectsToReceiveシステムの負荷分散を支援するために、予想されるワークロードを提供します。
  • resume()タスクを開始します。

(16:48) プッシュには緊急レベルもあります。荒天警報は優先度が高いものに適しています。緊急ではないパッシブ通知は優先度を低くするために使用でき、デバイスがウェイクアップするまで、またはその他の適切な時間までサーバーが送信を遅らせることができます。

apns-priority: 5

キーポイント:

  • apns-priorityAPNs リクエストヘッダーです。
  • 価値5優先度の低いプッシュを示します。
  • 優先度の低いプッシュは、デバイスがスリープから復帰する回数を減らすために延期できるメッセージに適しています。

重要ポイント

  • 「バックグラウンド測位チェック」デバッグ ページを作成します: 現在の測位セッションがまだ実行中かどうか、最新の停止時間、および MetricKit の累積バックグラウンド測位時間を表示します。こうすることで、テスト段階で電話をかけ忘れたことを知ることができます。stopUpdatingLocation()パス。エントリーAPIはCLLocationManager.stopUpdatingLocation()とMetricKitcumulativeBackgroundLocationTime

  • 「ターゲット フレーム レート」構成をカスタム アニメーションに追加: 装飾アニメーション、マーキー、パーティクル エフェクトのターゲット フレーム レートを、コンテンツに必要な範囲まで下げます。まず、Instruments の CoreAnimation FPS インストルメントを使用して過剰なフレーム レートを見つけてから、CADisplayLink.preferredFrameRateRange中程度の設定preferred価値。

  • 大きなファイルのダウンロードを延期可能なタスクに変更: ポッドキャスト、ビデオ、添付ファイルのプリフェッチには、即時のネットワーク アクセスは必要ありません。背景を使用するURLSession、設定isDiscretionaryearliestBeginDateおよび予期されるバイト数を指定して、システムがプラグインまたは Wi-Fi などのより適切なウィンドウを選択できるようにします。

  • 大きな明るい背景を持つページの暗いリソースを補完します: まず、最大の画面領域を占める背景色と画像を見つけて、それを動的カラーまたはペアの画像リソースに変更します。OLED デバイスでは、暗いコンテンツが広い領域にあると、ディスプレイの消費電力が直接削減されます。

  • サーバー プッシュに優先度ルールを追加: 重大なアラームとインスタント チャットを高い優先度に保ちます。概要、推奨事項、同期リマインダーを次のように変更します。apns-priority: 5。これにより、緊急でないメッセージのためにデバイスが起動する回数が減ります。

関連セッション

コメント

GitHub Issues · utterances