In macOS 10.12 and iOS 10.0, class properties were introduced to Objective-C [1]. I noticed that the Objective-C runtime treats class properties differently based on the deployment target. Example:

    // MyClass is an Objective-C class that has a class property
    let metaclass = object_getClass(MyClass.self)
    var count: UInt32 = 0
    let properties = class_copyPropertyList(metaclass, &count)
    // Work with properties
    // Deallocate properties

When the deployment target is macOS 10.12, passing a metaclass to copyPropertyList() returns the class properties, but it returns an empty list on a lower deployment target.

I'd like to perform a check (either at runtime or compile time) which of these behaviors I'll get.

I didn't find a way to perform a compile-time check in Swift against the deployment target; if #available() checks against the SDK the code is linked against. Likewise, the usual runtime check using ProcessInfo().isOperatingSystemAtLeast() doesn't check against the deployment target.

The best I came up with is this:

/**
Returns `true` if the current deployment target is at least the specified version that corresponds to the current platform.

The arguments must be passed in the form of the `__MAC_XX_X`, `__IPHONE_XX_X`, etc. constants defined in Availability.h.
 */
public func isDeploymentTargetAtLeast(
    macOS macOSVersion: Int32, iOS iOSVersion: Int32,
    tvOS tvOSVersion: Int32, watchOS watchOSVersion: Int32) -> Bool {

    #if os(macOS)
        return __MAC_OS_X_VERSION_MIN_REQUIRED >= macOSVersion
    #elseif os(iOS)
        return __IPHONE_OS_VERSION_MIN_REQUIRED >= iOSVersion
    #elseif os(tvOS)
        return __TV_OS_VERSION_MIN_REQUIRED >= tvOSVersion
    #elseif os(watchOS)
        return __WATCH_OS_VERSION_MIN_REQUIRED >= watchOSVersion
    #else
        return false
    #endif
}

For example, to test if the current deployment target is at least macOS 10.12, iOS 10.0, tvOS 10.0, or watchOS 3.0:

guard isDeploymentTargetAtLeast(
    macOS: __MAC_10_12, iOS: __IPHONE_10_0,
    tvOS: __TVOS_10_0, watchOS: __WATCHOS_3_0) else {

    // Deployment target is lower
    ...
}

Is this correct? Is there a better way to do this?

[1]: http://useyourloaf.com/blog/objective-c-class-properties/
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to