#iphone #objective-c #ios #cocoa-touch #ipad
#iPhone #objective-c #iOS #cocoa-touch #iPad
Вопрос:
Я хочу скопировать несколько файлов из моего NSBundle в каталог Documents при запуске приложения.
Это код для копирования файла:
- (NSString *) getPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingString:@"Photo.png"];
}
- (void) copyFile
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *Path = [self getPath];
BOOL success = [fileManager fileExistsAtPath:Path];
if(!success) {
NSString *defaultPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Photo.png"];
success = [fileManager copyItemAtPath:defaultPath toPath:Path error:amp;error];
if (!success)
NSAssert1(0, @"Failed to create writable file with message '%@'.", [error localizedDescription]);
}
}
Метод CopyFile будет вызван в методе ‘applicationDidFinishLaunchingWithOptions’. Но этот метод позволяет копировать только один файл в каталог Documents. Если я хочу скопировать 50 файлов из моего NSBundle, означает ли это, что я должен указать 50 путей? Есть ли какой-нибудь более короткий способ, например, получить все файлы в NSBundle всего несколькими строками кодов?
Ответ №1:
Вы можете скопировать все файлы из своих папок ресурсов, но я сомневаюсь, что вы действительно хотите это сделать, не так ли? В конце концов, это тоже ресурсы приложения (например, файл строк или графика только для кнопок пользовательского интерфейса и т.д.)
Таким образом, вы можете захотеть иметь подкаталог в вашей папке resources (например, с именем FilesToCopy
) со всеми файлами, которые вы хотите скопировать (например, Photo.png
находится по Contents/Resources/FilesToCopy/Photo.png
адресу)
Чтобы получить содержимое каталога, просто используйте
NSError * err;
NSArray * files;
NSString * srcPath;
NSString * dstPath;
NSFileManager * man;
srcPath = [self getSrcPath];
dstPath = [self getDstPath];
man = [[NSFileManager alloc] init];
files = [man contentsOfDirectoryAtPath:srcPath error:amp;err];
Затем вы можете копировать по одному файлу за раз:
for (NSString *aFile in files) {
BOOL success;
NSString * srcFile = [srcPath stringByAppendingPathComponent:aFile];
NSString * dstFile = [dstPath stringByAppendingPathComponent:aFile];
success = [man copyItemAtPath:srcFile toPath:dstFile error:amp;err];
// Verify success
}
Теперь вам нужно только srcPath
и dstPath
.
- (NSString *)getSrcPath
{
return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"FilesToCopy"];
}
- (NSString *)getDstPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
return [paths objectAtIndex:0];
}
Комментарии:
1. На самом деле это правильный ответ на вопрос. Спасибо Mecki.
2. Важно помнить одну вещь: выберите «Создать ссылки на папки» в диалоговом окне при перетаскивании их в ваш проект. Если вы просто создадите группу, код не найдет папку, потому что это группа, и поэтому он не будет перечислять файлы, и копирование не будет выполнено.
Ответ №2:
Измените прототип ваших функций:
- (NSString *) getPathofFileName:(NSString*)name;
- (void) copyFileWithName:(NSString*)name;
Комментарии:
1. @Lloydworth Потому что тогда вы сможете вызывать
copyFileWithName
50 раз, каждый раз указывая другое имя файла, иcopyFileWithName
можете вызыватьgetPathOfFileName
каждый раз с другим именем файла, чтобы получить путь к текущему скопированному файлу. Конечно, это все равно означает, что вам нужен список всех этих 50 файлов. Так что это не совсем удобное решение.
Ответ №3:
да, конечно, вы можете это сделать
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSMutableArray *filesArray = [NSMutableArray arrayWithObjects:@"0.epub",@"1.epub",@"2.epub",@"3.epub",@"4.epub",nil];//here put the name of files you want to copy
[self copyFilesToDocuments:filesArray];
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
self.window.rootViewController = (UIViewController*)self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void) copyFilesToDocuments : (NSMutableArray*)filesArr {
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
for(int i = 0 ; i < [filesArr count] ; i ) {
NSString *filePath = [docDir stringByAppendingPathComponent:[filesArr objectAtIndex:i]];
NSFileManager *fm = [NSFileManager defaultManager];
BOOL exist = [fm fileExistsAtPath:filePath];
NSError *error = nil;
if (!exist) {
NSString *path = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:[filesArr objectAtIndex:i]];
BOOL success = [fm copyItemAtPath:path toPath:filePath error:amp;error];
if (!success) {
NSAssert1(0,@"%@",[error localizedDescription]);
}
}
}
}