Как и было обещано, вот решение, которое я придумал:
Сами файлы комплекта загружаются, как описано здесь .Чтобы добавить к информации, перечисленной там, я обнаружил, что если вы сначала создаете представления в приложении для iphone, вы можете предварительно просмотреть их в симуляторе.затем вы можете создать новый проект в виде пакета и перетащить ВСЕ файлы изображений и файл xib & .h в новый проект.не перетаскивайте файл .m, так как это создает проблемы при сборке.затем убедитесь, что настройки проекта определяют BASE SDK как «Последний IOS», а не настройку Mac OS X по умолчанию, которая была бы выбрана.затем вы все равно можете отредактировать xib, дважды щелкнув по нему.Любые распространенные файлы можно отменить в сборке, сняв флажок «target» для этого файла.см. «Дополнительная информация» далее в этом посте с ответом.
После того, как я скачал каждый пакет в zip-файле с сервера, я использую следующие методы, которые я кодировал для этой цели:
-(NSArray *) imageFileExtensions {
return [NSArray arrayWithObjects:@".png",@".gif",@".jpg",@".jpeg",@".bmp", nil];
}
и
-(void) cloneImageFilesInPath:(NSString *)path toPath:(NSString*)clonePath {
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *extensions = [self imageFileExtensions];
if ([fm fileExistsAtPath:path]) {
NSArray *files = [fm contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files){
for (NSString *ext in extensions) {
if ([file hasSuffix:ext]) {
NSString *targetFile = [clonePath stringByAppendingPathComponent:file];
if (![fm fileExistsAtPath:targetFile]) {
[fm createSymbolicLinkAtPath:targetFile withDestinationPath:[path stringByAppendingPathComponent:file] error:nil];
}
break;
}
}
}
}
}
эти методы создают сканирование основного каталога пакета приложения, и для каждого файла изображения, который НЕ находится в каталоге пользовательского пакета, в каталоге пользовательского пакета создается символическая ссылка, указывающая на главныйкаталог приложений.
Они вызываются в моем приложении-делегате следующим образом:
...(insert code to unzip the file to bundlePath here)...
[self cloneImageFilesInPath:[[NSBundle mainBundle] bundlePath] toPath:bundlePath];
Дополнительная информация
для создания реальных пакетов, я создал отдельное приложениепри этом удаляются все файлы изображений из каталога пользовательских пакетов, если эти имена файлов присутствуют в каталоге, содержащем общие файлы изображений, которые развернуты в основном комплекте приложений.Позже я обнаружил, что вы можете запретить xcode включать определенные файлы из сборки, сняв флажок целевого столбца для этого файла, так что этот шаг не обязательно нужен - однако, если у вас есть много представлений для создания, может быть проще просто оставитьих в связках, и раздеть их, используя этот метод.
-(void) removeDuplicatedImageFilesInPath:(NSString *)sourcePath fromTargetPath:(NSString*)path {
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *extensions = [self imageFileExtensions];
if ([fm fileExistsAtPath:path]) {
NSArray *files = [fm contentsOfDirectoryAtPath:sourcePath error:nil];
for (NSString *file in files){
for (NSString *ext in extensions) {
if ([file hasSuffix:ext]) {
NSString *targetPath = [path stringByAppendingPathComponent:file];
if ([fm fileExistsAtPath:targetPath]) {
[fm removeItemAtPath:targetPath error:nil];
}
break;
}
}
}
}
}
Дополнительная информация для работы с файлами zip
Я выбрал ObjectiveZip (послепредложение автора здесь . Чтобы упростить задачу, я обернул это в следующие 2 метода делегата приложения (один используется в реальном приложении, другой в автономном приложении создания пакета)
в основном приложении
-(void) unzipArchive:(NSString *)zipFileName toPath:(NSString *)path {
NSFileManager *fm = [NSFileManager defaultManager];
ZipFile *unzipFile = [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeUnzip];
NSArray *infos= [unzipFile listFileInZipInfos];
[unzipFile goToFirstFileInZip];
for (FileInZipInfo *info in infos) {
ZipReadStream *read1= [unzipFile readCurrentFileInZip];
NSMutableData *fileData = [[[NSMutableData alloc] initWithLength:info.length] autorelease];
int bytesRead1 = [read1 readDataWithBuffer:fileData];
if (bytesRead1 == info.length) {
NSString *fileName = [path stringByAppendingPathComponent:info.name ];
NSString *filePath = [fileName stringByDeletingLastPathComponent];
[fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
[fileData writeToFile:fileName atomically:YES];
}
[read1 finishedReading];
[unzipFile goToNextFileInZip];
}
[unzipFile close];
[unzipFile release];
}
и в автономном приложении создания пользовательских пакетов.
-(void) createArchive:(NSString *) zipFileName usingPath:(NSString *)path {
NSArray *files = [self filesInDirectory:path];
ZipFile *zipFile= [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeCreate];
for (NSString *file in files) {
NSString *fileNameForZip = [file substringFromIndex:path.length];
ZipWriteStream *stream= [zipFile writeFileInZipWithName:fileNameForZip fileDate:[NSDate dateWithTimeIntervalSinceNow:-86400.0] compressionLevel:ZipCompressionLevelBest];
[stream writeData:[NSData dataWithContentsOfFile:file]];
[stream finishedWriting];
}
[zipFile close];
[zipFile release];
}
примечание: предыдущий метод основан на следующих 2 методах, которые создают NSArray, содержащийполный путь ко всем файлам по указанному пути (повторяется в подкаталогах)
-(void)loadFilesInDirectory:(NSString *)path intoArray:(NSMutableArray *)files {
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *fileList = [NSMutableArray arrayWithArray:[fm contentsOfDirectoryAtPath:path error:nil]];
for (NSString *file in fileList) {
BOOL isDirectory = NO;
NSString *filePath = [path stringByAppendingPathComponent:file];
if ([fm fileExistsAtPath:filePath isDirectory:&isDirectory]) {
if (isDirectory) {
[self loadFilesInDirectory:filePath intoArray:files];
} else {
[files addObject:filePath];
};
};
}
}
-(NSArray *)filesInDirectory:(NSString *)path {
NSMutableArray *files = [NSMutableArray array];
[self loadFilesInDirectory:path intoArray:files];
return files;
}