美文网首页iOS知识点iOS成长之路
Pod本地私有库使用图片和XIB资源文件

Pod本地私有库使用图片和XIB资源文件

作者: 梦里桃花舞倾城 | 来源:发表于2020-07-02 23:05 被阅读0次

    前言

    制作本地本地POD库就不做过多的介绍,因为本身就一个命令的事pod lib create xxxx

    pod库

    pod管理项目的时候,如果用到了图片或者XIB文件一般有两种写法:resources或者resource_bundles

    Example

     spec.resources = "CXSalesmanModule/**/*.{xib,png}"
    
    
    spec.resource_bundles = {
        'CXSalesmanModule' => ['CXSalesmanModule/**/*.{xib,png,xcassets}']
      }
    

    先来说说区别:

    • 利用 resources 属性可以指定 pod 要使用的资源文件。这些资源文件在build 时会被直接拷贝到 client targetmainBundle 里。这样就实现了把图片、音频、NIB等资源打包进最终应用程序的目的。但是这会导致POD库的资源文件和主工程里的资源文件命名冲突。

    Example

    主工程有一个a.png的图片,而pod库里面也有一个a.png的图片,此时就产生命名冲突了。

    • resource_bundles就是为了解决命名冲突的问题,CocoaPods0.23.0 加入的新属性。
    • resource_bundles会自动生成bundle把资源文件打包进去,resources则不会。所以我们在使用resources的时候一般都会把资源文件提前打包到bundle最后在添加。

    建议使用resource_bundles方式来管理资源文件

    use_frameworks重点

    OC项目pod init的时候一般是不使用use_frameworks!,但是当我们用cocoapods导入swift框架到swift项目和OC项目都必须要use_frameworks!

    对于Podfile有或者没有使use_frameworksresources或者resource_bundles这两种写法的最后编译之后生成的包是不一样的。

    • 如果使用了use_frameworks编译之后查看包,我们会发现POD库是放在mainBundle下的Frameworks目录下。
    • 没有使用use_frameworks,则不会生成Frameworks

    pod install编译之后我们来看下资源文件打包到哪里了

    show in finder products

    使用spec.resources写法

     spec.resources = ["CXSalesmanModule/**/*.{xib,png}"]
    
    
    没有使用user_frameworks
    resources没有使用user_frameworks

    如果使用图片或者XIB,因为资源文件是直接打包到和主工程的bundle也就是mainBundle,所以我们依旧可以和之前的写法一样:

    使用

    self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"];
    // xib 这里暂未做测试
    
    使用了user_frameworks
    resources使用user_frameworks

    此时我们发现pod库里面的资源文件被打包进了主工程(即:mainBundle)下的Frameworks->CXSalesmanModule.framework目录下:
    所以我们使用资源文件的时候,就不能直接加载mainBundle;我们需要找到资源文件所在的bundle

    获取bundle的两种方式

    通过class类型查找对应的bundle目录,这种在category中不能使用,虽然可以通过传入class的方式查找,但是容易出错。不建议使用

    NSBundle *cbundle = [NSBundle bundleForClass:[self class]]; 
    NSString *path = [bundle pathForResource:bundleName ofType:@"bundle"]; 
    NSBundle *bundle = [NSBundle bundleWithPath:path];
    

    使用

    NSURL *associateBundleURL = [[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:nil];
    associateBundleURL = [associateBundleURL URLByAppendingPathComponent:@"CXSalesmanModule"];
    associateBundleURL = [associateBundleURL URLByAppendingPathExtension:@"framework"];
    NSBundle *bundle = [NSBundle bundleWithURL:associateBundleURL];
    self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
      inBundle: associateBunle
    compatibleWithTraitCollection:nil];
    

    XIB同理也是通过Bundle去加载。

    使用spec.resource_bundles写法

    spec.resource_bundles = {
      'CXSalesmanModule' => ['CXSalesmanModule/**/*.{xib,png,xcassets}']
    }
    
    没有使用user_frameworks
    resource_bundles没有使用user_frameworks

    此时我们发现pod库里面的资源文件是被打包进了主工程(即:mainBundle)里面的CXSalesmanModule.bundle内,所以我们使用的话,只需要拿到这个bundle即可。这里也验证了上面所说的resource_bundles会默认生成bundle

    使用

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"CXSalesmanModule" withExtension:@"bundle"];
    NSBundle *bundle = [NSBundle bundleWithURL:url];
    self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
      inBundle: bundle
    compatibleWithTraitCollection:nil];
    
    使用了user_frameworks
    resource_bundles使用了user_frameworks

    此时我们发现pod库里面的资源文件是被打包进了主工程(即:mainBundle)下的Frameworks->CXSalesmanModule.framework->CXSalesmanModule.bundle目录下:
    所以我们使用资源文件的时候,就不能直接加载mainBundle;我们需要找到资源文件所在的CXSalesmanModule.bundle这里也验证了上面所说的resource_bundles会默认生成bundle

    使用

    NSURL *associateBundleURL = [[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:nil];
    associateBundleURL = [associateBundleURL URLByAppendingPathComponent:@"CXSalesmanModule"];
    associateBundleURL = [associateBundleURL URLByAppendingPathExtension:@"framework"];
    NSBundle *associateBunle = [NSBundle bundleWithURL:associateBundleURL];
    associateBundleURL = [associateBunle URLForResource:@"CXSalesmanModule" withExtension:@"bundle"];
    NSBundle *bundle = [NSBundle bundleWithURL:associateBundleURL];
    self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
      inBundle: bundle
    compatibleWithTraitCollection:nil];
    

    XIB同理也是通过Bundle去加载。

    总的来说,使用pod库里面的资源文件,我们只需要找资源文件所在的路径即可,如果是mainBundle则使用方式不变,如果是其他的bundle,我们只要获取到bundle就可以通过bundle去使用。

    图片存放方式

    • 直接将png格式的图片拖到Assets目录下。
    • 采用xcassets,将图片都放到Images.xcassets里面,新建项目的时候默认工程会有一个Assets.xcassets

    这里的图片是采用xcassets来打包的,按住command + n选择Asset Catalog即可。

    资源文件 生成Asset

    一般我们都是直接把图片放到相应的目录下,这里我要说的是resource_bundles打包图片使用xcassets的注意点

    注意(低于iOS10的系统)

    对于pod资源打包方式采用resource_bundles并且podfile里使用了user_framework,如果采用.xcassets方式打包图片,iOS9 Release环境下图片会加载不出来。如果未使用user_framework则可以正常展示(iOS8暂没有测试,以及采用resources来打包这里本人暂未做测试有兴趣的小伙伴可以去测试一波)

    相关文章

      网友评论

        本文标题:Pod本地私有库使用图片和XIB资源文件

        本文链接:https://www.haomeiwen.com/subject/uhodqktx.html