programing

Swift에서 NSDocument Directory를 찾는 방법은 무엇입니까?

sourcejob 2023. 6. 3. 08:25
반응형

Swift에서 NSDocument Directory를 찾는 방법은 무엇입니까?

다음 코드를 사용하여 문서 폴더 경로를 가져오려고 합니다.

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

그러나 Xcode는 다음과 같은 오류를 표시합니다.Cannot convert expression's type 'AnyObject[]!' to type 'NSSearchPathDirectory'

저는 코드에 무엇이 잘못되었는지 이해하려고 노력하고 있습니다.

보아하니 컴파일러가 생각하기에NSSearchPathDirectory:0배열이고, 물론 유형을 예상합니다.NSSearchPathDirectory대신.확실히 유용한 오류 메시지는 아닙니다.

하지만 그 이유에 대해서는:

첫째, 당신은 인수 이름과 유형을 혼동하고 있습니다.기능 정의를 살펴봅니다.

func NSSearchPathForDirectoriesInDomains(
    directory: NSSearchPathDirectory,
    domainMask: NSSearchPathDomainMask,
    expandTilde: Bool) -> AnyObject[]!
  • directory그리고.domainMask이름입니다. 유형을 사용하고 있지만 기능을 위해 제외해야 합니다.주로 방법에 사용됩니다.
  • 또한 스위프트는 강력한 타이핑을 하기 때문에 0만 사용하면 안 됩니다.대신 열거형 값을 사용합니다.
  • 마지막으로, 단일 경로가 아닌 배열을 반환합니다.

이제 Swift 2.0으로 업데이트된 기능은 다음과 같습니다.

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

스위프트 3의 경우:

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

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
}

최신 권장 사항은 NSString 기반 경로 대신 파일 및 디렉토리에 NSURL을 사용하는 것입니다.

여기에 이미지 설명 입력

앱의 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을 반환하고, 초기 버전이 아직 존재하지 않으면 번들 밖으로 복사하거나, 오류가 발생하면 0을 복사합니다.

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)

일반적으로 이 확장자를 사용합니다.

Swift 3.xSwift 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]
    }
}

보다 편리한 Swift 3 방법:

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

Swift 2.2와 함께 작동하는 예를 보는 모든 사람들을 위해, 현대적인 시도가 있는 아비젠 코드 오류 처리.

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에는 가드(아날로그가 아닌 경우 루비)가 있으므로 가드를 사용하면 훨씬 짧고 읽기 쉽습니다.

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 
}

Xcode 8b4 Swift 3.0

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

나는 보통 swift 3에서 아래와 같은 것을 선호합니다. 왜냐하면 나는 파일 이름을 추가하고 파일을 쉽게 만들 수 있기 때문입니다.

let fileManager = FileManager.default
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    let databasePath = documentsURL.appendingPathComponent("db.sqlite3").path
    print("directory path:", documentsURL.path)
    print("database path:", databasePath)
    if !fileManager.fileExists(atPath: databasePath) {
        fileManager.createFile(atPath: databasePath, contents: nil, attributes: nil)
    }
}

이 줄을 앱 대리자에 복사하여 붙여넣으면 다음과 같은 경로가 인쇄 경로가 인쇄됩니다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as String)
        return true
    }

경로를 복사하여 파인더의 폴더로 이동에 붙여넣기를 마우스 오른쪽 단추로 클릭한 다음 입력합니다.

Xcode로 파일 열기

여기에 이미지 설명 입력

언급URL : https://stackoverflow.com/questions/24055146/how-to-find-nsdocumentdirectory-in-swift

반응형