22

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

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

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

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

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

4

7 回答 7

14

我知道这是一个旧线程,但为了防止新人犯同样的错误,这里有一个注意事项:

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

于 2014-10-20T15:14:14.327 回答
8

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

UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
于 2015-05-05T16:59:33.367 回答
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
    

您也可以只将框架拖到 Copy Resources 步骤,但随后您将添加不必要的标头和编译代码。

编辑

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

MyImage

经过:

MYFrameworkResources.bundle/MyImage.png

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

从代码中加载一个 Nib:

[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...

最后,您可以在 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

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

于 2012-12-14T00:37:20.367 回答
4

为了从Swift 3中的动态框架加载图像:

UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)

于 2016-10-12T21:44:58.607 回答
1

基本框架不包含大多数类型的资源,要包含资源使用这个“假”框架库

您最终会得到一个 .embeddedframework 文件夹,其中包含实际框架,但还包括您添加到 Copy Bundle Resources 构建阶段的任何资源。我用它来包含 xib、核心数据模型、图像和 plist

于 2012-08-29T14:26:13.003 回答
-1

简短的回答:你不能。

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

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

于 2012-08-29T14:24:51.047 回答
-1

从 Xcode 7 开始,我们现在可以使用资产目录。在我的实验中,我发现您可以在同一个工作区中引用不同项目中的文件,从而无需在构建阶段对资产进行微管理或担心目标。

于 2016-03-10T02:10:10.100 回答