Статическая Платформа IOS с ресурсами внутри
Я пытаюсь создать структуру, которая сохраняет некоторый общий код, который я использую в своих проектах. Я нашел онлайн-учебники и сумел создать фреймворк, но у меня все еще есть одна проблема, связанная с ресурсами (xibs, изображения и т. д.).
Допустим у меня есть MainViewController.xib
с UIImageView
С помощью test.png
. Все это есть в моем рамочном пакете.
когда я использую фреймворк в другом проекте, я добавляю его в фазу сборки "копировать ресурсы пакета". Проблема в том, что xib доступен только с помощью пути dummy.framework/Resources/MainViewController.xib
и UIImageView
внутри не удается загрузить test.png
.
кажется, что UIImageView попытается загрузить png из корня пакета, а не из относительной папки, где также хранится xib.
кому-нибудь удалось создать фреймворк с кодом и ресурсами и использовать его в другом проекте?
7 ответов
короткий ответ: вы не можете.
когда вы компилируете приложение, пакет генерируется с ресурсами "основного" проекта, игнорируя ресурсы в связанных фреймворках. Это включает изображения, xib, plist и т. д. (все, что не является исходным файлом)
Что вам нужно сделать, это добавить эти ресурсы в свой основной проект, чтобы они были доступны для использования внутри вашего приложения, а не самым счастливым способом, но он будет работать.
Я знаю, что это старая нить, но чтобы новые люди не делали тех же ошибок, вот Примечание:
начиная с Xcode 6 и iOS8, Apple имеет полностью поддерживаемое решение для динамической платформы первой партии. Для получения дополнительной информации смотрите здесь: https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14
но короче говоря, создайте новый проект и выберите шаблон Cocoa Touch Framework.
Я создал цель фреймворка и для доступа к изображениям внутри его каталога активов я сделал следующее:
UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
Я больше не управляю фреймворками вручную, но использую and рекомендую CocoaPods вместо.
оригинальный ответ:
- использовать фейк рамках @wattson12 упоминается. Он также будет компилировать и сохранять ресурсы.
-
вдохновленный этот скрипт добавьте это к вашей цели, чтобы скопировать ресурсы в app:
SOURCE_PATH="${TARGET_BUILD_DIR}/MYFramework.framework/Resources/" TARGET_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MYFrameworkResources.bundle" mkdir -p $TARGET_PATH cp -R $SOURCE_PATH $TARGET_PATH
вы также можете просто перетащить фреймворк на шаг копирования ресурсов, но тогда вы также добавите ненужные заголовки и скомпилированный код.
редактировать
чтобы использовать эти ресурсы из IB, например файл png, замените:
MyImage
by:
MYFrameworkResources.bundle/MyImage.png
он будет просматривать сломанный значок изображения, но будет работать при запуске.
загрузите перо из код:
[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...
наконец, вы можете добавить эти методы в категорию NSBundle, чтобы облегчить доступ к ресурсам Nib, которые находятся в вашем основном пакете или в MYFrameworkResources.бандл:
@implementation NSBundle (MyCategory)
+ (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)extension
{
// First try with the main bundle
NSBundle * mainBundle = [NSBundle mainBundle];
NSString * path = [mainBundle pathForResource:name
ofType:extension];
if (path)
{
return path;
}
// Otherwise try with other bundles
NSBundle * bundle;
for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
inDirectory:nil])
{
bundle = [NSBundle bundleWithPath:bundlePath];
path = [bundle pathForResource:name
ofType:extension];
if (path)
{
return path;
}
}
NSLog(@"No path found for: %@ (.%@)", name, extension);
return nil;
}
+ (NSArray *)loadNibNamed:(NSString *)name
owner:(id)owner
options:(NSDictionary *)options
{
// First try with the main bundle
NSBundle * mainBundle = [NSBundle mainBundle];
if ([mainBundle pathForResource:name
ofType:@"nib"])
{
NSLog(@"Loaded Nib named: '%@' from mainBundle", name);
return [mainBundle loadNibNamed:name
owner:owner
options:options];
}
// Otherwise try with other bundles
NSBundle * bundle;
for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
inDirectory:nil])
{
bundle = [NSBundle bundleWithPath:bundlePath];
if ([bundle pathForResource:name
ofType:@"nib"])
{
NSLog(@"Loaded Nib named: '%@' from bundle: '%@' ", name, bundle.bundleIdentifier);
return [bundle loadNibNamed:name
owner:owner
options:options];
}
}
NSLog(@"Couldn't load Nib named: %@", name);
return nil;
}
@end
он сначала посмотрит в ваш пакет приложений, а затем в MYFrameworkResources.bundle, etc.
основные рамки не включают большинство видов ресурсов, чтобы включить использование ресурсов эта "поддельная" библиотека фреймворков
вы в конечном итоге с a .папка embeddedframework, которая содержит фактическую структуру, но также включает все ресурсы, добавленные на этапе сборки ресурсов пакета копирования. Ive использовал его для включения xibs, основных моделей данных, изображений и plists
для загрузки изображения из динамической структуры в Swift 3:
UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)
начиная с Xcode 7 мы теперь можем использовать каталоги активов. В моих экспериментах я обнаружил, что u может ссылаться на файлы в одной и той же рабочей области в разных проектах, устраняя необходимость микроуправления активами на этапах сборки или беспокоиться о целях.