我怎么能从一个NSBundle中的Assets.car(编译版本的xcassets)加载图像?

简而言之 :

我怎样才能加载一个NSBundle编译的Assets.car图像?

完整版:

我正在转换一套应用程序使用CocoaPods 。 每个应用程序都依赖于一个名为Core的共享窗格。

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

以下是创build资源包的Podspec for Core的相关行:

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

Podspec通过Podspec pod spec lint ,依赖于它的主项目正确构build。

但是, Core内的任何xcasset文件的图像都不显示。

我(天真地)尝试加载图像使用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是一个submodule ,而且这个解决scheme工作的很好。 然而,检查我以前的bundle文件(与main包分开),我注意到所有的图像被简单地复制到bundle …即

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

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

Assets.car

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

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

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

Podspec语法参考给出了这个例子:

 spec.resource = "Resources/HockeySDK.bundle" 

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

不过,这更像是一种解决scheme。

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

我和你的情况是一样的,最后我用了你提到的“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安装之前构build捆绑包,以便.bundle可用,然后可以像链接源一样链接。 这样我可以轻松地在捆绑目标中添加新的resources / images / xibs,并且它们将被编译和链接。 奇迹般有效。

我在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; } 

我还没有失败