Статическая структура IOS с ресурсами внутри
Я пытаюсь создать фреймворк, который поддерживает некоторый общий код, который я использую в своих проектах.
Я нашел онлайн-учебники и сумел создать фреймворк, но у меня все еще есть одна проблема, связанная с ресурсами (xibs, images и т.д.).
Скажем, у меня есть MainViewController.xib
, который имеет UIImageView
, используя test.png
. Все это в моем пакете framework.
Когда я использую фреймворк в другом проекте, я добавляю его в фазу сборки "Copy Bundle Resources". Проблема в том, что xib доступен только с использованием пути, такого как dummy.framework/Resources/MainViewController.xib
, а UIImageView
внутри не может загрузить test.png
.
Кажется, что UIImageView попытается загрузить png из корня пакета, а не из относительной папки, в которой также хранится xib.
Кто-нибудь смог создать фреймворк с кодом и ресурсами и использовать его в другом проекте?
Ответы
Ответ 1
Короткий ответ: вы не можете.
При компиляции приложения пакет генерируется ресурсами основного проекта, игнорируя ресурсы в связанных рамках. Сюда входят изображения, xib, plist и т.д. (Все, что не является исходным файлом)
Что вам нужно сделать, это добавить эти ресурсы в свой основной проект, чтобы они были доступны для использования внутри вашего приложения, а не самым счастливым образом вокруг него, но он будет работать.
Ответ 2
Я знаю, что это старый поток, но для того, чтобы новые люди делали одни и те же ошибки, обратите внимание:
Как и в Xcode 6 и iOS8, у Apple есть полностью поддерживаемое решение для первой группы Dynamic Framework. Для получения дополнительной информации смотрите здесь: https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14
Но, тем не менее, создайте новый проект и выберите шаблон Cocoa Touch Framework.
Ответ 3
Я создал целевую среду фреймворка и обратился к изображениям внутри своего каталога активов. Я сделал следующее:
UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
Ответ 4
Я больше не управляю файлами вручную, но использую рекомендовать CocoaPods.
Оригинальный ответ:
- Используйте фальшивую инфраструктуру @wattson12. Он также скомпилирует и сохранит ресурсы.
-
Вдохновленный этим script, добавьте это в свою цель, чтобы скопировать ресурсы в ваше приложение:
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
Вы также можете просто перетащить фреймворк на свой уровень ресурсов копирования, но затем вы будете добавлять ненужные заголовки и скомпилированный код.
Edit
Чтобы использовать эти ресурсы из IB, например png файл, замените:
MyImage
по:
MYFrameworkResources.bundle/MyImage.png
Он будет просматривать значок сломанного изображения, но будет работать при запуске.
Загрузите нить из кода:
[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...
Наконец, вы можете добавить эти методы в категорию NSBundle, чтобы облегчить доступ к ресурсам Nib, которые я буду в вашем основном пакете или в MYFrameworkResources.bundle:
@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 и т.д.
Ответ 5
Базовые структуры не включают в себя большинство видов ресурсов, чтобы включить ресурсы эту "фальшивую" инфраструктурную библиотеку
В итоге вы получите папку .embeddedframework, которая содержит фактическую структуру, но также включает любые ресурсы, которые вы добавляете к фазе сборки Copy Bundle Resources. Ive использовал его для включения xib, основных моделей данных, изображений и плоскостей.
Ответ 6
Чтобы загрузить изображение из динамической структуры в Swift 3:
UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)
Ответ 7
Начиная с Xcode 7 мы теперь можем использовать каталоги активов. В моих экспериментах я обнаружил, что u может ссылаться на файлы в одном и том же бите работы различных проектов, устраняя необходимость микроконтролировать активы в фазах сборки или беспокоиться о целях.