简而言之:
如何从Assets.car
内的已编译NSBundle
加载图片?
完整版:
我正在将一套应用转换为使用CocoaPods
。每个应用都依赖于名为Core
的共享广告连播。
Core
包含代码文件,xib
文件和多个xcasset
文件。
以下是创建资源包的Podspec
Core
的相关行:
s.resource_bundles = {'CoreResources' => ['Core/Resources/*']}
Podspec
传递pod spec lint
,依赖于它的主项目正确构建。
但是,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
是submodule
,此解决方案运行正常。但是,在检查我之前的bundle
文件(与main
捆绑包分开)后,我发现所有图片都被简单地复制到了bundle
...即
Image.png
,Image@2x.png
等都在捆绑中。
检查CocoaPods
生成的包时,它包含
Assets.car
我理解为所有<{1}}子目录中所有 xcasset
个文件的组合编译版本。
如何在此Core
资源包中加载此已编译Assets.car
的图片?
作为一个黑客,我想我可以......
Core
这似乎表明可以在Xcode中手动创建捆绑包并让CocoaPods简单地复制它。
这更像是一个 hack 而非解决方案。
我相信CocoaPods(v 0.29+)可以完全处理这个......?
答案 0 :(得分:4)
我和你一样处于同样的境地,我最终选择了你提到的“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安装之前构建软件包,以便.bundle可用,然后就可以像在源代码中一样将它链接起来。这样我就可以轻松地在bundle目标中添加新的资源/ images / 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;
}
我还没有失败。