1

I am writing a macOS application with Swift using story boards. I have a NSTableView which contains files that I want the user to be able to preview via QuickLook.

I seemingly have everything in place and my code looks very similar to what has been described here: QuickLook consumer as a delegate from an NSViewController, but I keep getting the error

-[QLPreviewPanel setDataSource:] called while the panel has no controller - Fix this or this will raise soon.
    See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.

I've been trying to adapt the solution of above post to my situation with Swift and story boards.

The main pieces are:

import Quartz

class ViewController: NSViewController, QLPreviewPanelDataSource, QLPreviewPanelDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        let windowNextResponder = self.view.window?.nextResponder
        self.view.window?.nextResponder = self
        self.nextResponder = windowNextResponder
    }

    // *** Quicklook stuff ***

    @IBAction func quickLookButtonAction(_ sender: Any) {
        guard qlPanel != nil else {
            return
        }

        if qlPanel!.currentController == nil {
            print ("No controller")
            //qlPanel!.windowController = self.view.window?.windowController
            // qlPanel!.updateController()
        } else {
            print (qlPanel!.currentController)
        }
        qlPanel!.delegate = self
        qlPanel!.dataSource = self

        qlPanel!.makeKeyAndOrderFront(self)
    }

    func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
        return CSVarrayController.selectedObjects.count
    }

    func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
        let file = CSVarrayController.selectedObjects[index] as! CSVfile
        return file.url as NSURL
    }
    override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
        return true
    }
    override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
        panel.dataSource = self
        panel.delegate = self
    }

    override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
        panel.dataSource = nil
        panel.delegate = nil
    }
} 

With or without messing with the responder chain I get the error. The delegate functions all get called as expected as well.

1 Answers1

1

Remove

qlPanel!.delegate = self
qlPanel!.dataSource = self

in quickLookButtonAction, the viewcontroller isn't in control yet. Wait for beginPreviewPanelControl.

From the documentation for currentController:

You should never change the preview panel’s state (its delegate, datasource, and so on) if you are not controlling it.

From comments in QLPreviewPanel.h for -beginPreviewPanelControl::

Sent to the object taking control of the Preview Panel.

The receiver should setup the preview panel (data source, delegate, binding, etc.) here.

Community
  • 1
  • 1
Willeke
  • 14,578
  • 4
  • 19
  • 47
  • Tried it. It's accepting control, beginning control, providing a count (several times) as well as providing the file to display, and the empty panel is shown with the "spinner". Then nothing happens for 6-7 seconds before it crashes without any info, unfortunately. – Rene Rosendahl Sep 01 '19 at 23:14
  • That said, the original error message does not appear any more, so I guess this is progress.... :) – Rene Rosendahl Sep 01 '19 at 23:34
  • I tried your code and it's working for me. Does Quick Look from the Finder work? – Willeke Sep 02 '19 at 00:30