1

We have an implementation with the UIDocumentPickerViewController that looks something like this:

case .openInitialization:
    // Setup UIDocumentPicker.
    if #available(iOS 14, *) {
        documentsPicker = UIDocumentPickerViewController(forOpeningContentTypes: [
            UTType.text,
            UTType.utf8PlainText,
            UTType.flatRTFD,
            UTType.pdf])
    } else {
        documentsPicker = UIDocumentPickerViewController(documentTypes: [
            String(kUTTypeText),
            String(kUTTypeUTF8PlainText),
            String(kUTTypeFlatRTFD),
            String(kUTTypePDF)], in: .open)
    }

Everything works great and we can select a document. When we select a document we get a document url but in some cases (especially with one drive) we get issues when we want to turn the url into a bookmark. Following code returns nil:

guard let bookmark = try? url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil) else { return }

Do anyone have an idea to why this is happening? Or what we can do to get it to work without returning nil?

Edit:

We've tryed to add try catch and we got following error which doesn't quite help much: Error Domain=NSCocoaErrorDomain Code=260 (file doesn't exist).

Edit 2:

So if I open from archive directly into our app it works no issues at all. But we still need to work from UIDocumentPickerViewController.

Also for some reasons files unlocked this way will just work from UIDocumentPickerViewController afterward.

Files can also be opened from onedrive and from there be opened in another app (ours). But this does't and gives a file does not exist error as well.

Edit 3: So I've tested and read a ton. I can tell that following will return false for some files picked by documentpicker:

var exist = FileManager.default.fileExists(atPath: url.path)

But again if I open the file just once from iOS archive app it will work perfectly fine afterward. If there just were some way to tell it to update/download like apples does.

Edit 4: I've made a sample project demonstrating the problem at github .

Warpzit
  • 27,966
  • 19
  • 103
  • 155

2 Answers2

1

I answered a similar question here: PDFKit doesn’t work on iPads while works fine on a simulator [iOS, Swift]

Can you check if wrapping your url in a security access scope helps?:

url.startAccessingSecurityScopedResource()
print(FileManager.default.fileExists(atPath: url.path))
url.stopAccessingSecurityScopedResource()

The above should print true. This is because these API's access files outside of the applications sandbox.

See: https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories

Rufus Mall
  • 569
  • 4
  • 14
  • I did try this and the file doesn't exist. But it is clearly present and in existence. If I open through archive it works. – Warpzit Nov 03 '21 at 08:26
  • Ahh sorry for providing false info. Can you put a sample project on github? I am busy at the moment but would be intersted in taking a look in the future to see if I can work out the problem. – Rufus Mall Nov 03 '21 at 15:17
  • I can try to see if I can make a sample project. It would be good to eliminate all other noises to make sure I'm not missing something. Give me some time though ;) – Warpzit Nov 04 '21 at 09:15
  • Sorry for the delay Rufus: https://github.com/vitec-mv/iosdocpicker – Warpzit Nov 08 '21 at 12:31
  • So apparently we need to wrap the call to bookmark with a NSFileCoordinator. I've added the answer apple came up with from a technical ticket. – Warpzit Nov 19 '21 at 07:02
1

Used a technical ticket for apple and they came with a solution :D

NSFileCoordinator().coordinate(readingItemAt: url, options: .withoutChanges, error:&err, byAccessor: { (newURL: URL) -> Void in
  do {
    let bookmark = try newURL.bookmarkData()
  } catch let error {
    print("\(error)")
  }
})

if let err = err {
  print(err.localizedDescription)
}
Warpzit
  • 27,966
  • 19
  • 103
  • 155
  • 1
    Nice one! I have never heard of that before. I always forgt about those apple tech tickets. Thanks for sharing!! – Rufus Mall Nov 19 '21 at 15:42