Swift 4.1中删除用户选中文件的函数失效问题排查
排查Swift中UIAlertAction handler传参删除文件失效的问题
我来帮你分析下这个问题的根源,以及对应的解决办法:
核心问题:文件名后缀重复拼接
你的deleteFileSelected函数里,会自动给传入的fileName拼接.txt后缀:
let searchfilePath = NSString(format:"%@/%@.txt", directoryPath, fileName) as String
但如果你的listFilesPresent()函数返回的文件名已经包含了.txt后缀(比如返回的是"test.txt"而不是"test"),那拼接后的路径就会变成"Documents/test.txt.txt"——这样自然找不到目标文件,删除操作也就失效了。
而你单独传参时偶尔有效,大概率是因为你手动传入的是不带后缀的文件名,刚好匹配了函数里的拼接逻辑。
辅助问题:闭包捕获与代码优化
另外还有几个小细节可以优化,避免潜在问题:
- 你的
deleteFileSelected函数声明返回[String]?但实际返回nil,改成Void类型更合理; - 用
URL而非字符串拼接路径,更安全且符合Swift的现代写法; - 闭包中添加
[weak self]避免循环引用,同时显式捕获变量避免意外;
完整修复后的代码
1. 根据文件列表返回值调整删除函数
情况1:listFilesPresent()返回带.txt后缀的文件名
去掉函数里多余的后缀拼接:
func deleteFileSelected(fileName: String) { guard let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { print("无法获取Documents目录") return } let fileURL = directoryPath.appendingPathComponent(fileName) if FileManager.default.fileExists(atPath: fileURL.path) { do { try FileManager.default.removeItem(at: fileURL) print("文件已删除:\(fileName)") } catch { print("删除失败:\(error.localizedDescription)") } } else { print("目标文件不存在:\(fileURL.path)") } }
情况2:listFilesPresent()返回不带后缀的文件名
保留后缀拼接,但用URL方式实现:
func deleteFileSelected(fileName: String) { guard let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { print("无法获取Documents目录") return } let fileURL = directoryPath.appendingPathComponent("\(fileName).txt") if FileManager.default.fileExists(atPath: fileURL.path) { do { try FileManager.default.removeItem(at: fileURL) print("文件已删除:\(fileName).txt") } catch { print("删除失败:\(error.localizedDescription)") } } else { print("目标文件不存在:\(fileURL.path)") } }
2. 优化Alert创建逻辑(更健壮)
直接遍历文件列表添加所有删除选项,同时处理无文件的情况:
@IBAction func deleteConfigAction(_ sender: Any) { guard let userFilesPresent = listFilesPresent(), !userFilesPresent.isEmpty else { // 没有文件时提示用户 let alert = UIAlertController(title: "提示", message: "当前没有可删除的文件", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .cancel)) present(alert, animated: true) return } let alert = UIAlertController(title: "删除文件", message: "选择要删除的文件", preferredStyle: .alert) for fileName in userFilesPresent { alert.addAction(UIAlertAction(title: fileName, style: .default, handler: { [weak self] _ in self?.deleteFileSelected(fileName: fileName) print("要删除的文件:\(fileName)") })) } alert.addAction(UIAlertAction(title: "关闭", style: .cancel)) present(alert, animated: true) }
验证步骤
- 先打印
userFilesPresent的内容,确认返回的文件名是否带后缀; - 在
deleteFileSelected里打印fileURL路径,对比实际文件路径是否一致; - 运行代码,查看控制台打印信息,确认文件是否存在、删除是否成功。
内容的提问来源于stack exchange,提问作者nar0909
相关产品推荐
相关产品推荐

