Статическая структура 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 может ссылаться на файлы в одном и том же бите работы различных проектов, устраняя необходимость микроконтролировать активы в фазах сборки или беспокоиться о целях.