How to extend a class that depends on the OS

In Objective-C we have a category on both UIColor and NSColor where the code itself is identical - 100%. The only difference is the return types. So we have a #define at the top - if we're on iOS "#define PIColor UIColor" and on OS X we "#define PIColor NSColor".


I can't seem to get this to work in Swift and it may not be possible, but I've only been using Swift for a week - so asking here. Maybe there is a better way to do this (protocol extensions maybe?). I am using Swift 2.


I was disappointed that this didn't work:

#if os(iOS)
extension UIColor {
#elseif os(OSX)
extension NSColor {
#endif

  func stringFromColor() -> String {
  }


}


I can just keep our ObjC version for now…but this seems like there should be a way to do this in Swift.

I just saw "typealias". That might solve my problem. http://ericasadun.com/2014/06/06/swift-cross-platform-code/

I haven't checked precisely, but does this not work?

#if os(iOS)
    typealias MyColor = UIColor
#elseif os(OSX)
    typealias MyColor = NSColor
#endif
extension MyColor {
    func stringFromColor() -> String {
        //...
    }
}

I can confirm that OOPer's suggestion works very well.


The reason that your original attempt failed is that #if…#else…#end in Swift is syntactical, not lexical. That is, each enclosed piece must be properly formed syntactically. Your code isn't syntactically correct because the braces don't match properly. To get this to work, you'd have to put one version of the entire extension after the #if, and another after the #else.


In this case, you don't really want to duplicate the body of the extension in the source code, so typealias is the best way to go.

That technique is called shimming and is not recommended by Apple because it is hard to read, maintain and fix. Checkout last year's WWDC titled Sharing Code Between iOS and OSX https://developer.apple.com/videos/wwdc/2014/?id=233 where they showed how they were able to share over 75% of the code of iWorks for iOS and OSX. Instead of shimming, they created wrapper objects for OS specific objects. Unfortunately, the referred sample code in the video called Photo Memories is already gone.

How to extend a class that depends on the OS
 
 
Q