如何从文本文件读取数据 iOS 15

发布于 2025-01-10 20:45:22 字数 3286 浏览 0 评论 0原文

更新:此代码在模拟器中有效,但在我的设备上无效。显然,我需要它来同时处理这两个问题。

我已按照教程进行操作,但似乎无法使此功能发挥作用。当用户选择 barButtonItem 时,DocumentPicker 将打开,允许用户选择 .txt 文件。然后,我获取所选文件的 URL 并尝试从中返回一个字符串;但是,我收到以下错误:“无法打开文件“Test.txt”,因为您无权查看它。”我缺少什么?我是否没有在某处请求许可?我尝试清理构建文件夹 - 没有用。

@IBAction func importFileBtnTapped(_ sender: Any) {
        selectFiles()
    }
    
    
    func selectFiles() {
        let types = UTType.types(tag: "txt",
                                 tagClass: UTTagClass.filenameExtension,
                                 conformingTo: nil)
        let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: types)
        documentPickerController.delegate = self
        self.present(documentPickerController, animated: true, completion: nil)
    }
    
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard let myURL = urls.first else {
            let alert = SCLAlertView()
            alert.showError("ERROR", subTitle: "Unable to retrieve document.")
            return
        }
        let text = createStringFromSelectedFile(fileURL: myURL)
        if text == "error" {
            print("ERROR creating a string from the selected file.")
            return
        }
        let separatedStrings = decipherString(text: text)
        if separatedStrings.first == "error" {
            print("ERROR deciphering the string in ClaimInfoViewController")
            return
        }
        for string in separatedStrings {
            print("\(string)")
        }
        print("import result: \(myURL)")
    }
    
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        dismiss(animated: true, completion: nil)
    }
    
    
    func createStringFromSelectedFile(fileURL: URL) -> String {
        var text = String()
        do {
            text = try String(contentsOf: fileURL)
        }
        catch {
            print("ERROR in the createStringFromSelectedFile function in ClaimInfoViewController")
            print("The error: \(error.localizedDescription)")
            let alert = SCLAlertView()
            alert.showError("ERROR", subTitle: "Unable to read the file. Please try again.")
            return "error"
        }
        return text
    }
    
    func decipherString(text: String) -> [String]{
        let newText = text
        let startIndexes = ["<Claim#",
                            "<File#",
                            "<DateOfLoss:"
        ]
        var claimNumber = String()
        var fileNumber = String()
        var dateOfLoss = String()
        
        for indexValue in startIndexes {
            guard let index = newText.firstIndex(of: ">") else { return ["error"] }
            let newString = String(newText[..<index])
            
            if indexValue == "<Claim#" {
                claimNumber = newString
            }
            else if indexValue == "<File#" {
                fileNumber = newString
            }
            else if indexValue == "<DateOfLoss:" {
                dateOfLoss = newString
            }
        }
        
        let finalText = [claimNumber, fileNumber, dateOfLoss]
        
        return finalText
    }

Update: This code works in the simulator, but not on my device. Obviously, I'm needing it to work on both.

I've followed the tutorials, yet I cannot seem to get this feature to work. When the user selects the barButtonItem, DocumentPicker opens allowing the user to select a .txt file. I then take the URL to the selected file and attempt to return a string from it; however, I'm getting the following error: "The file “Test.txt” couldn’t be opened because you don’t have permission to view it." What am I missing? Did I fail to ask for permission somewhere? I've tried cleaning the build folder - didn't work.

@IBAction func importFileBtnTapped(_ sender: Any) {
        selectFiles()
    }
    
    
    func selectFiles() {
        let types = UTType.types(tag: "txt",
                                 tagClass: UTTagClass.filenameExtension,
                                 conformingTo: nil)
        let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: types)
        documentPickerController.delegate = self
        self.present(documentPickerController, animated: true, completion: nil)
    }
    
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard let myURL = urls.first else {
            let alert = SCLAlertView()
            alert.showError("ERROR", subTitle: "Unable to retrieve document.")
            return
        }
        let text = createStringFromSelectedFile(fileURL: myURL)
        if text == "error" {
            print("ERROR creating a string from the selected file.")
            return
        }
        let separatedStrings = decipherString(text: text)
        if separatedStrings.first == "error" {
            print("ERROR deciphering the string in ClaimInfoViewController")
            return
        }
        for string in separatedStrings {
            print("\(string)")
        }
        print("import result: \(myURL)")
    }
    
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        dismiss(animated: true, completion: nil)
    }
    
    
    func createStringFromSelectedFile(fileURL: URL) -> String {
        var text = String()
        do {
            text = try String(contentsOf: fileURL)
        }
        catch {
            print("ERROR in the createStringFromSelectedFile function in ClaimInfoViewController")
            print("The error: \(error.localizedDescription)")
            let alert = SCLAlertView()
            alert.showError("ERROR", subTitle: "Unable to read the file. Please try again.")
            return "error"
        }
        return text
    }
    
    func decipherString(text: String) -> [String]{
        let newText = text
        let startIndexes = ["<Claim#",
                            "<File#",
                            "<DateOfLoss:"
        ]
        var claimNumber = String()
        var fileNumber = String()
        var dateOfLoss = String()
        
        for indexValue in startIndexes {
            guard let index = newText.firstIndex(of: ">") else { return ["error"] }
            let newString = String(newText[..<index])
            
            if indexValue == "<Claim#" {
                claimNumber = newString
            }
            else if indexValue == "<File#" {
                fileNumber = newString
            }
            else if indexValue == "<DateOfLoss:" {
                dateOfLoss = newString
            }
        }
        
        let finalText = [claimNumber, fileNumber, dateOfLoss]
        
        return finalText
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷雾森÷林ヴ 2025-01-17 20:45:22

感谢上面评论的马特,我能够发现这是一个安全问题。添加这个简单的代码解决了这个问题:

let shouldStopAccessing = pickedFolderURL.startAccessingSecurityScopedResource()
        defer {
          if shouldStopAccessing {
            pickedFolderURL.stopAccessingSecurityScopedResource()
          }
       }

我在上面可以看到的这行代码之前添加了它:

let text = createStringFromSelectedFile(fileURL: myURL)

我从这里得到了这个代码: StackOverflow 帖子

Thanks to matt, who commented above, I was able to find out that it's a security issue. Adding this simple code resolved the issue:

let shouldStopAccessing = pickedFolderURL.startAccessingSecurityScopedResource()
        defer {
          if shouldStopAccessing {
            pickedFolderURL.stopAccessingSecurityScopedResource()
          }
       }

I added it right before this line of code that can be seen above:

let text = createStringFromSelectedFile(fileURL: myURL)

I got this code from here: StackOverflow Post

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文