I have a an iOS app using Firebase for notifications. Notifications are set up and working, and I now need to receive/handle the notifications to present view controllers accordingly. I use Objective C code to call my C++ code, and therefore I have a bridging header in my project, which is mainly written in Swift.
I have used this example from the firebase documentation (as well as other examples). In short terms: conform to the protocol UNUserNotificationCenterDelegate
and implement its functions. I also do import UserNotifications
in my AppDelegate
class.
Now, when compiling with these few changes I get these two errors
Cannot find protocol declaration for 'UNUserNotificationCenterDelegate'
Unknown type name 'UNNotificationPresentationOptions'
for the generated code:
SWIFT_AVAILABILITY(ios,introduced=10)
@interface AppDelegate (SWIFT_EXTENSION(myapp)) <UNUserNotificationCenterDelegate>
- (void)userNotificationCenter:(UNUserNotificationCenter * _Nonnull)center willPresentNotification:(UNNotification * _Nonnull)notification withCompletionHandler:(void (^ _Nonnull)(UNNotificationPresentationOptions))completionHandler;
- (void)userNotificationCenter:(UNUserNotificationCenter * _Nonnull)center didReceiveNotificationResponse:(UNNotificationResponse * _Nonnull)response withCompletionHandler:(void (^ _Nonnull)(void))completionHandler;
@end
--- Update
After some trial and error it seems that commenting out all calls from objC to Swift as well as all usage of Swift types declared as @objc
makes my code compile, and the bridging header does not complain anymore. This also includes commenting out #import "myapp-Swift.h"
in all my Objective C code (which is probably why the bridging header does not complain anymore). Unfortunately it is not feasible to stop using the Swift types in ObjC, as it would require quite some rewrite for a seemingly small change.
I guess this could somewhat indicate the origin of the issue, though I am still no sure why or how this affects the UNUserNotificationCenterDelegate
protocol.
--- End Update
Other things to note:
- The error originates from an Objective C++ file where I import the generated
myapp-Swift.h
. - I tried adding
#import <UserNotifications/UNUserNotificationCenter.h>
to my bridging header. Xcode does not complain about the include, so it does find it, but it does not help. Doing#import <UserNotifications/UserNotifications.h>
does not work either. - I tried conforming to
UNUserNotificationCenterDelegate
both in theAppDelegate
itself and as an extension. The errors are the same in both cases. - The bridging header is included in my
.mm
files and the errors originate from there. UserNotifications.framework
is inFrameworks, Libraries and Embedded Content
.UserNotifications.framework
is inLink Binary With Libraries
.- I tried changing the deployment target to newer versions without luck.
- I looked at this question which is basically the same as this one, but nothing works. It points further to
- this question, but that is not my use case.
Here is my git diff
for reference:
diff --git a/ios/myapp.xcodeproj/project.pbxproj b/ios/myapp.xcodeproj/project.pbxproj
index 1ac676e..ca3a814 100644
--- a/ios/myapp.xcodeproj/project.pbxproj
+++ b/ios/myapp.xcodeproj/project.pbxproj
@@ -1550,7 +1550,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "";
- IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -1601,7 +1601,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "";
- IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
diff --git a/ios/myapp/AppDelegate.swift b/ios/myapp/AppDelegate.swift
index a1c9543..1010f99 100644
--- a/ios/myapp/AppDelegate.swift
+++ b/ios/myapp/AppDelegate.swift
@@ -7,6 +7,7 @@
//
import UIKit
+import UserNotifications
import Firebase
@UIApplicationMain
@@ -21,6 +22,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate
FirebaseInterface.initialize()
ShoppingListInterface.loadLastSavedShoppingList()
+
+ if #available(iOS 10.0, *) {
+ // For iOS 10 display notification (sent via APNS)
+ UNUserNotificationCenter.current().delegate = self
+
+ let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
+ UNUserNotificationCenter.current().requestAuthorization(
+ options: authOptions,
+ completionHandler: {_, _ in })
+ } else {
+ let settings: UIUserNotificationSettings =
+ UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
+ application.registerUserNotificationSettings(settings)
+ }
+
return true
}
@@ -73,3 +91,46 @@ class AppDelegate: UIResponder, UIApplicationDelegate
// TODO: Save ShoppingList
}
}
+
+@available(iOS 10, *)
+extension AppDelegate : UNUserNotificationCenterDelegate
+{
+
+ // Receive displayed notifications for iOS 10 devices.
+ func userNotificationCenter(_ center: UNUserNotificationCenter,
+ willPresent notification: UNNotification,
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
+ let userInfo = notification.request.content.userInfo
+
+ // With swizzling disabled you must let Messaging know about the message, for Analytics
+ // Messaging.messaging().appDidReceiveMessage(userInfo)
+ // Print message ID.
+// if let messageID = userInfo[gcmMessageIDKey] {
+// print("Message ID: \(messageID)")
+// }
+
+ // Print full message.
+ print(userInfo)
+
+ // Change this to your preferred presentation option
+ completionHandler([[.alert, .sound]])
+ }
+
+ func userNotificationCenter(_ center: UNUserNotificationCenter,
+ didReceive response: UNNotificationResponse,
+ withCompletionHandler completionHandler: @escaping () -> Void) {
+ let userInfo = response.notification.request.content.userInfo
+ // Print message ID.
+// if let messageID = userInfo[gcmMessageIDKey] {
+// print("Message ID: \(messageID)")
+// }
+
+ // With swizzling disabled you must let Messaging know about the message, for Analytics
+ // Messaging.messaging().appDidReceiveMessage(userInfo)
+ // Print full message.
+ print(userInfo)
+
+ completionHandler()
+ }
+}
+// [END ios_10_message_handling]
diff --git a/ios/myapp/myapp-Bridging-Header.h b/ios/myapp/myapp-Bridging-Header.h
index 1b2d4c1..4973a15 100644
--- a/ios/myapp/myapp-Bridging-Header.h
+++ b/ios/myapp/myapp-Bridging-Header.h
@@ -11,6 +11,7 @@
myapp-Swift.h, remember to do #import <UIKit/UIKit.h> in the Objective C
header file.
*/
+#import <UserNotifications/UNUserNotificationCenter.h>
#import "ShoppingListWrapper.h"
#import "DBWrapper.h"
#import "FirebaseWrapper.h"