11

简而言之 :

如何Assets.carNSBundle.

完整版本:

我正在将一套应用程序转换为使用CocoaPods. 每个应用程序都依赖于一个名为Core.

Core包括代码文件、xib文件和几个xcasset文件。

这是创建资源包的Podspecfor的相关行:Core

  s.resource_bundles = {'CoreResources' => ['Core/Resources/*']}

正确构建了Podspecpasspod spec lint和依赖它的 main 项目。

但是,其中任何xcasset文件的图像Core都没有显示。

我(天真地)尝试使用这样的类别加载图像UIImage

@implementation UIImage (Bundle)

+ (UIImage *)imageNamed:(NSString *)name bundle:(NSBundle *)bundle
{
    if (!bundle)
        return [UIImage imageNamed:name];

    UIImage *image = [UIImage imageNamed:[self imageName:name forBundle:bundle]];
    return image;
}

+ (NSString *)imageName:(NSString *)name forBundle:(NSBundle *)bundle
{
    NSString *bundleName = [[bundle bundlePath] lastPathComponent];
    name = [bundleName stringByAppendingPathComponent:name];
    return name;
}
@end

以前,Core是 a submodule,并且此解决方案运行良好。但是,在检查我以前的bundle文件(与捆绑包分开main)后,我注意到所有图像都被简单地复制到bundle......即

Image.png, Image@2x.png, 等都在捆绑包中。

检查生成的CocoaPods包后,它包含一个

Assets.car

我理解它是所述子目录中所有xcasset文件的组合编译版本。Core

如何从这个资源包中编译Assets.car的这个加载图像?Core

作为一个黑客,我想我可以......

Podspec语法参考以此为例:

spec.resource = "Resources/HockeySDK.bundle"

这似乎表明可以在 Xcode中手动创建包并让 CocoaPods 简单地复制它。

不过,这更像是一种技巧,而不是一种解决方案。

我相信 CocoaPods (v 0.29+) 可以完全处理这个......?

4

1 回答 1

3

我和你的情况一样,我最终选择了你提到的“hack”,但它在 pod 安装期间是自动化的,所以它更易于维护。

在我的 podspec 我有

# Pre-build resource bundle so it can be copied later
  s.pre_install do |pod, target_definition|
    Dir.chdir(pod.root) do
      command = "xcodebuild -project MyProject.xcodeproj -target MyProjectBundle CONFIGURATION_BUILD_DIR=Resources 2>&1 > /dev/null"
      unless system(command)
        raise ::Pod::Informative, "Failed to generate MyProject resources bundle"
      end
    end
  end

然后在 podspec 中:

  s.resource = 'Resources/MyProjectBundle.bundle'

这里的技巧是在 pod install 之前构建捆绑包,以便 .bundle 可用,然后可以链接起来,就好像你一直在源代码中一样。这样我就可以轻松地在捆绑目标中添加新的资源/图像/xib,它们将被编译和链接。奇迹般有效。

我在 NSBundle+MyResources 上有一个类别,可以轻松访问捆绑资源:

+ (NSBundle *)myProjectResources
{
    static dispatch_once_t onceToken;
    static NSBundle *bundle = nil;
    dispatch_once(&onceToken, ^{
        // This bundle name must be the same as the product name for the resources bundle target
        NSURL *url = [[NSBundle bundleForClass:[SomeClassInMyProject class]] URLForResource:@"MyProject" withExtension:@"bundle"];
        if (!url) {
            url = [[NSBundle mainBundle] URLForResource:@"MyProject" withExtension:@"bundle"];
        }
        bundle = [NSBundle bundleWithURL:url];
    });
    return bundle;
}

因此,如果您想加载例如核心数据模型:

NSURL *modelURL = [[NSBundle myProjectResources] URLForResource:@"MyModel" withExtension:@"momd"];

我还做了一些方便的方法来访问图像:

+ (UIImage *)bundleImageNamed:(NSString *)name
{
    UIImage *imageFromMainBundle = [UIImage imageNamed:name];
    if (imageFromMainBundle) {
        return imageFromMainBundle;
    }

    NSString *imageName = [NSString stringWithFormat:@"MyProject.bundle/%@", name];
    UIImage *imageFromBundle = [UIImage imageNamed:imageName];
    if (!imageFromBundle) {
        NSLog(@"Image not found: %@", name);
    }
    return imageFromBundle;
}

我还没有失败过。

于 2014-02-27T12:09:27.820 回答