我正在使用CSVImporter窗格来解析从iCloud Drive上传的CSV文件,解析后的每一行的意图都将上传到我的数据库。
执行importFile()
时,它会打印路径,但随后会打印"The CSV file couldn't be read."
Q1:我做错了什么?
import UIKit
import MobileCoreServices
import CSVImporter
class importBatchVC: UIViewController,UIDocumentPickerDelegate,UINavigationControllerDelegate {
var path=""
var docURL = URL(string: "")
@IBAction func chooseDoc(_ sender: Any) {
let importMenu = UIDocumentPickerViewController(documentTypes: [String(kUTTypeContent),String(kUTTypePlainText)], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .formSheet
self.present(importMenu, animated: true, completion: nil
}
@IBAction func importFile(_ sender: Any) {
if docURL==nil {
let alert = UIAlertController(title: "Error", message: "Please select a spreadsheet.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
} else {
do {
self.path = String(describing:docURL)
print(path)
let importer = CSVImporter<[String]>(path: path)
importer.startImportingRecords { $0 }.onFail {
print("The CSV file couldn't be read.")
}.onProgress { importedDataLinesCount in
print("\(importedDataLinesCount) lines were already imported.")
}.onFinish { importedRecords in
print("Did finish import with \(importedRecords.count) records.")
}
}
}
}
@IBAction func cancel(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
print("The Url is : \(String(describing: url))")
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
try FileManager.default.moveItem(at: url.standardizedFileURL, to: documentDirectory.appendingPathComponent(url.lastPathComponent))
self.docURL = documentDirectory.appendingPathComponent(url.lastPathComponent)
print("now check this: \(docURL!)")
} catch {
print(error)
}
}
func documentMenu(_ documentMenu: UIDocumentPickerViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
}
注意:这是重新发布的问题,因为&#34;重复&#34;以上代码是建议的实现。
我的初始和首选实现是通过documentPicker
获取iCloud驱动器文件的链接,并在运行时将其解析/上传到数据库,但我得到的错误与我现在一样:&#34;无法读取CSV文件。&#34;
Leo Dabus提供的解释是:
"UIDocumentPickerModeImport The URL refers to a copy of the selected document. This document is a temporary file. It remains available only until your application terminates. To keep a permanent copy, you must move this file to a permanent location inside your sandbox."
documentDirectory
,有什么办法可以通过我从documentPicker获得的链接解析它吗?
我最初实施的代码:
import UIKit
import MobileCoreServices
import CSVImporter
class importBatchVC: UIViewController,UIDocumentPickerDelegate,UINavigationControllerDelegate {
var path=""
var docURL = URL(string: "")
@IBAction func chooseDoc(_ sender: Any) {
let importMenu = UIDocumentPickerViewController(documentTypes: [String(kUTTypeContent),String(kUTTypePlainText)], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .formSheet
self.present(importMenu, animated: true, completion: nil)
}
@IBAction func importFile(_ sender: Any) {
if docURL==nil {
let alert = UIAlertController(title: "Error", message: "Please select a spreadsheet.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
else{
do {
self.path = docURL!.path
print(path)
let importer = CSVImporter<[String]>(path: path)
importer.startImportingRecords { $0 }.onFinish { importedRecords in
for record in importedRecords {
// record is of type [String] and contains all data in a line
print(record)
}
}
}
}
}
@IBAction func cancel(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
docURL = url as URL
print("The Url is : \(String(describing: url))")
}
func documentMenu(_ documentMenu: UIDocumentPickerViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
}
答案 0 :(得分:1)
Q1:
我在docURL
尝试解析文件时看到的问题如下:
self.path = String(describing:docURL)
这不是将文件URL转换为路径的正确方法。正确的代码是:
self.path = docURL.path
Q2:
在UIDocumentPickerViewController
模式下使用import
时,委托方法中给出的URL仅在委托方法结束前有效。这就是您必须复制/移动所选文件的原因。
来自文档:
URL指的是所选文档的副本。这些文件是临时文件。它们仅在您的应用程序终止之前保持可用。要保留永久副本,请将这些文件移动到沙箱中的永久位置。
所以是的,你必须复制一份。但是,您可以在解析文件后删除该文件。