#if canImport(UIKit) && !os(watchOS) 和 #if os(iOS) 这两种条件编译写法各有适用场景。本文将深入解析它们的本质区别,并提供清晰的选用指南。要理解这两种写法的区别,首先需要了解 Apple 各系统中 UI 框架的分布:
os(iOS) | |||
os(iOS) | |||
os(tvOS) | |||
os(macOS)targetEnvironment(macCatalyst) | |||
os(watchOS) |
关键点:
虽然 iPadOS 是独立的操作系统,但在编译时仍使用 os(iOS)宏UIKit 是 iOS、iPadOS、tvOS 的原生框架,但通过 Mac Catalyst 也可以在 macOS 上运行 watchOS 完全不支持 UIKit
#if os(iOS):基于系统类型的精确判断这种写法检查编译目标是否为 iOS 系统(包含 iPhone 和 iPad)。
#if os(iOS)// 这里的代码会在 iOS 和 iPadOS 设备上编译#endif优点:
缺点:
#if canImport(UIKit) && !os(watchOS):基于框架可用性的智能适配这种写法首先检查能否导入 UIKit 框架,然后主动排除 watchOS。
#if canImport(UIKit) && !os(watchOS)// 这里的代码会在所有支持 UIKit 的平台上编译// 包括:iOS、iPadOS、tvOS、macOS Catalyst#endif优点:
!os(watchOS) 让意图更清晰,即使 canImport(UIKit) 在 watchOS 上已经返回 false缺点:
os(iOS) 稍复杂,但可读性依然优秀canImport 写法)// 适配所有支持 UIKit 的平台,排除 watchOS#if canImport(UIKit) && !os(watchOS)import UIKit// 这是一个所有 UIKit 平台都能用的通用扩展extensionUIViewController{funcshowAlert(title: String, message: String) {let alert = UIAlertController( title: title, message: message, preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) }}#endifos(iOS) 写法)// 仅针对 iOS 和 iPadOS 系统#if os(iOS)import UIKit// 适用于 iOS/iPadOS 的功能extensionUIDevice{var isPhone: Bool {return userInterfaceIdiom == .phone }var isPad: Bool {return userInterfaceIdiom == .pad }functriggerHapticFeedback(style: UIImpactFeedbackGenerator.FeedbackStyle) {let generator = UIImpactFeedbackGenerator(style: style) generator.impactOccurred() }}#endif由于编译时无法通过 os(iPadOS) 判断,需要在运行时区分设备类型:
#if os(iOS)import UIKit// 运行时判断设备类型funcdeviceSpecificBehavior() {switchUIDevice.current.userInterfaceIdiom {case .phone:// iPhone 专属逻辑print("Running on iPhone")case .pad:// iPad 专属逻辑print("Running on iPad")default:break }}#endif掌握这两种条件编译写法的适用场景,能帮助你编写更清晰、更健壮的跨平台代码,提升代码的可维护性和可读性。如果考虑未来兼容性,使用基于框架可用性的判断(canImport)比基于系统版本的判断(os())更具前瞻性。未来 Apple 推出新系统但支持 UIKit,代码无需修改就能适配。
About the Author
龚阳 /Gong Yang
Gong Yang is an experienced MBaaS iOS technologist specializing in mobile development. He is proficient in Swift and Objective-C programming languages and their ecological frameworks, and familiar with various software design patterns and architectures. With rich hands-on experience, he is especially good at functional programming, SwiftUI and cross-platform technology development.
Copyright
This article was originally written by Klilala Group and its affiliates and is copyrighted by Klilala Group. Anyone wishing to reproduce, abstract or otherwise quote the contents of this article must obtain the express authorization and written permission of Klilala Group, and indicate the source of reproduction when doing so. Any unauthorized reproduction or use of this article will result in legal liability.
For authorization, please contact us at
group@klilala-inc.com
028-67876790
Thank you for your understanding and support!
Follow us on our official WeChat public account