如何仅在布尔值为true时实现didReceiveRemoteNotification方法?
解决方案
方案1:使用条件编译宏控制方法编译
运行时的布尔变量无法控制方法是否被编译进二进制,这也是Xcode提示的核心原因——只要方法存在于代码中,无论是否被调用,Xcode都会检测到。改用编译宏可以直接让方法在禁用推送时不被编译:
- 让使用库的开发者在项目的
Build Settings > Other Swift Flags中添加-D ENABLE_PUSH_NOTIFICATIONS(启用推送时),不添加则默认禁用。 - 在你的库代码中用宏包裹推送相关的方法和初始化逻辑:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { #if ENABLE_PUSH_NOTIFICATIONS UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge], completionHandler: { (_, _) in }) application.registerForRemoteNotifications() UNUserNotificationCenter.current().delegate = self #endif return true } #if ENABLE_PUSH_NOTIFICATIONS func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 你的推送处理逻辑 completionHandler(.newData) } #endif
当未定义宏时,didReceiveRemoteNotification方法不会被编译,Xcode也就不会弹出那个提示了。
方案2:用协议+扩展拆分推送功能
这种方式更符合Swift的面向协议设计,能灵活控制推送功能的启用:
- 在库中定义推送处理协议,包含必要的方法和初始化逻辑:
import UIKit import UserNotifications protocol PushCapable: UIApplicationDelegate, UNUserNotificationCenterDelegate { func setupPushNotifications(_ application: UIApplication) } extension PushCapable { func setupPushNotifications(_ application: UIApplication) { UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge], completionHandler: { (_, _) in }) application.registerForRemoteNotifications() UNUserNotificationCenter.current().delegate = self } // 默认实现,使用者可以按需重写 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { completionHandler(.noData) } }
- 让使用库的开发者在需要启用推送时,让他们的
AppDelegate遵循PushCapable协议,并调用初始化方法:
class AppDelegate: UIResponder, UIApplicationDelegate, PushCapable { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { setupPushNotifications(application) return true } // 可选:重写推送处理逻辑 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 自定义处理逻辑 completionHandler(.newData) } }
如果开发者不需要推送,只需让AppDelegate不遵循PushCapable协议即可,此时不会有didReceiveRemoteNotification的实现,Xcode也不会触发提示。
不推荐的方案:运行时动态添加方法
虽然可以通过Objective-C运行时API动态添加方法,但这种方式复杂度高,调试困难,且Swift类默认是非动态的,需要额外配置@objc dynamic,容易引入兼容性问题,因此不建议作为首选方案。
内容的提问来源于stack exchange,提问作者danilink88
相关产品推荐
相关产品推荐

