简而言之:
如何从 NSBundle
中已编译的 Assets.car
加载图像?
完整版:
我正在将一套应用程序转换为使用 CocoaPods
。每个应用程序都依赖于一个名为 Core
的共享 pod。
Core
包括代码文件、xib
文件和几个 xcasset
文件。
这是 Podspec
中用于创建资源包的 Core
的相关行:
s.resource_bundles = {'CoreResources' => ['Core/Resources/*']}
Podspec
通过了 pod spec lint
,依赖它的主项目正确构建。
但是,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
是一个子模块
,这个解决方案运行良好。然而,在检查我之前的 bundle
文件(与 main
bundle 分开)时,我注意到所有图像都被简单地复制到 bundle
... 即
Image.png
、Image@2x.png
等都在包中。
在检查 CocoaPods
生成的包时,它包含一个
Assets.car
据我所知,它是上述 Core
子目录中所有 xcasset
文件的组合编译版本。
我如何从这个编译过的 Assets.car
加载图像到这个 Core
资源包中?
作为黑客,我想我可以...
spec.resource = "Resources/HockeySDK.bundle"
这似乎表明可以在 Xcode 中手动创建包并让 CocoaPods 简单地复制它。
不过,这与其说是解决方案,不如说是hack。
我相信 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 install 之前构建 bundle,这样 .bundle 就可用了,然后就可以链接了,就像你一直在源代码中一样。这样我就可以轻松地在 bundle 目标中添加新的资源/图像/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;
}
我还没有失败过。
关于ios - 如何在 NSBundle 中从 Assets.car(xcassets 的编译版本)加载图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21857986/