67 lines
2.5 KiB
Dart
67 lines
2.5 KiB
Dart
import 'package:blind_master/BlindMasterResources/secure_transmissions.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
/// Bridge to the native iOS APNs registration in `ios/Runner/AppDelegate.swift`.
|
|
/// The Swift side captures the device token in
|
|
/// `didRegisterForRemoteNotificationsWithDeviceToken`, hex-encodes it, and
|
|
/// pushes it back here over the `blindmaster/apns` MethodChannel. We then POST
|
|
/// it to `/register_apns_token` so the server can target this device.
|
|
///
|
|
/// Mirrors the LockInBroMobile NotificationService flow — Android has no APNs
|
|
/// equivalent and the backend only supports APNs, so this is a no-op there.
|
|
class ApnsService {
|
|
static const _channel = MethodChannel('blindmaster/apns');
|
|
static bool _handlerInstalled = false;
|
|
|
|
/// Wire the channel handler once at startup so a token delivered before the
|
|
/// first `register()` call (or after, asynchronously) is still uploaded.
|
|
static void install() {
|
|
if (_handlerInstalled) return;
|
|
if (defaultTargetPlatform != TargetPlatform.iOS &&
|
|
defaultTargetPlatform != TargetPlatform.macOS) {
|
|
return;
|
|
}
|
|
_handlerInstalled = true;
|
|
_channel.setMethodCallHandler((call) async {
|
|
if (call.method == 'onToken') {
|
|
final token = call.arguments as String?;
|
|
if (token == null || token.isEmpty) return;
|
|
debugPrint('APNS: token received');
|
|
try {
|
|
await securePost({'token': token}, 'register_apns_token');
|
|
} catch (e) {
|
|
debugPrint('APNS: token upload failed: $e');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/// Request notification permission and upload the cached token if APNs has
|
|
/// already produced one. Safe to call repeatedly (login + session-restore) —
|
|
/// the server upserts.
|
|
static Future<void> register() async {
|
|
if (defaultTargetPlatform != TargetPlatform.iOS &&
|
|
defaultTargetPlatform != TargetPlatform.macOS) {
|
|
return;
|
|
}
|
|
install();
|
|
try {
|
|
final granted =
|
|
await _channel.invokeMethod<bool>('requestPermission') ?? false;
|
|
if (!granted) {
|
|
debugPrint('APNS: notifications denied — enable in Settings');
|
|
return;
|
|
}
|
|
final token = await _channel.invokeMethod<String?>('getToken');
|
|
if (token == null || token.isEmpty) {
|
|
debugPrint('APNS: token not ready yet — onToken handler will catch it');
|
|
return;
|
|
}
|
|
await securePost({'token': token}, 'register_apns_token');
|
|
} catch (e) {
|
|
debugPrint('APNS registration failed: $e');
|
|
}
|
|
}
|
|
}
|