内部资源的IOS静态框架

And*_*scu 20 frameworks xib uiimageview ios

我正在尝试创建一个框架,保留我在项目中使用的一些常用代码.我找到了在线教程并设法创建了一个框架,但我仍然有一个与资源相关的问题(xib,图像等).

假设我有MainViewController.xib一个UIImageView使用a test.png.所有这些都在我的框架包中.

当我在另一个项目中使用框架时,我将其添加到"Copy Bundle Resources"构建阶段.问题是xib只能使用类似的路径访问dummy.framework/Resources/MainViewController.xib,并且UIImageView内部无法加载test.png.

似乎UIImageView将尝试从bundle的根目录加载png,而不是从也存储xib的相对文件夹加载.

有没有人设法创建一个包含代码和资源的框架并在另一个项目中使用它?

Rya*_*los 15

我知道这是一个老话题,但为了防止新人犯同样的错误,请注意:

从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模板.

  • 是.它相当简单但可能并不明显.简单地将您的图像包含在正常的框架中,但要加载它们,您需要引用框架的包.所以`[NSBundle bundleWithIdentifier:@"com.<#company#>.<#framework#>"];` (10认同)
  • 是的,使用`imageNamed:inBundle:compatibleWithTraitCollection`.发送inBundle:`[NSBundle bundleWithClass [self class]]`或者在我使用图像的地方给出的任何内容. (2认同)

dev*_*oss 7

我创建了一个框架目标并访问其资产目录中的图像,我执行了以下操作:

UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
Run Code Online (Sandbox Code Playgroud)

  • 不过,这是用于动态框架,而不是静态框架,因为对于静态框架,`bundleForClass:self.class` 返回主应用程序包。 (3认同)

Riv*_*era 5

我不再手动管理框架,而是使用和推荐 CocoaPods.


原始答案:

  1. 使用虚假框架 @ wattson12提到.它还将编译和保存资源.
  2. 受此脚本的启发,将其添加到目标以将资源复制到您的应用:

    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
    
    Run Code Online (Sandbox Code Playgroud)

您也可以将框架拖到"复制资源"步骤,但随后您将添加不必要的标头和编译代码.

编辑

要从IB使用这些资源,例如png文件,请替换:

MyImage
Run Code Online (Sandbox Code Playgroud)

通过:

MYFrameworkResources.bundle/MyImage.png
Run Code Online (Sandbox Code Playgroud)

它将预览损坏的图像图标,但在运行时将起作用.

从代码加载Nib:

[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...
Run Code Online (Sandbox Code Playgroud)

最后,您可以在NSBundle类别中添加这些方法,以便于访问我在主包或MYFrameworkResources.bundle中的Nib资源:

@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
Run Code Online (Sandbox Code Playgroud)

它将首先查看您的应用程序包,然后查看MYFrameworkResources.bundle等.


Ism*_*ael -1

简短的回答:你不能。

编译应用程序时,将使用“主”项目的资源生成捆绑包,忽略链接框架中的资源。这包括图像、xib、plist 等(任何不是源文件的内容)

您需要做的是将这些资源添加到您的主项目中,以便它们可以在您的应用程序中使用,这不是最快乐的方法,但它会起作用。

  • @doozMen 介意解释一下吗? (6认同)
  • 这是最接近事实的答案。然而,您可以强制 xcode 从框架复制资源,但它们将被放置在主包的子文件夹中。这使得加载它们变得很痛苦。 (3认同)