简体   繁体   中英

Cannot access file after moving it to documents directory

I have an App that uses CloudKit as backend, which has some CKRecords with some CKAssets

Some of those assets are PDF files, and I'm failing to open them in the QuickLook Previewer

After fetching the records, I save the CKAsset URLs in an array, with the following code:

guard let assets = attachment["attachments"] as? [CKAsset] else { return }
assets.forEach({ (asset) in
    attachmentsURLs.append(asset.fileURL)
})

Each fileURL gets printed somehow like this:

file:///private/var/mobile/Containers/Data/Application/C4406091-B55C-46AC-A612-69052F2275BB/Library/Caches/CloudKit/34af81edf8344be1cf473ef394e06ccc8e1bc8cf/Assets/85DEDDB6-FB5B-4BC9-AB93-D8951AC304F7.012af7f83e322df6d0d1829b94956e4b829edbe974

The last string : 85DEDDB6-FB5B-4BC9-AB93-D8951AC304F7.012af7f83e322df6d0d1829b94956e4b829edbe974 is the file itself, and having this I try to move this file to DocumentsDirectory .

I try to move them and rename them and give them the specific extension, in this particular case will be .pdf

I do this with the following code:

let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
var url = URL.init(fileURLWithPath: documentsPath)
let component = NSUUID().uuidString + "." + fileExtensions[index]
url.appendPathComponent(component)

do {
    try FileManager.default.moveItem(at: fileURL as URL, to: url)
} catch {
    print("Failed to save attachment with extension with error:", error)
    return
}

As you can see, I move the cached file to documents directory and rename it with a random string + file extension.

Using the iOS Simulator, everything works as expected.

The file gets moved from here: file:///Users/ivancantarino/Library/Developer/CoreSimulator/Devices/CCE2FCA5-05F0-4BB7-9A25-CBC168398A62/data/Containers/Data/Application/561A3461-0048-4676-808F-2D96B74DBDCD/Library/Caches/CloudKit/34af81edf8344be1cf473ef394e06ccc8e1bc8cf/Assets/FADF0479-E7AE-4340-83C5-C9E0889E4E87.012af7f83e322df6d0d1829b94956e4b829edbe974

to here:

file:///Users/ivancantarino/Library/Developer/CoreSimulator/Devices/CCE2FCA5-05F0-4BB7-9A25-CBC168398A62/data/Containers/Data/Application/561A3461-0048-4676-808F-2D96B74DBDCD/Documents/52CAC8CD-EF0E-4E55-8D1B-8B267D07BAAA.pdf

And them I fill the QuickLook datasource and I can visualize the files as expected, however in a real iPhone device this doesn't work.

The preview shows an empty file, with ZERO KB .

On a real device the file gets moved from here:

file:///private/var/mobile/Containers/Data/Application/6870DDC2-32FD-4FF2-89F4-04F87BBE534B/Library/Caches/CloudKit/34af81edf8344be1cf473ef394e06ccc8e1bc8cf/Assets/A187A987-BE4E-4C6A-9CBE-E66F3FEF7333.012af7f83e322df6d0d1829b94956e4b829edbe974

to here:

file:///var/mobile/Containers/Data/Application/6870DDC2-32FD-4FF2-89F4-04F87BBE534B/Documents/FD501C6D-9E95-46DD-BC58-EA2C45B62DAC.pdf

What can be causing this issue?

Why does this works in the simulator and doesn't work on the device?

I've tried a lot of different stuff and this is driving me crazy.

Any hint?

Thank you.

Well, I solved the issue and it was a bit embarrassing to be honest, and I'll explain.

Since I'm using QuickLook framework from Apple, which is pretty amazing in my opinion, I had to implement the QuickLook protocol methods in order to fill the datasource to be able to present the desired files, and the problem was right here.

After fetching the desired files I saved the URLs in a [URL] array.

In the QuickLook protocol method numberOfPreviewItems(:_) I return the [URL].count as the number of items and in the previewController(:_)->QLPreviewItem I was doing the following:

func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
    let doc = URL(fileURLWithPath: attachmentURLs[index].absoluteString)
    return doc as QLPreviewItem
}

But if you notice, the doc variable was initiated with a URL(fileWithPath) and I was passing the URL.absoluteString which doesn't point to the specific file;

Instead I converted that line to the following:

let doc = URL(fileURLWithPath: attachmentURLs[index].path)

Since I want to access the Path of the given cached URL , and by doing this everything worked perfectly.

What was an headache was that with the previous implemented way it worked in the iOS Simulator but not on the real device, and that lead me to seek the answer in different ways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM