トラッキングのリクエストはアプリがActive状態になってから呼び出さないと表示されない。
Calls to the API only prompt when the application state is UIApplicationStateActive.
https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/requesttrackingauthorization(completionhandler:)
アプリ起動直後にリクエスト行う場合、AppDelegateクラスが元々ある場合はdidFinishLaunchingWithOptions
に直接定義することが多いと思う。
しかしAppDelegateがない場合はSwiftUIのView内の.onAppear
や.task
に定義しようと考えてしまうが、それだとリクエストのAlertが表示されない。
というのも、.onAppear
の次に.task
が呼ばれ、その後にアプリがActive状態になるためである。
import SwiftUI
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
EmptyView()
.onAppear {
print("onAppear")
}
.task {
print("task")
}
.onChange(of: scenePhase) {
if scenePhase == .active {
print("active")
}
}
}
}
↓実行結果
なので.onAppear
, task
にリクエストを定義しても、まだActive状態になっていないのでアラートが表示されない。
ということでscenePhaseがactiveになったタイミングでリクエストすればいい。
import SwiftUI
import AppTrackingTransparency
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
EmptyView()
.onChange(of: scenePhase) {
if scenePhase == .active {
Task {
guard ATTrackingManager.trackingAuthorizationStatus == .notDetermined else { return }
_ = await ATTrackingManager.requestTrackingAuthorization()
}
}
}
}
}
自分も.onAppear
や.task
に定義して少しだけ遅延させて表示させていたが、上記の方法が正しそう。
あとSwift6でrequestTrackingAuthorization
のcompletionの方を呼ぶとクラッシュするというのを見たが、クロージャ内で@Sendableを付与すると回避できる。でも普通にasyncの方を使うので良さそう。
ATTrackingManager.requestTrackingAuthorization { @Sendable status in
print(status)
}
Views: 2