如何在Swift中找到NSDocumentDirectory?

 happy玛奇朵_387 发布于 2023-01-11 15:29

我正在尝试使用代码获取Documents文件夹的路径:

var documentsPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory:0,NSSearchPathDomainMask:0,true)

但Xcode给出了错误: Cannot convert expression's type 'AnyObject[]!' to type 'NSSearchPathDirectory'

我试图了解代码中的错误.

8 个回答
  • 显然,编译器认为NSSearchPathDirectory:0是一个数组,当然它期望类型NSSearchPathDirectory.当然不是一个有用的错误消息.

    但至于原因:

    首先,您会混淆参数名称和类型.看一下函数定义:

    func NSSearchPathForDirectoriesInDomains(
        directory: NSSearchPathDirectory,
        domainMask: NSSearchPathDomainMask,
        expandTilde: Bool) -> AnyObject[]!
    

    directory并且domainMask是名称,您使用的是类型,但是无论如何都应该将它们留给函数.它们主要用于方法.

    此外,Swift是强类型的,所以你不应该只使用0.使用枚举的值代替.

    最后,它返回一个数组,而不仅仅是一个路径.

    这样就离开了我们(为Swift 2.0更新):

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
    

    对于Swift 3:

    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    

    2023-01-11 15:30 回答
  • 现代建议使用NSURLs代替基于NSString的路径的文件和目录:

    在此输入图像描述

    因此,要将应用程序的Document目录作为NSURL获取:

    func databaseURL() -> NSURL? {
    
        let fileManager = NSFileManager.defaultManager()
    
        let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    
        if let documentDirectory: NSURL = urls.first as? NSURL {
            // This is where the database should be in the documents directory
            let finalDatabaseURL = documentDirectory.URLByAppendingPathComponent("items.db")
    
            if finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) {
                // The file already exists, so just return the URL
                return finalDatabaseURL
            } else {
                // Copy the initial file from the application bundle to the documents directory
                if let bundleURL = NSBundle.mainBundle().URLForResource("items", withExtension: "db") {
                    let success = fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL, error: nil)
                    if success {
                        return finalDatabaseURL
                    } else {
                        println("Couldn't copy file to final location!")
                    }
                } else {
                    println("Couldn't find initial database in the bundle!")
                }
            }
        } else {
            println("Couldn't get documents directory!")
        }
    
        return nil
    }
    

    这有一个基本的错误处理,因为这取决于你的应用程序在这种情况下会做什么.但是这会使用文件URL和更现代的api来返回数据库URL,如果它不存在则将初始版本复制到bundle之外,或者在出现错误时将其复制为nil.

    2023-01-11 15:30 回答
  • Swift 3.0和4.0

    如果找不到路径,直接从数组中获取第一个元素可能会导致异常.所以调用first然后解包是更好的解决方案

    if let documentsPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
        //This gives you the string formed path
    }
    
    if let documentsPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        //This gives you the URL of the path
    }
    

    2023-01-11 15:30 回答
  • 通常我会首先使用此扩展名:

    Swift 3.x和Swift 4.0:

    extension FileManager {
        class func documentsDir() -> String {
            var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as [String]
            return paths[0]
        }
    
        class func cachesDir() -> String {
            var paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true) as [String]
            return paths[0]
        }
    }
    

    Swift 2.x:

    extension NSFileManager {
        class func documentsDir() -> String {
            var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as [String]
            return paths[0]
        }
    
        class func cachesDir() -> String {
            var paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true) as [String]
            return paths[0]
        }
    }
    

    2023-01-11 15:32 回答
  • Xcode 8.2.1•Swift 3.0.2

    let documentDirectoryURL =  try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    

    Xcode 7.1.1•Swift 2.1

    let documentDirectoryURL =  try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
    

    2023-01-11 15:32 回答
  • 对于看起来与Swift 2.2一起使用的示例的每个人,使用现代的Abizern代码尝试捕获错误句柄

    func databaseURL() -> NSURL? {
    
        let fileManager = NSFileManager.defaultManager()
    
        let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    
        if let documentDirectory:NSURL = urls.first { // No use of as? NSURL because let urls returns array of NSURL
            // This is where the database should be in the documents directory
            let finalDatabaseURL = documentDirectory.URLByAppendingPathComponent("OurFile.plist")
    
            if finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) {
                // The file already exists, so just return the URL
                return finalDatabaseURL
            } else {
                // Copy the initial file from the application bundle to the documents directory
                if let bundleURL = NSBundle.mainBundle().URLForResource("OurFile", withExtension: "plist") {
    
                    do {
                        try fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL)
                    } catch let error as NSError  {// Handle the error
                        print("Couldn't copy file to final location! Error:\(error.localisedDescription)")
                    }
    
                } else {
                    print("Couldn't find initial database in the bundle!")
                }
            }
        } else {
            print("Couldn't get documents directory!")
        }
    
        return nil
    }
    

    更新 我错过了新的swift 2.0有防范(Ruby除非是模拟),所以有了防范它更短更可读

    func databaseURL() -> NSURL? {
    
    let fileManager = NSFileManager.defaultManager()
    let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    
    // If array of path is empty the document folder not found
    guard urls.count != 0 else {
        return nil
    }
    
    let finalDatabaseURL = urls.first!.URLByAppendingPathComponent("OurFile.plist")
    // Check if file reachable, and if reacheble just return path
    guard finalDatabaseURL.checkResourceIsReachableAndReturnError(nil) else {
        // Check if file is exists in bundle folder
        if let bundleURL = NSBundle.mainBundle().URLForResource("OurFile", withExtension: "plist") {
            // if exist we will copy it
            do {
                try fileManager.copyItemAtURL(bundleURL, toURL: finalDatabaseURL)
            } catch let error as NSError { // Handle the error
                print("File copy failed! Error:\(error.localizedDescription)")
            }
        } else {
            print("Our file not exist in bundle folder")
            return nil
        }
        return finalDatabaseURL
    }
    return finalDatabaseURL 
    }
    

    2023-01-11 15:32 回答
  • 更方便的Swift 3方法:

    let documentsUrl = FileManager.default.urls(for: .documentDirectory, 
                                                 in: .userDomainMask).first!
    

    2023-01-11 15:32 回答
  • Xcode 8b4 Swift 3.0

    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
    

    2023-01-11 15:34 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有