【问题标题】:Conditional Compilation for User Notifications in Swift 3 and Xcode 8.2Swift 3 和 Xcode 8.2 中用户通知的条件编译
【发布时间】:2017-03-03 20:22:37
【问题描述】:

我们有一个支持 iOS 9+ 的应用程序,它正在 Swift 3 和 Xcode 8.2.x 中开发。 iOS 10 引入了一种注册推送通知的新方法,很好地描述了in this post。由于 iOS 9 不知道 User Notifications 框架,所以我们想在设备是 iOS 9 时使用 iOS 9 方法,而在 iOS 10 上使用 UserNotifications.framework。在 Objective C 中,我们将通过条件编译来实现(例如#ifdef 语句)。

在 Swift 3 中,有一些条件编译工具 #available#if。我们尝试将通知注册代码的分支包装在这两个指令中,应用程序将无法编译。 #available 产生相似的结果

这是针对通用/真实设备的情况。该应用程序将针对模拟器进行编译。

【问题讨论】:

  • 这很有趣...无法重现此编译问题。如果您还没有尝试清理项目并删除派生数据?
  • 我会在星期一试一试。您是为“通用 iOS 设备”还是实际设备构建?这就是问题发生的地方。正如我提到的,它针对模拟器进行编译。
  • 条件编译真的是你想要的吗?你有 iOS 9 和 iOS 10 的单独版本吗?
  • 另请注意,#available 不是条件编译,它是运行时检查。
  • 是的,在#available 上理解。条件编译是我能想到的最接近的东西。我们想要 iOS 10 上的新框架和 iOS 9 上的旧框架。如果您尝试在 iOS 10 设备(或通用设备)上构建,它不会构建,因为它不知道 UIUserNotificationSettings。当引入 IOS 7 注册方法时,我们进行了类似的检查。我们在 Objective C 中做了类似的事情并且没有问题。我们没有遇到问题,因为 7 仍然知道 6 方法。在这种情况下,似乎 10 并没有识别出 9 路。

标签: ios iphone swift xcode


【解决方案1】:

根据上面的 cmets,您需要运行时检查,而不是条件编译,#available 正是如此。

这对我来说很好用:

if #available(iOS 10.0, *) {
    UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) {
        (granted, error) in
    }
}
else {
    UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
}

UIUserNotificationSettings 在 iOS 10 中已弃用,但它实际上仍然存在。在 API 被弃用很长时间之前,Apple 通常不会删除它们。

我怀疑您还有其他类型的构建问题。突然想到:您是否正确设置了基本 SDK 和部署目标?

【讨论】:

  • 是的,部署目标肯定设置为 9。我会仔细检查基础 SDK。就像我说的那样,可用的检查适用于模拟人生,但不会在通用设备或连接到 Mac 的物理设备上编译。您在这两种情况下看到成功了吗?
  • 是的,适用于通用 iOS 设备和我可信赖的 ole iPhone 5s。
  • 我想我已经明白了。 @zpasternack 这个项目正在使用 Swift 3。它不会让我更改基础 SDK,因为 Swift 3 仅在我想的新 SDK 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多