【问题标题】:Check for framework availability at run time在运行时检查框架可用性
【发布时间】:2017-10-09 11:41:11
【问题描述】:

要在我的库中生成本地通知,我需要使用 UserNotificationUILocalNotification,具体取决于我的主机应用程序使用什么。 (一些客户仍在使用已弃用的didReceiveLocalNotification: API)。

现在,当我创建通知时,是否可以在运行时确定主机应用使用哪个系统并创建适当的 API。这意味着我需要有条件地导入和使用UserNotification 头文件。

编辑: 关于NSClassFromString的使用:

if (NSClassFromString(@"FrameworkClass") == nil) {
   // the framework is not available
} else {
   // the framework is avaiable
}

但是我有很多UserNotification 代码要写。我不认为使用performSelector: 会很实用。

【问题讨论】:

  • 你检查过this吗?
  • @PuneetSharma 是的。我已经更新了我的问题。

标签: ios objective-c


【解决方案1】:

预处理器宏呢?

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
// Only COMPILE this if compiled against BaseSDK iOS10.0 or greater
#import <UserNotifications/UserNotifications.h>
#endif

【讨论】:

  • 这是一个编译时检查。这在我的情况下不起作用,因为我必须在运行时做出决定。
【解决方案2】:

这是注册远程通知检查 API 的示例

在斯威夫特中

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)
}

application.registerForRemoteNotifications()

在 Obj-C 中

if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
  UIUserNotificationType allNotificationTypes =
  (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
  UIUserNotificationSettings *settings =
  [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
  [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
  // iOS 10 or later
  #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  // For iOS 10 display notification (sent via APNS)
  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions =
      UNAuthorizationOptionAlert
      | UNAuthorizationOptionSound
      | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
      }];
  #endif
}

[[UIApplication sharedApplication] registerForRemoteNotifications];

【讨论】:

  • UINotifications 已被弃用,但在 iOS 10、11 上并未停止使用。应用程序可能会选择仍使用 UINotifications。
【解决方案3】:

我不认为您可以在 Objective-C 中在运行时导入框架。

您可以利用 Objective C 运行时魔法并使用 performSelector: 在不导入类/框架的情况下调用选择器/方法,但您不一定要使用它,因为没有对选择器名称进行编译时检查,可能会导致如果使用不当,应用程序会崩溃。

我能想到实现您想要的唯一方法是在您的库中使用 weak-link UserNotifications 框架。

在运行时,您可以检查您的客户端是否支持框架,如果框架符号可用,您可以安全地运行它们。

这样做,您可以获得方法名称检查的编译时安全性,并且您可以以正常方式编写代码,但是不要忘记在执行框架的任何符号之前检查框架的可用性。

【讨论】:

  • 是的,这就是我要采用的方法。但是,如何检查宿主应用程序是否支持该框架?
  • @NSRover:您可以简单地使用 if( [UserNotifications class])。但请确保您的库中有弱链接的 UserNotifications 框架,即在目标的构建阶段使框架链接成为可选。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 2011-04-07
  • 2012-01-05
  • 1970-01-01
相关资源
最近更新 更多