我怎么能从一个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.png
, Image@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; }
我还没有失败