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

  在组件化开发的过程中,在业务组件中,常常会加载各种资源文件,例如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创建组件库还有一些其他的资源文件管理的方案,但存在一些问题,不是官方推荐的,这里我就不过多介绍了,以免误导大家。

更多优质文章,可以微信扫码关注:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值