Reputation: 16256
I have seen this trick to implement a platform-agnostic interface to (say) the image classes UIImage/NSImage:
#if os(iOS)
import UIKit
typealias Image = UIImage
#elseif os(macOS)
import Cocoa
typealias Image = NSImage
#endif
Now I am trying to adopt it in a framework. Let's say I have a class like this:
public final class MyClass {
public var image: Image // < Compiler Error (see below)
init?(imageURL: URL) {
guard let image = Image(contentsOf: imageFileURL) else {
return nil
}
self.image = image
}
}
I get the error:
Property cannot be declared open because its type uses an internal type
Is the "internal type" refering to NSImage? How do I get around this?
Note: I don't think this a duplicate of this question: I am using a typealias, it is not evident what declaration I sould mark as "public".
Upvotes: 1
Views: 3383
Reputation: 19692
In this specific case (when used within a framework target), making the typealias
public will not solve the issue. You need to use the platform condition check also when declaring the image property, as follows:
#if os(iOS)
import UIKit
typealias Image = UIImage
#elseif os(macOS)
import Cocoa
typealias Image = NSImage
#endif
public final class MyClass {
#if os(iOS)
public var image: UIImage
#elseif os(macOS)
public var image: NSImage
#endif
init?(imageURL: URL) {
guard let image = Image(contentsOf: imageFileURL) else {
return nil
}
self.image = image
}
}
The same applies for any public methods that use this type, whether it is a parameter or the return type of a function.
Offtopic: Make sure to initialize this class on a background queue/thread to avoid blocking the main thread and freezing the UI while the image is being downloaded.
Upvotes: 1