如何使用FileManager检索嵌套文件?

时间:2017-01-14 22:51:45

标签: ios objective-c swift nsurl nsfilemanager

在我的应用中,我会在应用首次启动时立即创建此文件夹结构:

enter image description here

我在这里阅读Can I save the keep the absolute path of a file in database? - 我不应该存储目录或文件的绝对路径。 因此,我无法参考上图中显示的最后一个文件 I-Want-This-File-Path

我可以访问上图中的Feed文件夹,如下所示:

extension FileManager {
    /// APPLICATION SUPPORT DIRECTORY
    static func createOrFindApplicationSupportDirectory() -> URL? {
        let bundleID = Bundle.main.bundleIdentifier
        // Find the application support directory in the home directory.
        let appSupportDir = self.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)

        guard appSupportDir.count > 0 else {
            return nil
        }

        // Append the bundle ID to the URL for the Application Support directory.
        let dirPath = appSupportDir[0].appendingPathComponent(bundleID!)

        // If the directory does not exist, this method creates it.
        do {
            try self.default.createDirectory(at: dirPath, withIntermediateDirectories: true, attributes: nil)
            return dirPath
        } catch let error {
            print("Error creating Application Support directory with error: \(error)")
            return nil
        }
    }

    /// FEED DIRECTORY
    static func createOrFindFeedDirectory() -> URL? {
        guard let appSupportDir = createOrFindApplicationSupportDirectory() else {
            return nil
        }

        let dirPath = appSupportDir.appendingPathComponent("Feed")

        // If the directory does not exist, this method creates it.
        do {
            try self.default.createDirectory(at: dirPath, withIntermediateDirectories: true, attributes: nil)
            return dirPath
        } catch let error {
            print("Error creating Favorites directory with error: \(error)")
            return nil
        }
    }
}

要访问FileStack文件夹,我有一个名为FileStack的对象,它保存了部分path。我没有保存绝对路径,而是在运行时构建它,如下所示:

class FileStack {

    var title = ""
    var localDirectoryName: String?
    var files: File? // THIS OBJECT IS WHERE I WANT TO SAVE THE PATH

    // THIS IS HOW I BUILD THE URL AT RUNTIME TO GET THE PATH TO THE DIRECTORY CALLED "FILESTACK"
    var localDirectoryPath: URL? {
        guard let localDirectoryName = localDirectoryName else { return nil }
        return FileManager.createOrFindFeedDirectory()?.appendingPathComponent(localDirectoryName)
    }
}

注意属性var files: File? - 这是一个名为File的自定义对象,我想在上面的图片中保存I-Want-This-File-Path文件的路径。对象是这样的:

class File {

    dynamic var iWantThisFileName: String?

    var iWantThisFilePath: URL? {
        guard let iWantThisFileName = iWantThisFileName else { return nil }
        return /// ??? HOW DO I RETURN THE PATH HERE?
    }
}

所以最终我希望能够像那样 I-Want-This-File-Path 的路径

let fileStack = FileStack()
fileStack.file.iWantThisFilePath // This will give me the path

有什么建议吗?

更新1

在应用程序支持中 - > com.Company.DemoApp目录,会有多个文件夹。例如,Feed和SavedForLater如此处所示。此外,FileStack将有多个文件,如下所示。

enter image description here

更新2

换句话说,我在运行时为File对象构建路径时遇到了麻烦。

我需要将FileStack的{​​{1}}传递给它的嵌套对象localDirectoryName,因为File对象需要在运行时构建它的路径。我上面的代码显示了这样的东西。 如果这些是单独的对象,意思是没有彼此嵌套,我可以简单地将File传递给下一个对象......但是因为它们是嵌套的,所以我被卡住了。

1 个答案:

答案 0 :(得分:0)

我认为你在其他问题上误解了答案。 你想得到这条道路:

/Library/Application Support/com.Company.DemoApp/Feed/FileStack/I-Want-This-File

/Library/Application Support/这是您可以在任何地方保存的部分,您必须在运行时从FileManager获取它。这是因为您无法控制此路径,并且未经您的批准可能会更改。您希望应用程序中的路径相对于此文件夹。

com.Company.DemoApp/Feed/FileStack/I-Want-This-File这是您可以存储在数据库/配置文件中的文件路径的一部分。只有在更改时,此路径才会更改。因此,如果您更新应用程序并更改路径,则还可以更改数据库中的路径。

这是如何实施的粗略示例:

enum DataDirectoryType : String
    {
    case wantedFile = "Feed/FileStack/I-Want-This-File-Path"
    case anotherFiles = "Feed/AnotherFiles/"
}

extension FileManager {
    /// APPLICATION SUPPORT DIRECTORY
    static private func createOrFindApplicationSupportDirectory() -> URL? {
        let bundleID = Bundle.main.bundleIdentifier
        // Find the application support directory in the home directory.
        let appSupportDir = self.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)

        guard appSupportDir.count > 0 else {
            return nil
        }

        // Append the bundle ID to the URL for the Application Support directory.
        return appSupportDir[0].appendingPathComponent(bundleID!)
    }

    static func createOrFindFilePath(_ type : DataDirectoryType ) -> URL? {
        guard let appSupportDir = createOrFindApplicationSupportDirectory() else {
            return nil
        }

        let dirPath = appSupportDir.appendingPathComponent(type.rawValue)

        // If the directory does not exist, this method creates it.
        do {
            try self.default.createDirectory(at: dirPath, withIntermediateDirectories: true, attributes: nil)
            return dirPath
        } catch let error {
            print("Error creating Favorites directory with error: \(error)")
            return nil
        }
    }
}


let urlToWantedFile = FileManager.createOrFindFilePath(.wantedFile)