mattmassicotte / nsui

AppKit and UIKit without conditional compilation
BSD 3-Clause "New" or "Revised" License
56 stars 4 forks source link

Handling optionality differences #7

Closed mattmassicotte closed 6 months ago

mattmassicotte commented 7 months ago

NSTextView.layoutManger -> NSLayoutManager? UITextView.layoutManage ->NSLayoutManager NSFont.init(descriptor:, size:)` is failable in AppKit but not in UIKit.

These differ only by optionality, which is a real pain. The initializer seems particularly tricky to handle.

mattmassicotte commented 7 months ago

@martindufort do you have thoughts on this?

martindufort commented 7 months ago

Hey @mattmassicotte Nice Friday to you.

That's a very good question. Not sure how to handle this without breaking the simple "find and replace" ease of use of NSUI.

Do we want AppKit user to check for a failable initializer? Probably not but perhaps that's the only solution. Need to think...

mattmassicotte commented 7 months ago

Here are things that already exist, in case that's interesting.

extension Image {
    public init(nsuiImage: NSUIImage)
}

extension ImageRenderer {
    public var nsuiImage: NSUIImage?
}

However, ImageRenderer returns an optional image in both cases so it was easy there.

mattmassicotte commented 6 months ago

I oped for this:

extension NSUITextView {
    /// NSUI wrapper around `layoutManager` property.
    ///
    /// This value can be nil on macOS.
    public var nsuiLayoutManager: NSLayoutManager? {
        layoutManager
    }
}

extension NSUIFont {
    /// NSUI wrapper around `init`.
    ///
    /// This initializer can fail on macOS.
    public convenience init?(nsuiDescriptor: NSUIFontDescriptor, size: CGFloat) {
        self.init(descriptor: nsuiDescriptor, size: size)
    }
}

I think this is a reasonable approach, and is easy to understand. These callsites will always need to be platform-specific, so seeing the nsui prefix helps to make that clear.

mattmassicotte commented 6 months ago

Oh, I also added something neat on main you might like:

import NSUI

Via tricks, this now automatically imports AppKit or UIKit as needed. I found that pretty annoying and this is way better!