fix(push): register APNs and VoIP tokens on iOS

The local notifications plugin was initialised without iOS settings, so
flutter_local_notifications threw "iOS settings must be set" before the
app registered with Apple, and restoreMode swallowed the error. iPhones
never sent the relay an APNs token for message wake-ups or a VoIP token
for calls.

- add DarwinInitializationSettings and request iOS permission explicitly
- register with Apple before asking for notification permission (silent
  wake-ups do not need it)
- send the VoIP token on its own (PLATFORM_APNS with an empty endpoint)
  when no APNs token is available yet
- record a failed registration so the chat list shows it instead of
  failing silently
- drop the force cast of rootViewController in AppDelegate and the unused
  SceneDelegate
This commit is contained in:
Julius Joska
2026-10-23 10:51:02 +02:00
parent 717aeed4ff
commit 59992af778
6 changed files with 246 additions and 46 deletions
+15 -1
View File
@@ -27,6 +27,14 @@ class PushNotifier {
await _plugin.initialize(
InitializationSettings(
android: const AndroidInitializationSettings('@mipmap/ic_launcher'),
// Bez iOS nastavení plugin hodí ArgumentError a s ním padala celá
// APNs registrace — iPhony relayi neposlaly token vůbec. O oprávnění
// se žádá až v [requestPermission], ne při první notifikaci.
iOS: const DarwinInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
),
linux: LinuxInitializationSettings(
defaultActionName: l10n.pushActionOpen,
),
@@ -48,17 +56,23 @@ class PushNotifier {
priority: Priority.high,
category: AndroidNotificationCategory.message,
),
iOS: const DarwinNotificationDetails(),
linux: const LinuxNotificationDetails(),
);
}
/// Android 13+ runtime permission — volat při zapnutí pushe v nastavení.
/// Oprávnění k viditelným notifikacím (Android 13+, iOS) — volat při
/// zapnutí pushe. Tichý budíček na iOS ho nepotřebuje.
static Future<void> requestPermission() async {
await _ensureInit();
await _plugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
await _plugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(alert: true, badge: true, sound: true);
}
/// Notifikace o přijaté zprávě, když appka běží, ale není v popředí.