【发布时间】:2020-09-26 11:43:48
【问题描述】:
我有一个 iOS 应用,它使用 Firebase 进行通知。通知已设置并正在工作,我现在需要接收/处理通知以相应地呈现视图控制器。我使用 Objective C 代码来调用我的 C++ 代码,因此我的项目中有一个桥接头,它主要是用 Swift 编写的。
我使用了 firebase 文档(以及其他示例)中的 this example。简而言之:遵守协议UNUserNotificationCenterDelegate并实现其功能。我也在我的AppDelegate 课堂上做import UserNotifications。
现在,在使用这几个更改进行编译时,我得到了这两个错误
找不到“UNUserNotificationCenterDelegate”的协议声明
未知类型名称'UNNotificationPresentationOptions'
对于生成的代码:
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
--- 更新
经过反复试验,似乎注释掉从 objC 到 Swift 的所有调用以及声明为 @objc 的所有 Swift 类型的使用使我的代码编译,并且桥接头不再抱怨。这还包括在我所有的 Objective C 代码中注释掉#import "myapp-Swift.h"(这可能是桥接头不再抱怨的原因)。不幸的是,在 ObjC 中停止使用 Swift 类型是不可行的,因为对于看似很小的更改,它需要进行相当多的重写。
我想这可能在一定程度上表明了问题的根源,但我仍然不确定为什么或如何影响UNUserNotificationCenterDelegate 协议。
--- 结束更新
其他注意事项:
- 错误源于我导入生成的
myapp-Swift.h的 Objective C++ 文件。 - 我尝试将
#import <UserNotifications/UNUserNotificationCenter.h>添加到我的桥接头中。 Xcode 不会抱怨包含,所以它确实找到了它,但它没有帮助。执行#import <UserNotifications/UserNotifications.h>也不起作用。 - 我尝试在
AppDelegate本身和作为扩展中都符合UNUserNotificationCenterDelegate。两种情况下的错误都是一样的。 - 桥接头包含在我的
.mm文件中,错误源自那里。 -
UserNotifications.framework在Frameworks, Libraries and Embedded Content。 -
UserNotifications.framework在Link Binary With Libraries中。 - 我尝试将部署目标更改为较新的版本,但没有成功。
- 我看了this question,和这个基本一样,但是没有用。它进一步指向
- this question,但这不是我的用例。
这是我的git diff供参考:
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"
【问题讨论】:
-
据我了解,
AppDelegate.swift' is swift and conforming toUNUserNotificationCenterDelegate, so there's no need for#import` in myapp-Bridging-Header.h -
@PushpakNarasimhan 这都是真的,
myapp-Bridging-Header.h中的包含只是我尝试看看它是否改变了什么。 -
您可能想在链接框架时尝试选择可选
-
可能与 C++ 对模块的不良支持有关。将有问题的代码移到 Objective C 有什么不同吗?
-
我做了更多的挖掘(请参阅问题中的更新)。注释掉从 Objective C 到 Swift 的所有调用,以及在 Objective C 中标记为
@objc的所有 Swift 类型的使用,使代码编译成功。这还包括在所有 Objective C 代码中注释掉#import "myapp-Swift.h"。不幸的是,我不太确定这个事实告诉我什么。
标签: ios swift firebase apple-push-notifications bridging-header