iOS主屏幕Widget应用终止时更新内容的可行方案求解
背景
- 正在开发一款显示字符串的简单Widget
- 希望每日从服务器获取数据更新该字符串(仅需用服务器数据更新Widget,无其他偏好)
- 主应用采用Flutter开发,Widget为iOS原生实现
- 核心问题:未找到应用终止(从应用切换器划走)时获取服务器数据并更新Widget的可行方案
本人接受Flutter、iOS原生或混合解决方案。
已尝试方案
使用Workmanager包
在Flutter中尝试调度周期性任务从Firebase获取数据,Android端运行正常,但根据文档,iOS不支持周期性任务,仅支持单次任务。
通过Firebase Cloud Messaging发送通知或静默通知
在Flutter中尝试使用firebaseMessagingBackgroundHandler,但根据文档:
On iOS, if the user swipes away the application from the app switcher, it must be manually reopened for background messages to start working again
实际测试符合该描述:Android端可正确处理并达成预期效果,但iOS端无法实现。
测试结果
- 前台状态:Android和iOS均可正确接收并处理通知(推送和静默)
- 后台或终止状态:Android和iOS均可显示推送通知,但无法处理通知内容并更新Widget
Python Google Cloud Function 代码
# Imports import firebase_admin from firebase_admin import messaging # Regular Push Notification title = 'Title Text' body = 'Notification Body' regular_message = messaging.Message( notification=messaging.Notification( title=title, body=body ), token=token, ) # Send regular push notification regular_response = messaging.send(regular_message) # Silent Push Notification textA = 'Title Text' textB = 'Notification Body' silent_message = messaging.Message( data={ 'textA': textA, 'textB': textB, 'content_available': '1', }, token=token, ) # Send silent notification silent_response = messaging.send(silent_message)
Flutter FirebaseMessaging 代码
Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); //Setup FCM await setupFirebaseCloudMessaging(); //Set up background message handler FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); runApp(MyApp()); } Future<void> setupFirebaseCloudMessaging() async { try { // Request FCM permission final messaging = FirebaseMessaging.instance; final settings = await messaging.requestPermission(provisional: true); print('Permission granted: ${settings.authorizationStatus}'); //Register with FCM // It requests a registration token for sending messages to users from your App server or other trusted server environment. String? token = await messaging.getToken(); if (token != null) { print('Registration Token=$token'); await persistToken(token); } // Set up foreground message handler FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (message.data.containsKey('content_available') && message.data['content_available'] == '1') { // Silent Notification (Data-only) print('Handling silent notification'); // Access data from the data payload String textA = message.data['textA']; String textB = message.data['textB']; // Uses HomeWidget package to store in user defaults updateWidget(textA, texB); } else { // Regular Push Notification print('Handling regular push notification'); // Add the message to the stream for normal notification _messageStreamController.sink.add(message); } }); } catch (e) { print('Error setting up FCM: $e'); } } Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { if (message.data.containsKey('content_available') && message.data['content_available'] == '1') { // Silent Notification (Data-only) print('Handling silent notification'); // Access data from the data payload String textA = message.data['textA']; String textB = message.data['textB']; // Uses HomeWidget package to store in user defaults updateWidget(textA, texB); } else { // Regular Push Notification print('Handling regular push notification'); } }
期望
了解到iOS对终止或后台状态下的应用有诸多(刻意设置的)限制,但仍有许多应用可在应用终止时用服务器数据更新主屏幕Widget,现求可行方案,不限Flutter或原生实现。
已查阅的资料
- Flutter FCM接收相关文档
- Flutter Workmanager iOS配置文档
- FlutterFire项目相关Issue
- Apple官方远程通知后台更新文档
- Stack Overflow:Flutter FCM在iOS应用终止时无法处理消息
- Stack Overflow:Flutter在iOS应用终止时获取数据
- Stack Overflow:iOS推送通知与AppDelegate方法行为
- 其他大量相关内容
内容的提问来源于stack exchange,提问作者Recurring Value
相关产品推荐
相关产品推荐

