Статическая Платформа 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 вместо.


оригинальный ответ:

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