Flutter iOS中如何先请求追踪透明权限再请求通知权限
问题:调整App追踪授权与通知弹窗的顺序
每次启动App时,通知授权弹窗总是比App追踪授权弹窗先出现,我希望用户先看到App Tracking Transparency授权弹窗,再看到通知授权弹窗。我尝试过在runApp()前后、推送通知请求代码await PushNotificationService().setupInteractedMessage();之前调用await AppTrackingTransparency.requestTrackingAuthorization();,也已在info.plist中添加了对应的权限键,但弹窗顺序还是未改变。
用户提供的代码:
int? initScreen; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // await Firebase.initializeApp(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); // runApp(MyApp()); SharedPreferences preferences = await SharedPreferences.getInstance(); initScreen = await preferences.getInt('initScreen'); await preferences.setInt('initScreen', 1); // MobileAds.instance.initialize(); runApp(MyApp()); //await AppTracking // final status = await AppTrackingTransparency.requestTrackingAuthorization(); await AppTrackingTransparency.requestTrackingAuthorization(); await PushNotificationService().setupInteractedMessage(); MobileAds.instance.initialize(); RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) { // App received a notification when it was killed } } class MyApp extends StatelessWidget { // This widget is the root of your application. // final TrackingStatus status; // // MyApp({required this.status}); static FirebaseAnalytics analytics = FirebaseAnalytics.instance; static FirebaseAnalyticsObserver observer = new FirebaseAnalyticsObserver(analytics: analytics); @override Widget build(BuildContext context) { // String statusText; // switch (status) { // case TrackingStatus.authorized: // statusText = 'Tracking Status Authorized'; // break; // case TrackingStatus.denied: // statusText = 'Tracking Status Denied'; // break; // case TrackingStatus.notDetermined: // statusText = 'Tracking Status Not Determined'; // break; // case TrackingStatus.notSupported: // statusText = 'Tracking Status Not Supported'; // break; // case TrackingStatus.restricted: // statusText = 'Tracking Status Restricted'; // break; // default: // statusText = 'You should not see this...'; // break; // } return GetMaterialApp( debugShowCheckedModeBanner: false, title: 'Culture Islamique', theme: ThemeData( primarySwatch: Colors.blue, ), // home: initialRoute: initScreen == 0 || initScreen == null ? 'onboard' : 'home', routes: { 'home': (context) => navbar(analytics: analytics, observer: observer), 'onboard': (context) => onboardingHomePage(), }, ); } }
弹窗顺序截图:
解决方案
问题出在main函数中,runApp()之后执行的异步操作会与App的UI初始化逻辑并行,导致推送通知的权限请求可能提前触发,无法保证顺序。正确的做法是将权限请求移到页面的初始化生命周期中,严格控制先后顺序:
- 修改main函数:移除
runApp()之后的追踪授权和通知服务初始化代码,确保App先完成UI启动:
int? initScreen; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); SharedPreferences preferences = await SharedPreferences.getInstance(); initScreen = await preferences.getInt('initScreen'); await preferences.setInt('initScreen', 1); MobileAds.instance.initialize(); RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) { // 处理App被杀状态下收到的通知 } runApp(MyApp()); }
- 在首个加载的页面中添加权限请求逻辑:比如在引导页
onboardingHomePage或首页navbar的initState中,先请求追踪授权,等待用户处理完毕后再请求通知权限:
class onboardingHomePage extends StatefulWidget { const onboardingHomePage({Key? key}) : super(key: key); @override State<onboardingHomePage> createState() => _onboardingHomePageState(); } class _onboardingHomePageState extends State<onboardingHomePage> { @override void initState() { super.initState(); _requestPermissionsInOrder(); } Future<void> _requestPermissionsInOrder() async { // 先请求App追踪授权 await AppTrackingTransparency.requestTrackingAuthorization(); // 再初始化推送通知服务(内部包含通知权限请求) await PushNotificationService().setupInteractedMessage(); } @override Widget build(BuildContext context) { // 页面原有代码 return ...; } }
原理说明
将权限请求移到页面的initState中,能保证在UI渲染完成后,严格按照代码顺序执行异步操作:必须等用户处理完追踪授权弹窗,才会触发通知权限请求,从而实现预期的弹窗顺序。
内容的提问来源于stack exchange,提问作者Taoufik
相关产品推荐
相关产品推荐

