Search code examples
swiftnsfilemanager

Different path URL for FileManager everytime I open the app


I want to create one folder in the fileManager root path, but before creating it, I want to check that the folder exist or not, and if not, I will create, otherwise will leave it

here are the function that I use

public func isDirectoryExist(path: String) -> Bool {
    let fileManager = FileManager.default
    var isDir : ObjCBool = false
    if fileManager.fileExists(atPath: path, isDirectory:&isDir) {
        if isDir.boolValue {
            return true
        } else {
            return false
        }
    } else {
        return false
    }
}


public func createNewDirectory(name: String) {
    
    let DocumentDirectory = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let DirPath = DocumentDirectory.appendingPathComponent(name)
    do
    {
        try FileManager.default.createDirectory(atPath: DirPath!.path, withIntermediateDirectories: true, attributes: nil)
    }
    catch let error as NSError
    {
        Logger.logError("Unable to create directory \(error.debugDescription)")
    }
    Logger.logInfo("Dir Path = \(DirPath!)")
}

Now, when I check the folder existing, it's always false and create a new folder and it happen every time

    func createARObjectDirectory() {
        let rootURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        if isDirectoryExist(path: "\(rootURL.absoluteString)\(DefaultURL.arObjectUrlDirectoryName)") {
            Logger.logServer("ARObject directly found")
        } else {
            createNewDirectory(name: DefaultURL.arObjectUrlDirectoryName)
        }
    }

Then I print the root url, and seems the hash in the middle of url is always different, how I can check it?

 file:///var/mobile/Containers/Data/Application/5AD0690B-498D-4309-8BD0-191FB88766AC/Documents/AR-Object/
 file:///var/mobile/Containers/Data/Application/41D35A54-1807-417E-AE29-311D43FCC21D/Documents/AR-Object/
 file:///var/mobile/Containers/Data/Application/F7E385CC-7921-4C37-B9BF-BCEFFC2AEE9E/Documents/AR-Object/
 file:///var/mobile/Containers/Data/Application/4748B014-5E55-46BB-BC83-394A6BC27292/Documents/AR-Object/

Thanks for your help


Solution

  • You are using the wrong API. absoluteString (in rootURL.absoluteString) returns the string representation including the scheme file://. The correct API for file system URLs is path

    I recommend to use the URL related API as much as possible

    public func directoryExists(at url: URL) -> Bool {
        let fileManager = FileManager.default
        var isDir : ObjCBool = false
        if fileManager.fileExists(atPath: url.path, isDirectory:&isDir) {
            return isDir.boolValue
        } else {
            return false
        }
    }
    

    and compose the URL in a more reliable way

    func createARObjectDirectory() {
        let documentsDirectory = URL.documentsDirectory
        if directoryExists(at: documentsDirectory.appendingPathComponent(DefaultURL.arObjectUrlDirectoryName)  {
            Logger.logServer("ARObject directly found")
        } else {
            createNewDirectory(name: DefaultURL.arObjectUrlDirectoryName)
        }
    }
    

    And this is swiftier too

    public func createNewDirectory(name: String) {
        
        let documentsDirectory = URL.documentsDirectory
        let dirURL = documentsDirectory.appendingPathComponent(name)
        do
        {
            try FileManager.default.createDirectory(at: dirURL, withIntermediateDirectories: false, attributes: nil)
        }
        catch let error as NSError
        {
            Logger.logError("Unable to create directory \(error.debugDescription)")
        }
        Logger.logInfo("Dir Path = \(dirPath.path)")
    }