iPhone / iPad: не удается скопировать папку из NSBundle в NSDocumentDirectory

#objective-c #ios #file-io #nsfilemanager #nsbundle

#objective-c #iOS #file-io #nsfilemanager #nsbundle

Вопрос:

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

     NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:@"Images"];

    NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
                                          stringByAppendingPathComponent:@"Images"];
        [fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:amp;error];
  

Допустим, в папке с именем Test.png есть изображение, и я хочу отобразить изображение на моей кнопке, это не работает!
Однако, если я скопировал только одно изображение из NSBundle в NSDocumentDirectory, это работает!

Пример:

Изменение

 stringByAppendingPathComponent:@"Images"  
  

Для

 stringByAppendingPathComponent:@"Test.png"
  

Итак, проблема заключается в копировании папки в NSDocumentDirectory!
Мои приведенные выше коды неверны?
Или невозможно скопировать папки? (Что означает, что я должен копировать файлы по отдельности)

Ответ №1:

Приведенный ниже код создаст папку с именем «images» в каталоге документов и скопирует все файлы из папки с именем «folderinbundle» в вашем пакете в «images»

 - (void) copyImages
{
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"folderinbundle"];  //folder contain images in your bundle
    NSString *destPath = [documentsDirectory stringByAppendingPathComponent:@"images"];  //images is your folder under document directory

    NSError *error;
    [[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destPath error:amp;error];  //copy every files from sourcePath to destPath
}
  

Отредактируйте, чтобы уточнить: вышеуказанное сработает, если «folderinbundle» является физической папкой, а не группой.

Комментарии:

1. Я удалил свой предыдущий комментарий о том, что это не работает. Это работает отлично. Спасибо

Ответ №2:

Оскар прав, в настоящее время нет способа скопировать всю папку с помощью одной команды.

Подобный метод может помочь (предупреждаю — у меня отключено соединение с Office, и я не могу получить доступ к своему Mac, чтобы проверить, работает ли этот код. Проверю это, как только смогу). Просто вызовите [self copyDirectory:@»Images»], и он обработает все остальное.

 -(void) copyDirectory:(NSString *)directory {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:directory];
    NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:directory];

    if (![fileManager fileExistsAtPath:documentDBFolderPath]) {
        //Create Directory!
        [fileManager createDirectoryAtPath:documentDBFolderPath withIntermediateDirectories:NO attributes:nil error:amp;error];
    } else {
        NSLog(@"Directory exists! %@", documentDBFolderPath);
    }

    NSArray *fileList = [fileManager contentsOfDirectoryAtPath:resourceDBFolderPath error:amp;error];
    for (NSString *s in fileList) {
        NSString *newFilePath = [documentDBFolderPath stringByAppendingPathComponent:s];
        NSString *oldFilePath = [resourceDBFolderPath stringByAppendingPathComponent:s];
        if (![fileManager fileExistsAtPath:newFilePath]) {
            //File does not exist, copy it
            [fileManager copyItemAtPath:oldFilePath toPath:newFilePath error:amp;error];
        } else {
            NSLog(@"File exists: %@", newFilePath);
        }
    }
}
  

— РЕДАКТИРОВАТЬ 9.11.2011 —
Извините за это, как я уже предупреждал, я не смог получить доступ к своему Mac для проверки кода.
Обновил код, и я убедился, что теперь он работает должным образом. Добавлена пара быстрых NSLogs, чтобы сообщить вам, существует ли новый каталог или новый файл.

Комментарии:

1. В нем говорится, что directoryContentsAtPath устарел.

2. И это не работает. Я попытался извлечь изображение из NSDocumentDirectory и отобразить его в imageview, но это не работает.

3. @Lloydworth — обновленный код для вас, и он работает должным образом на iOS 5.0. Дайте мне знать, если у вас возникнут какие-либо вопросы или вам понадобится помощь с этим!

Ответ №3:

Боюсь, в настоящее время нет способа копировать папки, и если есть сторонняя функция, которая это делает, все, что она будет делать на самом деле, это копировать файл за файлом… Поэтому вам придется копировать каждый файл по отдельности.

Комментарии:

1. О нет… Что означает, что если у меня есть 50 файлов для копирования, мне нужно написать коды для копирования для 50 из них? 🙁

2. Боюсь, что да. Похоже, что это либо код geekswordsman, либо предварительный цикл массива имен файлов.