Property cannot be declared open because its type uses an internal type (Typealias)

3.3k views Asked by At

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".

1

There are 1 answers

4
Eneko Alonso On BEST ANSWER

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.