Как создать каталог с помощью кода Swift (NSFileManager)

У меня возникли проблемы с преобразованием кода Objective-C для создания каталога для Swift.

Цель-C:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/MyFolder"];

    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];

person Gian    schedule 14.11.2014    source источник
comment
Покажите нам, что вы пробовали в Swift и что не работает.   -  person Danny S    schedule 14.11.2014
comment
Я думаю, что немного грубо спрашивать, что OP пробовал в Swift, потому что вопрос достаточно ясен для всех, кто знаком со Swift и готов помочь.   -  person Totoro    schedule 20.06.2020


Ответы (8)


Свифт 5.0

let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let docURL = URL(string: documentsDirectory)!
let dataPath = docURL.appendingPathComponent("MyFolder")
if !FileManager.default.fileExists(atPath: dataPath.path) {
    do {
        try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true, attributes: nil)
    } catch {
        print(error.localizedDescription)
    }
}

Свифт 4.0

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentsDirectory: AnyObject = paths[0] as AnyObject
let dataPath = documentsDirectory.appendingPathComponent("MyFolder")!
    
do {
    try FileManager.default.createDirectory(atPath: dataPath.absoluteString, withIntermediateDirectories: false, attributes: nil)
} catch let error as NSError {
    print(error.localizedDescription)
}

Свифт 3.0

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
let dataPath = documentsDirectory.appendingPathComponent("MyFolder")!
        
do {
    try FileManager.default.createDirectory(atPath: dataPath.absoluteString, withIntermediateDirectories: false, attributes: nil)
} catch let error as NSError {
    print(error.localizedDescription)
}

Свифт 2.1

Вы можете создать каталог, используя метод ниже:

let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
let dataPath = documentsDirectory.stringByAppendingPathComponent("MyFolder")

do {
    try NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil)
} catch let error as NSError {
    print(error.localizedDescription)
}
person Kampai    schedule 14.11.2014
comment
Начиная со Swift 2: do {try fileManager.createDirectoryAtPath(outputPath, withIntermediateDirectories: false, attribute: nil)} отловить ошибку как NSError { print(error.localizedDescription); } - person Siamaster; 23.09.2015
comment
моя папка? Вы имеете в виду мой файл? - person Daniel Springer; 03.09.2019
comment
Я получаю сообщение об ошибке, что у меня нет прав доступа к файлу после его создания с помощью этого кода. - person Daniel Springer; 03.09.2019
comment
@DanielSpringer: Пожалуйста, прочитайте вопрос, ответ заключается в создании каталога с использованием Swift. Так что этот код вам не подойдет, так как вы пытаетесь создать файл с помощью функции createDirectory(). - person Kampai; 03.09.2019
comment
@Kampai да, я вижу, что это ответ на вопрос. У меня был похожий/похожий вопрос. - person Daniel Springer; 03.09.2019
comment
@DanielSpringer: Пожалуйста, дайте мне знать ваши вопросы, я здесь, чтобы помочь вам. - person Kampai; 03.09.2019
comment
@Kampai Я пытаюсь прочитать созданный файл, используя приведенный выше код, но получаю сообщение об ошибке «Отказано в доступе». Как создать файл, чтобы попытка записи в него не выдавала ошибку «нет такого файла»? - person Daniel Springer; 03.09.2019
comment
@DanielSpringer: Не могли бы вы указать версию Xcode и версию iOS? - person Kampai; 03.09.2019
comment
@Kampai Проголосовал за вас только потому, что вы внедрили проверку/отчетность об ошибках. Слава! - person SafeFastExpressive; 25.11.2020
comment
Используйте relativePath вместо absoluteString - person Bogdan Razvan; 28.12.2020
comment
Просто path вместо absoluteString. - person Sergey; 18.02.2021
comment
пусть docURL = URL (fileURLWithPath: documentDirectory), если вы хотите добавить файл в путь. замените «строку» на «fileURLWithPath», иначе вы получите ошибку схемы URL. В остальном хороший код, спасибо. - person johnrubythecat; 13.04.2021
comment
@Сергей Подмечено!!! - person Kampai; 14.04.2021

Ни один из ответов @Kampai и @Crashalot не помог мне.

.absoluteString создает URL-адрес с префиксом file:// и вызывает исключение при создании каталога. Вместо этого я использовал метод .path.

Фиксированный код для Swift 3

let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dataPath = documentsDirectory.appendingPathComponent("MyFolder")

do {
    try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
    print("Error creating directory: \(error.localizedDescription)")
}
person Mehdi Hosseinzadeh    schedule 23.11.2016
comment
Слава вам, я пытался понять это в течение дня! - person Jack; 02.03.2017
comment
Спасибо, .path был для меня недостающей частью - person thacilima; 09.06.2017
comment
Нужно ли при создании папки проверять, существует ли папка или нет? - person Arpit B Parekh; 11.04.2018
comment
Нет, это не нужно, потому что мы отправляем withIntermediateDirectories: true. Если папка создана/существует, она все равно вернет true. Вы можете прочитать больше здесь: developer.apple.com/documentation/foundation/filemanager/ - person Mehdi Hosseinzadeh; 11.04.2018

Принятый ответ больше не компилируется, так как строка с appendingPathComponent выдает ошибку.

Вот версия Swift 3, которая компилируется:

fileprivate func createDir(dirName: String) {
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let dataPath = documentsDirectory.appendingPathComponent(dirName)

    do {
        try FileManager.default.createDirectory(atPath: dataPath.absoluteString, withIntermediateDirectories: false, attributes: nil)
    } catch let error as NSError {
        printError("Error creating directory: \(error.localizedDescription)")
    }
}
person Crashalot    schedule 30.10.2016
comment
Я пробовал это на iPhone, но не смог найти созданную папку на устройстве. Обновили устройство до iOS 11, в которой есть файлы App. - person Suhail Parvez; 05.02.2018

Свифт 4:

NSSearchPathForDirectoriesInDomains возвращает массив строк, а не URL-адресов.

appendingPathComponent to string приводит к сбою приложения с сообщением -[NSPathStore2 URLByAppendingPathComponent:]: нераспознанный селектор отправлен экземпляру

Вот версия Swift 4, которая компилируется:

    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
    if let pathURL = URL.init(string: paths[0]) {
        let dataURL = pathURL.appendingPathComponent("MyFolder")
        do {
            try FileManager.default.createDirectory(atPath: dataURL.absoluteString, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription);
        }
    }
    else {
        print("Error in getting path URL");
    }
person Dhasdhageerkhan    schedule 30.03.2018

Свифт 4

// DB Directory and Path
lazy var applicationDocumentsDirectory: URL = {

    let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentDirectoryURL = urls[urls.count - 1] as URL
    let dbDirectoryURL = documentDirectoryURL.appendingPathComponent("DB")

    if FileManager.default.fileExists(atPath: dbDirectoryURL.path) == false{
        do{
            try FileManager.default.createDirectory(at: dbDirectoryURL, withIntermediateDirectories: false, attributes: nil)
        }catch{
        }
    }
    return dbDirectoryURL
}()
person Gurjinder Singh    schedule 17.12.2017

Свифт 5

guard let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else { return }
    if let pathURL = URL.init(string: path) {
        let dataURL = pathURL.appendingPathComponent("MyFolderName")
        do {
            try FileManager.default.createDirectory(atPath: dataURL.absoluteString, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription);
        }
    }
    else {
        print("Error in URL path");
    }
person Praveen    schedule 24.09.2019

Более простое решение:

"~/Desktop/demo".expand.createDir()//Now you have a folder named demo on your desk

extension String{
    func createDir(_ path:String){
        do {
            try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            NSLog("Unable to create directory \(error.debugDescription)")
        }
    }
    var expand:String {return NSString(string: self).expandingTildeInPath}
}
person Sentry.co    schedule 11.08.2017

Для других разработчиков я оставлю это здесь, так как это может помочь кому-то вроде меня найти способ выяснить, где создается папка.

let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDir = paths.firstObject as String
println("Path to the Documents directory\n\(documentsDir)")
person bona912    schedule 30.03.2018