Skip to content

Commit f4ffe68

Browse files
author
Franco Bugnano
committed
Started implementing push notifications for iOS
1 parent f88222d commit f4ffe68

File tree

10 files changed

+95
-12
lines changed

10 files changed

+95
-12
lines changed

examples/push_notifications/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294
"$(inherited)",
295295
"@executable_path/Frameworks",
296296
);
297-
PRODUCT_BUNDLE_IDENTIFIER = com.example.pushNotifications;
297+
PRODUCT_BUNDLE_IDENTIFIER = com.talkjs.flutter_push_example;
298298
PRODUCT_NAME = "$(TARGET_NAME)";
299299
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
300300
SWIFT_VERSION = 5.0;
@@ -422,7 +422,7 @@
422422
"$(inherited)",
423423
"@executable_path/Frameworks",
424424
);
425-
PRODUCT_BUNDLE_IDENTIFIER = com.example.pushNotifications;
425+
PRODUCT_BUNDLE_IDENTIFIER = com.talkjs.flutter_push_example;
426426
PRODUCT_NAME = "$(TARGET_NAME)";
427427
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
428428
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -444,7 +444,7 @@
444444
"$(inherited)",
445445
"@executable_path/Frameworks",
446446
);
447-
PRODUCT_BUNDLE_IDENTIFIER = com.example.pushNotifications;
447+
PRODUCT_BUNDLE_IDENTIFIER = com.talkjs.flutter_push_example;
448448
PRODUCT_NAME = "$(TARGET_NAME)";
449449
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
450450
SWIFT_VERSION = 5.0;

examples/push_notifications/ios/Runner/AppDelegate.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import Flutter
88
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
99
) -> Bool {
1010
GeneratedPluginRegistrant.register(with: self)
11+
12+
if #available(iOS 10.0, *) {
13+
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
14+
}
15+
1116
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
1217
}
1318
}

examples/push_notifications/ios/Runner/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,7 @@
4343
</array>
4444
<key>UIViewControllerBasedStatusBarAppearance</key>
4545
<false/>
46+
<key>flutter_apns.disable_swizzling</key>
47+
<true/>
4648
</dict>
4749
</plist>

examples/push_notifications/pubspec.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ packages:
139139
description: flutter
140140
source: sdk
141141
version: "0.0.0"
142+
flutter_apns_only:
143+
dependency: transitive
144+
description:
145+
name: flutter_apns_only
146+
url: "https://pub.dartlang.org"
147+
source: hosted
148+
version: "1.5.2"
142149
flutter_lints:
143150
dependency: "direct dev"
144151
description:

lib/src/chatbox.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,18 @@ class ChatBoxState extends State<ChatBox> {
224224
if (fcmToken != null) {
225225
execute('session.setPushRegistration({provider: "fcm", pushRegistrationId: "$fcmToken"});');
226226
}
227+
228+
if (apnsToken != null) {
229+
execute('session.setPushRegistration({provider: "apns", pushRegistrationId: "$apnsToken"});');
230+
}
227231
} else {
228232
if (fcmToken != null) {
229233
execute('session.unsetPushRegistration({provider: "fcm", pushRegistrationId: "$fcmToken"});');
230234
}
235+
236+
if (apnsToken != null) {
237+
execute('session.unsetPushRegistration({provider: "apns", pushRegistrationId: "$apnsToken"});');
238+
}
231239
}
232240
}
233241

lib/src/conversationlist.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,18 @@ class ConversationListState extends State<ConversationList> {
183183
if (fcmToken != null) {
184184
execute('session.setPushRegistration({provider: "fcm", pushRegistrationId: "$fcmToken"});');
185185
}
186+
187+
if (apnsToken != null) {
188+
execute('session.setPushRegistration({provider: "apns", pushRegistrationId: "$apnsToken"});');
189+
}
186190
} else {
187191
if (fcmToken != null) {
188192
execute('session.unsetPushRegistration({provider: "fcm", pushRegistrationId: "$fcmToken"});');
189193
}
194+
195+
if (apnsToken != null) {
196+
execute('session.unsetPushRegistration({provider: "apns", pushRegistrationId: "$apnsToken"});');
197+
}
190198
}
191199
}
192200

lib/src/notification.dart

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:isolate';
66
import 'package:firebase_messaging/firebase_messaging.dart';
77
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
88
import 'package:http/http.dart' as http;
9+
import 'package:flutter_apns_only/flutter_apns_only.dart';
910

1011
enum AndroidVisibility {
1112
/// Show the notification on all lockscreens, but conceal sensitive or private information on secure lockscreens.
@@ -87,19 +88,20 @@ class AndroidChannel {
8788
}
8889

8990
class IOSPermissions {
90-
final bool? alert;
91-
final bool? badge;
92-
final bool? sound;
93-
final bool? critical;
91+
final bool alert;
92+
final bool badge;
93+
final bool sound;
94+
final bool? critical; // ?
9495
const IOSPermissions({
95-
this.alert,
96-
this.badge,
97-
this.sound,
96+
this.alert = true,
97+
this.badge = true,
98+
this.sound = true,
9899
this.critical,
99100
});
100101
}
101102

102103
String? fcmToken;
104+
String? apnsToken;
103105

104106
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
105107
AndroidChannel? _androidChannel;
@@ -327,3 +329,37 @@ Future<void> registerAndroidPushNotificationHandlers(AndroidChannel androidChann
327329
FirebaseMessaging.onBackgroundMessage(_onFCMBackgroundMessage);
328330
}
329331

332+
Future<void> _onPush(String name, ApnsRemoteMessage message) async {
333+
final payload = message.payload;
334+
print('📘 _onPush $name: ${payload["notification"]?["title"]}');
335+
336+
final action = UNNotificationAction.getIdentifier(payload['data']);
337+
338+
if (action != null && action != UNNotificationAction.defaultIdentifier) {
339+
print('📘 _onPush action: $action');
340+
}
341+
}
342+
343+
Future<void> registerIOSPushNotificationHandlers(IOSPermissions iosPermissions) async {
344+
final connector = ApnsPushConnectorOnly();
345+
346+
connector.configureApns(
347+
onLaunch: (data) => _onPush('onLaunch', data),
348+
onResume: (data) => _onPush('onResume', data),
349+
onMessage: (data) => _onPush('onMessage', data),
350+
onBackgroundMessage: (data) => _onPush('onBackgroundMessage', data),
351+
);
352+
353+
connector.token.addListener(() {
354+
print('📘 apns token refresh: ${connector.token.value}');
355+
356+
apnsToken = connector.token.value;
357+
});
358+
359+
connector.requestNotificationPermissions(IosNotificationSettings(
360+
sound: iosPermissions.sound,
361+
alert: iosPermissions.alert,
362+
badge: iosPermissions.badge,
363+
));
364+
}
365+

lib/talkjs_flutter.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
library talkjs;
22

33
import 'dart:convert' show json, utf8;
4+
import 'dart:io' show Platform;
45
import 'package:crypto/crypto.dart' show sha1;
56
import 'src/notification.dart';
67

@@ -34,7 +35,15 @@ class Talk {
3435
}
3536

3637
Future<void> registerPushNotificationHandlers({AndroidChannel? androidChannel, IOSPermissions? iosPermissions}) async {
37-
if (androidChannel != null) {
38-
await registerAndroidPushNotificationHandlers(androidChannel);
38+
if (Platform.isAndroid) {
39+
if (androidChannel != null) {
40+
await registerAndroidPushNotificationHandlers(androidChannel);
41+
}
42+
}
43+
44+
if (Platform.isIOS) {
45+
if (iosPermissions != null) {
46+
await registerIOSPushNotificationHandlers(iosPermissions);
47+
}
3948
}
4049
}

pubspec.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ packages:
132132
description: flutter
133133
source: sdk
134134
version: "0.0.0"
135+
flutter_apns_only:
136+
dependency: "direct main"
137+
description:
138+
name: flutter_apns_only
139+
url: "https://pub.dartlang.org"
140+
source: hosted
141+
version: "1.5.2"
135142
flutter_local_notifications:
136143
dependency: "direct main"
137144
description:

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dependencies:
1717
firebase_messaging: ^11.3.0
1818
flutter_local_notifications: ^9.5.2
1919
http: ^0.13.4
20+
flutter_apns_only: ^1.5.2
2021

2122
dev_dependencies:
2223
flutter_test:

0 commit comments

Comments
 (0)