0

I am trying to load a NIB from file.

I have this code, from here

protocol NibLoadable {
  static var nibName: String? { get }
  static func createFromNib(in bundle: Bundle) -> Self?
}

extension NibLoadable where Self: NSView {

  static var nibName: String? {
    return String(describing: Self.self)
  }

  static func createFromNib(in bundle: Bundle = Bundle.main) -> Self? {
    guard let nibName = nibName else { return nil }
    var topLevelArray: NSArray? = nil
    bundle.loadNibNamed(NSNib.Name(nibName), owner: self, topLevelObjects: &topLevelArray)
    guard let results = topLevelArray else { return nil }
//    let views = Array<Any>(results).filter { $0 is Self }
//    return views.last as? Self
    let element =      results[0] as? Self

    return results[0] as? Self
  }
}

results have two elements, a NSView and NSApplication.

The problem here is the element is nil. The commented code was also giving me nil there.

I am new to swift. What is this Self delivering or what it represents on the last line of createFromNib?

2
  • what happens if you do let element = results[1] as? Self. Is it still nil? Commented Jun 26, 2019 at 12:58
  • yes. Still nil. Commented Jun 26, 2019 at 13:28

2 Answers 2

1

It's not guaranteed that the first object is the requested view.

Get the proper view with first(where

And declare nibName non-optional as a requirement.

protocol NibLoadable {
    static var nibName: String { get }
    static func createFromNib(in bundle: Bundle) -> Self?
}

extension NibLoadable where Self: NSView {    
    static var nibName: String {
        return String(describing: Self.self)
    }

    static func createFromNib(in bundle: Bundle = Bundle.main) -> Self? {
        var topLevelArray: NSArray? // Optionals are nil by default
        bundle.loadNibNamed(NSNib.Name(nibName), owner: self, topLevelObjects: &topLevelArray)
        return topLevelArray?.first(where: { $0 is Self }) as? Self
    }
}
Sign up to request clarification or add additional context in comments.

10 Comments

createFromNib still returning nil.
How do you call createFromNib? Is the nib name correct?
let myView : MyClass = MyClass.createFromNib() where MyClass is the name of the class this code is into.
What exactly is this Self supposed to return?
Self is the current type.
|
0

After hours trying to fiddle with non-existent documentation, I have come with this, much simpler.

  func loadViewFromNib() {

    var topLevelArray : NSArray?

    let bundle = Bundle(for: type(of: self))
    let nib = NSNib(nibNamed: .init(String(describing: type(of: self))), bundle: bundle)!
    nib.instantiate(withOwner: self, topLevelObjects: &topLevelArray)

    let myView = topLevelArray?.first(where: { $0 is NSView }) as? NSView
    addSubview(myView!)
}

Thanks @vadian for all the effort.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.