WWDC Quick Look 💓 By SwiftGGTeam
What's new in privacy

What's new in privacy

元の動画を見る

ハイライト

iOS 17 で Photos Picker の完全埋め込みモード、macOS Sonoma で SCContentSharingPicker 画面共有ピッカー、Oblivious HTTP プロトコルによるユーザー IP 保護、Sensitive Content Analysis フレームワークによるデバイス上 ML によるセンシティブコンテンツ検出、visionOS の空間入力モデルによるプロセス分離でアプリが視線データを取得できない設計が導入されました。

主要内容

Photos Picker: ユーザーが共有したい写真だけを共有

以前、アプリがユーザーの写真を取得するには、フォトライブラリ全体の権限をリクエストするか、独自の写真選択 UI を実装する必要がありました。iOS 17 の Photos Picker はアプリ内に完全に埋め込め、アプリの一部のように見えますが実際はシステムがレンダリングします。ユーザーが選択した写真のみアプリと共有され、それ以外は常にユーザーの管理下にあります。

3 つの埋め込みモード:

  • 装飾なしフルスクリーン: 最もシンプル、システム chrome なし
  • 単一行の横スクロール: スペースが限られた場所に適する
  • インライン完全ピッカー: オプションメニュー付き、タイトルや位置などのメタデータ共有を制御可能

iOS 17 では完全フォトライブラリ権限ダイアログも再設計され、写真数とサンプルプレビューを表示します。システムは定期的にどのアプリが完全ライブラリアクセスを持つかユーザーを通知します。

Screen Capture Picker: macOS 画面共有の過剰権限を解消

以前、macOS のビデオ会議アプリは完全な画面録画権限が必要で、一度許可するとアプリは画面全体を録画できました。macOS Sonoma では SCContentSharingPicker が導入され、アプリは録画権限を取得せず、システムがウィンドウ選択を表示し、ユーザーが共有するウィンドウや画面を明示的に選択した後にのみ共有されます。

macOS Sonoma ではメニューバーに画面共有アイコンも追加され、録画中のアプリをユーザーに通知します。タップで共有内容をプレビューし、ウィンドウの追加・削除、共有終了が可能です。

カレンダー権限: 最小必要原則

アプリがカレンダーイベントの作成のみ必要な場合、EventKitUI を使用すれば権限は不要です。カスタム UI が必要な場合は新しい write-only 権限をリクエストし、イベント追加のみ可能で既存イベントは読み取れません。完全アクセスが必要な場合にアップグレードをリクエストします。

カレンダーアクセスを許可済みのアプリは iOS 17 にアップグレードするとデフォルトで write-only にダウングレードされます。旧版 EventKit にリンクしたアプリは権限リクエスト時に write-only のみ付与され、読み取りを試みると自動でアップグレードダイアログが表示されます。

Oblivious HTTP: ユーザー IP アドレスの保護

ネットワーク事業者はユーザーがどのサーバーに接続したかを観察し、個人のアプリ使用パターンを推測できます。Oblivious HTTP(OHTTP)は標準化されたプロトコルで、中継サーバーにより「誰が」と「何にアクセスしたか」を分離します。

中継サーバーはユーザーの IP と宛先サーバー名を知りますが、暗号化されたコンテンツは見えません。宛先サーバーは中継から転送されたリクエストを受け取り、元の IP は見えません。単一ノードが送信元 IP、宛先 IP、コンテンツを同時に持つことはありません。iCloud Private Relay はすでに OHTTP で全 DNS クエリを保護しています。

Sensitive Content Analysis: デバイス上の児童保護

Communication Safety は Messages から AirDrop、FaceTime ボイスメール、電話連絡先ポスター、Photos Picker に拡張されました。同時に Sensitive Content Warning も全年齢向けに導入されました。

新しい SensitiveContentAnalysis フレームワークにより、開発者もアプリ内でセンシティブコンテンツを検出できます。システム提供のデバイス上 ML モデルを使用し、コンテンツをサーバーにアップロードする必要はありません。

macOS アプリデータ保護

macOS Sonoma ではアプリデータコンテナの保護が追加されました。同一開発者チーム内のアプリは互いのデータにアクセスできますが、他の開発者のアプリはユーザー認可が必要です。App Sandbox のアプリは自動的にこの保護を取得します。

NSDataAccessSecurityPolicy を Info.plist で設定し、どのプロセスがアプリデータにアクセスできるかをより厳格に指定できます。

CloudKit エンドツーエンド暗号化

Advanced Data Protection は iCloud の大部分のデータにエンドツーエンド暗号化を提供します。CloudKit アプリは暗号化データ型(EncryptedString など)を使用し、encryptedValues API で読み書きするだけで、自動的にエンドツーエンド暗号化を取得できます。

Safari プライベートブラウジングの強化

Safari 17 のプライベートブラウジングには 2 つの保護が追加されました:

  • 既知のトラッキングとフィンガープリントリソースの読み込みをブロック
  • URL からトラッキングパラメータを自動除去し、非識別部分は保持

Private Click Measurement もプライベートブラウジングに対応し、個人追跡なしで広告アトリビューションが可能になりました。

visionOS 空間入力のプライバシー設計

視線とジェスチャーデータは分離されたシステムプロセスで処理され、アプリは最終的なタップイベントのみ受け取ります。システムは画面コンテンツと視線位置を組み合わせてホバーハイライトを計算し、このハイライトはレンダリングエンジンに追加されるため、アプリはユーザーがどこを見ているかわかりません。新しい権限は不要で、既存の UIKit/SwiftUI/RealityKit アプリがそのまま動作します。

詳細

Photos Picker の埋め込み

03:58

import PhotosUI

struct PhotoPickerView: View {
    @State private var selectedItems: [PhotosPickerItem] = []
    
    var body: some View {
        PhotosPicker(
            selection: $selectedItems,
            matching: .images,
            photoLibrary: .shared()
        ) {
            Text("Select Photos")
        }
    }
}

キーポイント:

  • PhotosPicker は SwiftUI ネイティブビューで完全に埋め込み可能
  • フォトライブラリ権限は不要
  • matching パラメータで写真、動画、Live Photo をフィルタ可能
  • 選択されたコンテンツは PhotosPickerItem で非同期読み込み

Screen Capture Picker(macOS)

06:18

import ScreenCaptureKit

let picker = SCContentSharingPicker.shared

// picker を設定
let configuration = SCContentSharingPickerConfiguration()
configuration.allowsChangingSelectedContent = true

picker.setConfiguration(configuration, for: myAppBundleID)
picker.add(myContentSharingPickerObserver)
picker.isActive = true

// ユーザーが内容を選択した後、delegate 経由でコールバックを受け取る
func contentSharingPicker(
    _ picker: SCContentSharingPicker,
    didUpdateWith filter: SCContentFilter,
    forStreamID streamID: String
) {
// filter を使って SCStream を作成し、録画を開始
}

キーポイント:

  • SCContentSharingPicker.shared でシステム共有ピッカーを取得
  • アプリは画面録画権限をリクエストする必要がない
  • ユーザーが共有コンテンツを明示的に選択した後にのみ録画可能
  • メニューバーアイコンが録画中のアプリを継続的に通知

Sensitive Content Analysis

16:00

import SensitiveContentAnalysis

// 画像を解析
let analyzer = SCSensitivityAnalyzer()
let policy = analyzer.analysisPolicy

// ファイル URL 経由で解析
let imageResult = try await analyzer.analyzeImage(at: imageURL)

// または CGImage 経由で解析
let cgImageResult = try await analyzer.analyzeImage(image.cgImage!)

// 動画を解析
let handler = analyzer.videoAnalysis(forFileAt: videoURL)
let videoResult = try await handler.hasSensitiveContent()

if videoResult.isSensitive {
// policy に基づいて介入方法を決定
    intervene(based: policy)
}

func intervene(based policy: SCSensitivityAnalysisPolicy) {
    switch policy {
    case .communicationSafety:
// 子ども保護モード: 警告とリソースを表示
        showCommunicationSafetyIntervention()
    case .sensitiveContentWarning:
// センシティブ内容の警告: ぼかし処理し、ユーザーが表示を選択可能
        showSensitiveContentWarning()
    default:
        break
    }
}

キーポイント:

  • SCSensitivityAnalyzer はシステムのデバイス上 ML モデルを使用
  • analysisPolicy は現在のシステム設定のポリシータイプを返す
  • analyzeImage(at:)analyzeImage(_:) で静止画を分析
  • videoAnalysis(forFileAt:) はハンドラを返し、進捗追跡とキャンセルが可能
  • isSensitive が true の場合、介入 UI(ぼかし + オプション表示)を提供

カレンダー Write-only 権限

08:30

import EventKit

let store = EKEventStore()

// iOS 17 で write-only 権限が追加
do {
    let granted = try await store.requestWriteOnlyAccessToEvents()
    if granted {
// イベントの追加のみ可能で、読み取りは不可
        let event = EKEvent(eventStore: store)
        event.title = "Team Meeting"
        event.startDate = Date()
        event.endDate = Date().addingTimeInterval(3600)
        try store.save(event, span: .thisEvent)
    }
} catch {
    print("Access denied: \(error)")
}

キーポイント:

  • requestWriteOnlyAccessToEvents() は iOS 17 で追加
  • 新規イベントの作成のみ可能、既存イベントの読み取り・変更・削除は不可
  • 許可済みアプリは iOS 17 アップグレード後デフォルトで write-only にダウングレード
  • 完全アクセスが必要な場合、システムが自動でアップグレードダイアログを表示

CloudKit エンドツーエンド暗号化

22:15

import CloudKit

// 暗号化フィールドを使うレコードを作成
let record = CKRecord(recordType: "Note")

// encryptedValues API で暗号化データを書き込む
record.encryptedValues["title"] = "My Secret Note"
record.encryptedValues["content"] = "This is encrypted end-to-end"

// CloudKit に保存
let database = CKContainer.default().privateCloudDatabase
try await database.save(record)

// 読み取り時に自動復号
let fetchedRecord = try await database.record(for: record.recordID)
let decryptedTitle = fetchedRecord.encryptedValues["title"] as? String
let decryptedContent = fetchedRecord.encryptedValues["content"] as? String

キーポイント:

  • 通常フィールドではなく encryptedValues API を使用
  • CloudKit スキーマで EncryptedString などの暗号化データ型を使用
  • Advanced Data Protection 有効化後、自動的にエンドツーエンド暗号化を取得
  • キー管理、暗号化操作、復旧フローの管理は不要

App Sandbox データ保護(macOS)

<!-- Info.plist -->
<key>NSDataAccessSecurityPolicy</key>
<dict>
    <key>NSAllowList</key>
    <array>
        <string>com.mycompany.messenger</string>
        <string>com.mycompany.notes</string>
    </array>
</dict>

キーポイント:

  • デフォルトでは同一 Team ID のアプリが互いのデータコンテナにアクセス可能
  • NSDataAccessSecurityPolicy で明示的な許可リストに置き換え可能
  • リスト外のアプリはデータアクセス時にユーザー認可が必要
  • アプリ終了時に権限はリセット

重要ポイント

1. プライバシー優先の写真共有アプリ

  • 何を作るか: ユーザーが特定の写真を友人と共有でき、アプリは他の写真を一切見られない
  • なぜ価値があるか: Photos Picker は完全埋め込みでフォトライブラリ権限不要、ユーザーの信頼度が非常に高い
  • 始め方: PhotosPicker を埋め込み、PhotosPickerItem で選択コンテンツを読み込み、PHPhotoLibrary は一切使用しない

2. 安全な匿名ユーザーフィードバックシステム

  • 何を作るか: アプリ使用統計とクラッシュレポートを収集するが、サーバーは特定ユーザーと関連付けできない
  • なぜ価値があるか: OHTTP がユーザー IP とコンテンツを分離し、真の匿名分析を実現
  • 始め方: OHTTP 中継サーバーを構築し、アプリは中継経由で分析データを送信、サーバーは匿名化された統計のみ受信

3. 児童安全なソーシャルアプリ

  • 何を作るか: チャットや画像共有前にセンシティブコンテンツを自動検出し、未成年ユーザーを保護
  • なぜ価値があるか: SensitiveContentAnalysis はデバイス上で処理、サーバーへのアップロード不要、プライバシー規制に準拠
  • 始め方: 画像送信前に analyzer.analyzeImage() を呼び出し、analysisPolicy に基づき適切な介入 UI を表示

4. ゼロ権限スケジュール管理プラグイン

  • 何を作るか: ウェブページやメールからイベント情報を認識し、ワンタップでシステムカレンダーに追加
  • なぜ価値があるか: write-only カレンダー権限でユーザーは安心—アプリは追加のみで既存スケジュールを覗けない
  • 始め方: ウェブページのイベント情報を解析し、requestWriteOnlyAccessToEvents() でイベント追加、既存スケジュールの読み取りは不要

関連セッション

コメント

GitHub Issues · utterances