Swift库资源文件获取

库资源包括图片、xib、xib对应的图片、以及其它文件等。

本文只分析总结获取图片资源文件中所遇到的坑;大致原理其实都是一样,当你真正理解了其中的原理再获取其它资源是一样的容易。

我们制作的库有动态库、静态库之分;首先理解下:

Bundle

我们构建的app以及framework都是一个bundle,它又主要分为2种:

1)Bundle.main

The main bundle lets you access the resources in the same directory as the currently running executable. For a running app, the main bundle offers access to the app’s bundle directory. For code running in a framework, the main bundle offers access to the framework’s bundle directory.

可以理解为构建的.app就是一个main bundle

2)Bundle(for: AnyClass)

The NSBundle object that dynamically loaded aClass (a loadable bundle), the NSBundle object for the framework in which aClass is defined, or the main bundle object if aClass was not dynamically loaded or is not defined in a framework.

通过在framework中定义的class返回一个bundle对象,如果没有定义或者动态加载那么返回的是main bundle,这里没有动态加载的意思就是我们平时制作的.a或者framework静态库返回的其实和main bundle是一样的。

本文调试开发的库是Swift版本,且framework静态库,并且这个库目前只有一个subspec子模块Extension(多个也是一样的),目录结构如下:

pod依赖可以在framework静态库以及源码进行切换,而上面已经说了如果是静态库,那么获取资源文件和宿主工程其实是一样的,怎么调试都能获取到资源文件,比较简单,如:

Bundle.main.loadNibNamed(<#T##name: String##String#>, owner: <#T##Any?#>, options: <#T##[AnyHashable : Any]?#>)

UIImage(named: <#T##String#>)

这种情况就不讨论了;

所以本文仅仅是调试验证在pod源码依赖(并且宿主app打包是通过动态库的形式,如果是静态库那么和上面一样比较简单就不讨论了)的情况进行开发调试。

为啥要研究这块?

因为你做好的库,并不确定对方拿到后在宿主工程中到底是以静态库的形式打包还是动态库的形式,所以为了通用性,必须都得实现。

1、Bundle(for: Self.self)

不能这样写,因为如果当前扩展子模块中是对UIImageView写的一个扩展,那么这里的self就表示的是UIImageView,而UIImageView是系统动态库里面定义的,所以得到的是:

系统的UIKitCore动态库。

2、查看Example.app里面的内容

选择target为Example,进行编译:

查看包里面的内容:

这就是扩展里面的资源bundle,查看里面的资源文件发现实际是放了2层,即framework—>Extension.bundle---->Extension.bundle/xxx.png,为什么呢?

是因为podspec挂载资源文件区别导致的

sp.resource_bundles = {
        'Extension' => ['xxx/Assets/xxx.bundle']
    }
sp.resource = 'xxx/Assets/xxx.bundle'

resource_bundles如果podfile控制不管是源码依赖还是库依赖打包成静态库或者动态库,那么生成的bundle资源文件都会被再包裹一层;xxx.bundle/xxx.bundle/.png

resource资源文件不会被包裹,只有一层。

这2种我们应该用哪一个呢?CocoaPods官方是强烈推荐用第一种,为了避免和main bundle中的资源文件名字冲突:

For building the Pod as a static library, we strongly recommend library developers to adopt resource bundles as there can be name collisions using the resources attribute.

现在很多第三方库带资源文件的不少使用的是第二种,其实如果按照规范,对应的bundle前面加上自己的库名字,这种冲突几率是很小的。

3、定义一个Class

为什么还要单独定义一个类呢?我们这里有1个特殊性,就是我们这里的子模块是一个Extension扩展,都是Swift系统库中Class的扩展,所以为了获取到当前bundle必须自定义一个class,我们这里创建一个xxExtension.swift,然后在Example中进行调试:

(lldb) po Bundle(for: xxExtension.self)
NSBundle </Users/xx/Library/Developer/CoreSimulator/Devices/700BD15-4005-4C6B-943B-73CA56C020F/data/Containers/Bundle/Application/996818F0-9F7A-42DC-A02D-066A32B5E940/xxBaseModule_Example.app> (loaded)

(lldb) po Bundle.main
NSBundle </Users/xx/Library/Developer/CoreSimulator/Devices/700BD15-4005-4C6B-943B-73CA56C020F/data/Containers/Bundle/Application/996818F0-9F7A-42DC-A02D-066A32B5E940/xxBaseModule_Example.app> (loaded)

(lldb) 

????

为啥会是一样的?都是main bundle?官方文档不是说Bundle(for: AnyClass)中如果传入的是库中定义的类,应该返回的是xxBaseModule.framework才对,为啥不对???

原因:

还记得我们最上面的工程目录结构吗,project中有2个target,一个是我们的Example,一个是子Extension静态库的源码,而pod中是Development Pods本地私有库。

问题就出在Extension对应的target那里,我们当初创建它的目的是可以很方便的给这个组件库调试修改bug、增加功能等;虽然podfile中有引入这个组件,但是实际上我们Example中import的是import Extension 子模块,并不是基础模块xxBaseModule,而这个Extension对应的building我们当初定义的是一个静态库,所以无论你podfile如何更改,这里获取到的肯定是main bundle,那么我们要模拟pod源码依赖且动态库打包到宿主工程,我们应该如何做???

修改Extension对应的building为动态库。

4、Extension.framework和xxBaseModule.framework

编译后再次查看.app里面的内容,你会看到:

在这里插入图片描述

为啥获取到的是Extension.framework???

应该是xxBaseModule.framework才对啊,并且看上面截图也知道资源文件是放在这个里面的。

原因:

其实这里也还是因为上面Example项目中Extension对应的target导致的,这个时候就得新创建一个项目,通过podfile导入进行测试,正确。

其实这里是不用这么麻烦再创建一个新项目来验证的,目的是为了让自己能更清晰的理解bundle以及这里Example项目产生bug的原因。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenStack Swift是一个分布式对象存储系统,它可以用于存储和检索大文件。以下是在OpenStack Swift中处理大文件的一些建议: 1. 分片上传:将大文件分割成较小的块,并分别上传到Swift中。这样可以减少单个请求的负载,并且在网络中断或失败的情况下可以更容易地重试或恢复上传。你可以使用Swift提供的分片上传功能,或者在客户端层面实现分片上传。 2. 并发上传:使用多个并发连接同时上传文件的不同部分。这可以提高上传速度和效率。你可以在客户端层面实现并发上传,或者使用一些支持并发上传的工具。 3. 使用适当的线程和连接数:根据你的网络带宽和系统资源,调整并发连接数和线程数。如果连接数太多或线程数太多,可能会导致网络拥塞或系统资源不足。 4. 调整Swift配置:根据你的需求和性能测试结果,调整Swift的配置参数,如最大分片大小、并发限制等。这些配置可能会影响大文件的上传和检索性能。 5. 断点续传和故障恢复:实现断点续传和故障恢复机制,以便在上传过程中出现错误或中断时能够从上次中断的地方继续上传。 6. 压缩和加速:对于特别大的文件,可以考虑在上传前进行压缩,以减少传输时间和存储空间。另外,使用CDN等加速技术可以提高大文件的下载速度。 这些是处理大文件的一些常见方法和建议,但具体实施取决于你的具体需求和环境。你可以根据自己的情况选择适当的方法,并结合Swift的功能和配置进行调整。请参考OpenStack Swift的文档和相关资源,以获取更详细的信息和指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值