【问题标题】:How to determine device type from Swift? (OS X or iOS)如何从 Swift 确定设备类型? (OS X 或 iOS)
【发布时间】:2014-07-26 17:33:15
【问题描述】:

我知道 Swift 相对较新,但我想知道是否有办法确定设备类型?

(就像您过去可以使用 #define 一样)?

主要是我想知道如何区分 OS X 或 iOS。我没有找到关于这个主题的任何东西。

【问题讨论】:

  • 您可能希望有两个目标,一个用于您的 iOS 应用程序,一个用于您的 OS X 应用程序。
  • 由于 Swift 没有预处理器也没有宏,也许你可以使用运行时检查。

标签: ios macos swift


【解决方案1】:

Swift 5Xcode 13

如果你使用的是“Scale interface to Match iPad, you can't use UIDevice.current.userInterfaceIdiom, because it will return an .iPad value. 但是建议改用targetEnvironment。下面是示例代码:

    #if targetEnvironment(macCatalyst)
            //execute your code for mac device
    #endif

如果您没有使用缩放界面来匹配 iPad,而是使用“优化 Mac 界面”,您可以使用此代码来确定设备:

UIDevice.current.userInterfaceIdiom == .mac

这里是apple documantation,提供更多信息。

【讨论】:

    【解决方案2】:

    Swift 4(2020 年 7 月 21 日更新)

    enum TargetDevice {
        case nativeMac
        case iPad
        case iPhone
        case iWatch
        
        public static var currentDevice: Self {
            var currentDeviceModel = UIDevice.current.model
            #if targetEnvironment(macCatalyst)
            currentDeviceModel = "nativeMac"
            #elseif os(watchOS)
            currentDeviceModel = "watchOS"
            #endif
            
            if currentDeviceModel.starts(with: "iPhone") {
                return .iPhone
            }
            if currentDeviceModel.starts(with: "iPad") {
                return .iPad
            }
            if currentDeviceModel.starts(with: "watchOS") {
                return .iWatch
            }
            return .nativeMac
        }
    }
    

    用法:

    print(TargetDevice.currentDevice)
    

    【讨论】:

      【解决方案3】:

      如果您同时为 iOS 和 macOS(也可能为 watchOS 和 tvOS)构建,您至少要编译两次:每个平台一次。如果您希望在每个平台上执行不同的代码,则需要构建时条件,而不是运行时检查。

      Swift 没有预处理器,但它确实有条件构建指令——而且在大多数情况下,它们看起来像 C 等价物。

      #if os(iOS) || os(watchOS) || os(tvOS)
          let color = UIColor.red
      #elseif os(macOS)
          let color = NSColor.red
      #else
          println("OMG, it's that mythical new Apple product!!!")
      #endif
      

      您还可以使用构建配置来测试架构(x86_64armarm64i386)、目标环境(iOS 模拟器或 Mac Catalyst)或-D 编译器标志(包括DEBUG 标准 Xcode 模板定义的标志)。不要假设这些东西会同时出现——Apple 已经宣布 macOS on arm64 将于 2020 年发布,因此 arm64 并不意味着 iOS,iOS Simulator 也不意味着 x86,等等。

      参见Swift 编程语言中的Compiler Control statements

      (如果您想在运行时区分您使用的是哪种 iOS 设备,请像使用 ObjC 一样使用 UIDevice 类。查看对您而不是设备名称或惯用语——例如,使用特征和尺寸类来布置您的 UI,检查 Metal 以获得您需要的 GPU 功能等)

      【讨论】:

      • +1 表示else 案例。始终处理边缘情况! :-p
      • 注意根据Swift Documentation现在应该是#elseif os(macOS)
      【解决方案4】:

      这应该为您提供每个用例:

      #if os(OSX)
          print("macOS")
      #elseif os(watchOS)
          print("watchOS")
      #elseif os(tvOS)
          print("tvOS")
      #elseif os(iOS)
          #if targetEnvironment(macCatalyst)
              print("macOS - Catalyst")
          #else
              print("iOS")
          #endif
      #endif
      

      【讨论】:

      • iPadOS 有更新吗?或者它仍然被识别为iOS?
      • 如果 UIDevice.current.userInterfaceIdiom == .pad 用于 iPad
      【解决方案5】:

      更新 Mac Catalyst。您现在还可以使用以下内容来确定是 iOS 还是 Mac Catalyst:

      let color: UIColor
      #if targetEnvironment(macCatalyst)
      color = .systemRed
      #else
      color = .systemBlue
      #endif
      

      例如。

      【讨论】:

      • 谢谢,这对我很有帮助。 #if os(OSX) 不适用于 Mac Catalyst
      【解决方案6】:

      从 Swift 4.2 开始可以替换

      #if os(iOS) || os(watchOS) || os(tvOS)
          let color = UIColor.redColor()
      #elseif os(OSX)
          let color = NSColor.redColor()
      #else
           println("OMG, it's that mythical new Apple product!!!")
      #endif
      

      #if canImport(UIKit)
          let color = UIColor.redColor()
      #elseif os(OSX)
          let color = NSColor.redColor()
      #else
          #error("OMG, it's that mythical new Apple product!!!")
      #endif
      

      【讨论】:

      • @Cristik 我的答案是在 2018 年 6 月 11 日,接受的答案是在 2018 年 11 月 3 日更新的!我更新了接受的答案,但没有被批准!
      • 是的,但是自从 2014 年 6 月 5 日第一次修订以来,该答案中就出现了错误消息。顺便说一句,我只特别提到了该消息,而不是答案的其他方面。
      • 在我回答这个问题之前,接受的答案是#if canImport(UIKit),但是在4.2之后,测试变成了#if os(iOS) ||操作系统(watchOS) || os(tvOS) 这是我唯一改变的部分
      • 在这里查看:stackoverflow.com/revisions/24065534/1"OMG, it's that mythical new Apple product!!!" 在那里。这就是我所说的文字。
      • 我认为这将不再有效,因为 macOS 实际上可以将 UIKit 作为 Mac Catalyst 的一部分导入。
      【解决方案7】:
      var device = UIDevice.currentDevice().model 
      

      这段代码对我有用。我已经在文本字段和键盘解除部分实现了这一点。见下文。

      func textFieldShouldBeginEditing(textField: UITextField) -> Bool
      {
      
          print(device)
      
          if (textField.tag  == 1 && (device == "iPhone" || device == "iPhone Simulator" ))
          {
              var scrollPoint:CGPoint = CGPointMake(0,passwordTF.frame.origin.y/2);
              LoginScroll!.setContentOffset(scrollPoint, animated: true);
          }
          else if (textField.tag  == 2 && (device == "iPhone" || device == "iPhone Simulator"))
          {
              var scrollPoint:CGPoint = CGPointMake(0,passwordTF.frame.origin.y/1.3);
              LoginScroll!.setContentOffset(scrollPoint, animated: true);
          }
      
          return true
      
      }
      

      【讨论】:

      • 这仅适用于 iOS,不适用于 macOS
      • 在 Swift 3 中:UIDevice.current.model
      猜你喜欢
      • 2012-12-19
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多