【问题标题】:Trouble working with basic file system functionality in Swift 2.0在 Swift 2.0 中使用基本文件系统功能时遇到问题
【发布时间】:2016-02-24 17:38:05
【问题描述】:

尝试使用 Xcode 7.1 在 iOS 9.1 上的 Swift 2.0 中创建一个简单的示例代码块。在techotopia 试过这篇文章;我怀疑它基于 swift 1.2。

进行了一些微小的更改,以便它可以编译和运行,但是虽然它似乎可以工作,但它似乎并没有将我的字符串保存到文件中。有没有我在这里错过的能力或一些微妙的东西。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textBox: UITextField!

    var fileMgr: NSFileManager = NSFileManager.defaultManager()
    var docsDir: String?
    var dataFile: String?
    var string: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        let dirPaths = NSSearchPathForDirectoriesInDomains(
            .DocumentDirectory, .UserDomainMask, true)

        docsDir = dirPaths[0] as String
        let dataFile = NSURL(fileURLWithPath: docsDir!).URLByAppendingPathComponent("datafile.dat")

        string = "\(dataFile)"
        print(string)
        if fileMgr.fileExistsAtPath(string) {
            let databuffer = fileMgr.contentsAtPath(string)
            let datastring = NSString(data: databuffer!,
                encoding: NSUTF8StringEncoding)
            textBox.text = datastring as? String
        }
    }

    @IBAction func saveText(sender: AnyObject) {
        let databuffer = (textBox.text)
        let data = databuffer?.dataUsingEncoding(NSUTF8StringEncoding)

        fileMgr.createFileAtPath(string, contents: data,
            attributes: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

更多测试;注意到当我尝试创建文件时出现此错误... __connection_block_invoke_2 中的错误:连接中断;这解释了为什么它不起作用,如果我能锻炼它在说什么?

继续尝试调试;添加了 UIFileSharingEnabled 但看不到 Documents 目录;添加了更多代码来测试它的存在,如果缺失则创建它;没有告诉我它已经在那里......即使它显然是不可见的......

【问题讨论】:

    标签: ios swift file-io filesystems nsfilemanager


    【解决方案1】:

    当你这样做时,string 最终成为文件 URL 的字符串表示,例如file://...file:// 前缀是 URL“方案”(如 http://ftp://)。但是在字符串的开头包含方案意味着这不是一个有效的路径。您必须删除该方案。

    最简单的方法是使用path 方法从NSURL 获取路径,而不使用该方案。我现在也会使用URLForDirectory 来获取文档文件夹的 URL。

    class ViewController: UIViewController {
    
        @IBOutlet weak var textBox: UITextField!
    
        lazy var fileMgr = NSFileManager.defaultManager()
        var path: String!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let documents = try! fileMgr.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            path = documents.URLByAppendingPathComponent("datafile.dat").path
    
            if fileMgr.fileExistsAtPath(path) {
                if let data = fileMgr.contentsAtPath(path) {
                    textBox.text = String(data: data, encoding: NSUTF8StringEncoding)
                }
            }
        }
    
        @IBAction func saveText(sender: AnyObject) {
            let data = textBox.text?.dataUsingEncoding(NSUTF8StringEncoding)
    
            fileMgr.createFileAtPath(path, contents: data, attributes: nil)
        }
    
    }
    

    或者我可能完全停留在 URL 的世界中,完全停用路径,还使用抛出有意义的错误消息的方法:

    class ViewController: UIViewController {
    
        @IBOutlet weak var textBox: UITextField!
    
        lazy var fileMgr = NSFileManager.defaultManager()
        var fileURL: NSURL!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            do {
                let documents = try fileMgr.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
                fileURL = documents.URLByAppendingPathComponent("datafile.dat")
    
                var reachableError: NSError?
                if fileURL.checkResourceIsReachableAndReturnError(&reachableError) {
                    textBox.text = try String(contentsOfURL: fileURL)
                }
            } catch {
                print(error)
            }
        }
    
        @IBAction func saveText(sender: AnyObject) {
            do {
                try textBox.text?.writeToURL(fileURL, atomically: true, encoding: NSUTF8StringEncoding)
            } catch {
                print(error)
            }
        }
    
    }
    

    【讨论】:

    • 使用了第二个窗口解决方案,效果很好;优秀的代码。谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多