0

User picks document from UIDocumentPickerViewController that i will be working with later. Document picker delegate calls and gives me url for file, but there is no file at all.

This is how i create documentPicker. I use supportedFiles because typing manually extension doesn't work for me

let supportedFiles: [UTType] = [UTType.data]
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: supportedFiles)
documentPicker.delegate = self
documentPicker.modalPresentationStyle = .fullScreen
present(documentPicker, animated: true, completion: nil)

There is documentPicker delegate with all checks

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {

        var path = urls.first!.path
        let stream = InputStream(url: URL(fileURLWithPath: path))
        print(path)
        print(FileManager.default.fileExists(atPath: path))

        do {
            let items = try FileManager.default.contentsOfDirectory(atPath: path)
            print(items.count)
            for item in items {
                print("Found (item)")
            }
        } catch {
            print(error)
        }

        do {
            let csv = try CSVReader(stream: stream!)
            print("Everything is ok")
            while let row = csv.next() {
                print(row)
            }
        } catch {
            print(error)
        }
    }

And console show me this

/private/var/mobile/Containers/Shared/AppGroup/3232A257-B8F6-4F39-A12B-A7192EBF9524/File Provider Storage/Games.csv
false
Error Domain=NSCocoaErrorDomain Code=256 "The file “Games.csv” couldn’t be opened." UserInfo={NSUserStringVariant=(
    Folder
), NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/3232A257-B8F6-4F39-A12B-A7192EBF9524/File Provider Storage/Games.csv, NSUnderlyingError=0x282a277e0 {Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}
cannotOpenFile

As i understand i got url for file that does not exists? Then why fileManager gives me an error that this file is not a directory instead of saying that there is nothing at this url? There was also an error that i dont have permission to read this file, so i changed it to be readable. That means that it can see it, but it can't? I just dont understand.

Also tried to change path by deleting /private but it didnt work

Update:

When trying to get list of items in folder in which Games.svc is located I get another error

Error Domain=NSCocoaErrorDomain Code=257 "The file “File Provider Storage” couldn’t be opened because you don’t have permission to view it." UserInfo={NSUserStringVariant=(
    Folder
), NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/3232A257-B8F6-4F39-A12B-A7192EBF9524/File Provider Storage/, NSUnderlyingError=0x2819254d0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
8
  • "And console show me this" What is 'this'? You have eight lines with print(). Commented Jul 28, 2021 at 20:24
  • @ElTomato right after words "And console show me this" i wrote result in my console Commented Jul 28, 2021 at 20:55
  • Oh, okay, sorry about that. So you get 'this' as a result of which line? Commented Jul 28, 2021 at 21:01
  • @ElTomato From all of them. First line is the path. Second is file in this path exists. Third and fourth is the error i get from trying to open this file as a folder. Fifth line just an error from trying to decode this file. Also i will make an update on post right now Commented Jul 28, 2021 at 21:11
  • Whats the point of creating an url from the path of another url? Just use urls.first Commented Jul 29, 2021 at 1:30

1 Answer 1

-1

Found apple documentation about getting access to directories. Edited my code to this and now it is working

guard urls.first!.startAccessingSecurityScopedResource() else {
     print("Error getting access")
     return
}

defer { urls.first!.stopAccessingSecurityScopedResource() }

let path = urls.first!.path
let stream = InputStream(url: URL(fileURLWithPath: path))

do {
      let csv = try CSVReader(stream: stream!)
      print("Everything is ok")
      while let row = csv.next() {
      print(row)
}
      URL(fileURLWithPath: path).stopAccessingSecurityScopedResource()
} catch {
      print(error)
}

Basically before working with the URL you get the request to use secured URL by this function

guard urls.first!.startAccessingSecurityScopedResource() else {
     print("Error getting access")
     return
}

defer { urls.first!.stopAccessingSecurityScopedResource() }

And end working with secured connection by writing this line

URL(fileURLWithPath: path).stopAccessingSecurityScopedResource()

However code written in documentation is not working for me, and error check(that i deleted) still giving me an error

Update

If code is not working, you can delete this line

defer { urls.first!.stopAccessingSecurityScopedResource() }
Sign up to request clarification or add additional context in comments.

7 Comments

If this is not the answer, don't put it in the Answer field.
@matt this is the answer
Then what is the stuff about "not working for me" and "giving me an error" about?
Also, since the documentation is quite clear that the URL provided by a document picker is security scoped and must be treated accordingly, it isn't clear how this question and answer is useful. Basically aren't you simply saying that you've recently discovered something that is already generally well known?
@matt it is about recommended code in Apple documentation, not about my code. My code working fine
|

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.