移动开发 \ iOS \ iOS组件化开发过程中的沙盒路径解决策略

iOS组件化开发过程中的沙盒路径解决策略

总点击16
简介:  在组件化开发的过程中,在业务组件中,常常会加载各种资源文件,例如png图片,mp3音频。js文件,txt文件等等。我们此时用之前常用的方法[NSBundlemainBundle]pathForResource:@\"123.png\"type:nil]时发现获取不

  在组件化开发的过程中,在业务组件中,常常会加载各种资源文件,例如png图片,mp3音频。js文件,txt文件等等。我们此时用之前常用的方法[NSBundle mainBundle] pathForResource:@"123.png" type:nil] 时发现获取不到路径了。具体原因我们下面进行详细的分解说明。

什么是NSBundle?

  bundle 是一个目录,其中包含了程序会使用到的资源.这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in).对应bundle,cocoa为我们提供了类NSBundle。bundle 文件的创建,只需要在本地创建一个文件夹,给文件夹添加后缀.bundle 就行了。在没有进行组件化开发的时候我们接触更多的是mainBundle。[NSBundle mainBundle]是获得NSBundle的一个单例对象,而[[NSBundle mainBundle] resourcePath]就是你的app打包后的路径。为了获取app目录下的文件,我们常用的几个方法是:

- (nullable NSURL *)URLForResource:(nullable NSString *)name withExtension:(nullable NSString *)ext

+ (nullable NSString *)pathForResource:(nullable NSString *)name ofType:(nullable NSString *)ext inDirectory:(NSString *)bundlePath

为什么组件化后[UIImage imageName:@"123.png"]不起作用了

  在我们日常开发的过程中, 绘制UI用到比较多的就是[UIImage imageName:@"123.png"],是什么原因呢,主要原因是[UIImage imageName:@"123.png"]是在mainbundle下去寻找资源文件的,而组件化后,相关的图片是在自己的pod组件对应的bundle下, 再使用之前的方法已经无法找到相关的图片。为了解决这个问题我写了两个方法来满足这个需求。但是为了方便大家的理解,我这里先和大家说说使用cocoapod创建组件,资源文件的保存方式。

组件化时资源文件如何配置

在组件化开发的过程中,比较常见的podspec文件对资源文件的配置


有几种形式。


1):资源文件在组件中相互独立

s.resource_bundles

优点:


组件独立


有资源文件版本管理


资源文件修改等跟着业务组件正常发版

注:这一中也是比较常见的,常见的开源库的资源文件都是这样保存的。


针对这一种情况,我这边写了相关的方法可以获取

/**

获取某个Bundle下的文件的路径

@param fileName 文件的名字,可以带后缀名

@param podName pod组件的名字

@param ext 文件的后缀名

@return 文件的路径

*/

+ (nullable NSString *)pathWithFileName:(nonnull NSString *)fileName podName:(nonnull NSString *)podName ofType:(nullable NSString *)ext;

/**

获取某个podName对象的bundle对象

@param podName pod的名字

@return 对应的bundle对象

*/

+ (nullable NSBundle *)bundleWithPodName:(nonnull NSString *)podName;

/**

获取某个podName下的nib文件并创建对象

@param nibName xib文件的名字

@param podName pod库名

@return 创建好的对象

*/

+ (nullable id)loadNibName:(nonnull NSString *)nibName podName:(nonnull NSString *)podName;

/**

获取某个pod下的UIStoryboard文件的对象

@param name UIStoryboard 的名字

@param podName pod库名

@return UIStoryboard 对象

*/

+ (nullable UIStoryboard *)storyboardWithName:(nonnull NSString *)name podName:(nonnull NSString *)podName;

/**

在模块内查找UIImage的方法

@param imageName 图片的名字,如果是非png格式的话,要带上后缀名

@param podName pod库名

@return UIImage对象

*/

+ (nullable UIImage *)imageWithName:(nonnull NSString *)imageName podName:(nonnull NSString *)podName;

具体实现如下:

+ (nullable NSString *)pathWithFileName:(nonnull NSString *)fileName podName:(nonnull NSString *)podName ofType:(nullable NSString *)ext{

if (!fileName ) {

return nil;

}

NSBundle * pod_bundle =[self bundleWithPodName:podName];

if (!pod_bundle.loaded) {

[pod_bundle load];

}

NSString *filePath =[pod_bundle pathForResource:fileName ofType:ext];

return filePath;

}

+ (nullable NSBundle *)bundleWithPodName:(nonnull NSString *)podName{

if (!podName) {

return nil;

}

NSBundle * bundle = [NSBundle bundleForClass:NSClassFromString(podName)];

NSURL * url = [bundle URLForResource:podName withExtension:@"bundle"];

NSArray *frameWorks = [NSBundle allFrameworks];

if (!url) {

for (NSBundle *tempBundle in frameWorks) {

url = [tempBundle URLForResource:podName withExtension:@"bundle"];

if (url) {

break;

}

}

}

NSBundle * pod_bundle =[NSBundle bundleWithURL:url];

if (!pod_bundle.loaded) {

[pod_bundle load];

}

return pod_bundle;

}

+ (nullable id)loadNibName:(nonnull NSString *)nibName podName:(nonnull NSString *)podName{

NSBundle *bundle =[self bundleWithPodName:podName];

id object = [[bundle loadNibNamed:nibName owner:nil options:nil] lastObject];

return object;

}

+ (nullable UIStoryboard *)storyboardWithName:(nonnull NSString *)name podName:(nonnull NSString *)podName{

NSBundle *bundle =[self bundleWithPodName:podName];

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:name bundle:bundle];

return storyBoard;

}

+ (nullable UIImage *)imageWithName:(nonnull NSString *)imageName podName:(nonnull NSString *)podName {

NSBundle * pod_bundle =[self bundleWithPodName:podName];

if (!pod_bundle.loaded) {

[pod_bundle load];

}

UIImage *image = [UIImage imageNamed:imageName inBundle:pod_bundle compatibleWithTraitCollection:nil];

return image;

}

demo地址如下 demo下载地址


注:当然了, pod创建组件库还有一些其他的资源文件管理的方案,但存在一些问题,不是官方推荐的,这里我就不过多介绍了,以免误导大家。

更多优质文章,可以微信扫码关注:


意见反馈 常见问题 官方微信 返回顶部