swiftquicklookqlpreviewcontrollerfiles-app

Unable to preview files with QuickLook


I am using this simple tool for previewing different files in my app, but none of them is being successfully previewed.

First time I try to preview any file it opens preview controller with message Unsupported file format, and any other time it just displays filename and word data(see images).

Here is the implementation(Pay attention on the print statements):

extension FileShareVC: QLPreviewControllerDataSource, QLPreviewControllerDelegate {
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        filesList.count
    }
    
    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
        
        let url = NSURL(fileURLWithPath: filesList[index].filePath ?? "", isDirectory: false)
        print(filesList[index].filePath!)
        //prints file:///var/mobile/Containers/Data/Application/AB608864-C682-47BB-8396-2D456430879E/Documents/F9RIB62HBUAW.jpeg
        print("url: \(url)")
        //prints file:/var/mobile/Containers/Data/Application/AB608864-C682-47BB-8396-2D456430879E/Documents/F9RIB62HBUAW.jpeg -- file:///
        return url
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
                  
        let quickLookViewController = QLPreviewController()
        quickLookViewController.dataSource = self
        quickLookViewController.delegate = self
        quickLookViewController.currentPreviewItemIndex = indexPath.row
        present(quickLookViewController, animated: true)
    }

I am not sure why my url appends -- file:/// on the file path, maybe that causes the problem?

img1 img2


Solution

  • The issue is that you are using the wrong initializer. You are passing an absoluteString to the initializer that expects a path (your string contains the scheme file://). Btw calling filePath an absoluteString is misleading.

    guard let url = URL(string: filesList[index].filePath ?? "") else {
        return // an alternate URL or a just create a fatalError
    }
    

    Also note that your app is sandboxed and its location will change on every launch. If you need to persist that info you should save only its name and directory and recompose your URL when needed.


    edit update:

    Note that you are not supposed to place your files directly to the library folder. file system basics

    enter image description here