iOS 插件化开发汇总 Small框架
runfo1tvlf
8年前
<h3>应用插件化背景</h3> <p>目前很多应用功能越来越多,软件显得越来越臃肿。因此插件化就成了很多软件发展的必经之路,比如支付宝这种平台级别的软件:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b709a02989d4317b79ffd690fe87f84b.png"></p> <p>支付宝应用</p> <p>页上密密麻麻的功能,而且还在增多,照这个趋势发展下去,软件包的大小将会不可想象。目前常用的解决方案是使用web页面,但用户体验和Native界面是没法比的。</p> <p>设想,如果每一个功能点都是一个动态库,在用户想使用某个功能的时候让其从网络下载,然后手动加载动态库,实现功能的的插件化,就再也不用担心功能点的无限增多了,这该是件多么美好的事!</p> <h3>软件版本实时模块升级</h3> <p>还在忍受苹果动辄一周,甚至更长的审核周期吗?有了动态库妈妈就再也不用担心你的软件升级了!</p> <p>如果软件中的某个功能点出现了严重的bug,或者想在其中新增功能,你的这个功能点又是通过动态库实现的,这时候你只需要在适当的时候从服务器上将新版本的动态库文件下载到本地,然后在用户重启应用的时候即可实现新功能的展现。</p> <h3>共享可执行文件</h3> <p>在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。</p> <p>不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。</p> <p>PS: 上述关于动态库在iOS平台的使用,在技术上都是可行的,但本人并没有真正尝试过做出一个上线AppStore的应用,因此并不保证按照上述方式使用动态库一定能通过苹果审核!</p> <h3>模块化开发的优势:</h3> <ul> <li> <p>1、完美内置</p> <p>所有插件支持内置于宿主包中</p> </li> <li> <p>2、高度透明</p> <p>插件编码、布局编写方式与独立应用开发无异</p> <p>插件代码调试与整包开发无异</p> </li> <li> <p>3、极致裁剪</p> <p>对插件分离所有一切能分离的公共代码、资源</p> </li> <li> <p>4、无缝链接</p> <p>通过设定URI,宿主、本地化应用插件、本地化web插件、在线网页,以及任何自定义的插件之间能够相互调起与传递参数</p> </li> <li> <p>5、跨平台</p> <p>目前已支持Android、iOS以及html5插件。并且三者之间可以通过同一套Javascript接口进行通信。</p> </li> </ul> <h3>先看一下工程目录</h3> <p style="text-align:center"><img src="https://simg.open-open.com/show/04409d1f99763413a45899074b1c2f8f.jpg"></p> <p>工程目录.png</p> <h3>再来看一下效果图</h3> <p style="text-align:center"><img src="https://simg.open-open.com/show/8a8108bbaa38101011658fb4c59dac1d.gif"></p> <p>效果图</p> <h2>入门</h2> <p>1、 导入模板</p> <pre> <code class="language-objectivec">git clone https://github.com/wequick/Small.git cd Small/iOS cp -r Templates ~/Library/Developer/Xcode/Templates</code></pre> <p>重启Xcode</p> <p>2、 新建工程</p> <p>File -> New -> Project... ,选择 Small-pods 模板</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/8eb52dcef8312d33333ca560ba54e634.jpg"></p> <p>Small-pods Application.png</p> <p>3、 安装Pods</p> <pre> <code class="language-objectivec">cd [your-project-path] pod install --no-repo-update</code></pre> <p>4、 关闭工程并打开xcworkspace</p> <pre> <code class="language-objectivec">open *.xcworkspace</code></pre> <h2>工程讲解</h2> <p>1、工程配置重点</p> <p>(1)、bundle.json在SMBundle类中,方法</p> <pre> <code class="language-objectivec">-(instancetype)initWithDictionary:(NSDictionary *)dictionary</code></pre> <p>根据bundle.json配置文件信息查找framework、bundle文件,从而加载到应用中进行使用</p> <pre> <code class="language-objectivec">NSString *bundlePath = nil; NSString *bundleSuffix = @"bundle"; SMBundleType bundleType = SMBundleTypeAssets; if ([pkg rangeOfString:@".app."].location != NSNotFound || [pkg rangeOfString:@".lib."].location != NSNotFound) { bundleSuffix = @"framework"; bundleType = SMBundleTypeApplication; }</code></pre> <p>以上代码表明,要加载framework,pkg名称必须包含 .app. (模块库)、 .lib. (工具库),否则全部默认加载bundle包。因此bundle.json文件可以是这样的:</p> <pre> <code class="language-objectivec">"version": "1.0.0", "bundles": [ { "uri": "lib.utils", "pkg": "net.wequick.example.small.lib.utils" }, { "uri": "main", "pkg": "net.wequick.example.small.app.main" }, { "uri": "home", "pkg": "net.wequick.example.small.app.home" }, { "uri": "mine", "pkg": "net.wequick.example.small.app.mine" }, { "uri": "detail", "pkg": "net.wequick.example.small.app.detail" }, { "uri": "about", "pkg": "net.wequick.example.small.web.about" } ] }</code></pre> <p>(2)、 framework 编译成功后,名称跟 Product Name 一样,命名规则一般是这样的</p> <p>xx_xx_lib_xx<br> com_example_littleBit_lib_utils<br> xx_xx_app_xx<br> xx_xx_xx_xx<img src="https://simg.open-open.com/show/ed9ca1527c90b28f558be26221202d12.jpg"></p> <p>com_example_littleBit_lib_utils</p> <p>注意lib、app这些对查找framework文件相当重要,这所以会有"_",是small对"."做了替换</p> <p>(3)、 Principal class 设置,指定模块入口</p> <p><img src="https://simg.open-open.com/show/5d502d45e0aff47f57b2da2b355954d9.jpg"></p> <p>Principal class</p> <p>(4) framework 添加到主工程,不以 Linked 方式进行添加,使用 Build Phases 中的 Copy Bundle Resources 选项,将 framework 拖动添加其中即可,这样可以完成对 framework 编译完后的拷贝</p> <p><img src="https://simg.open-open.com/show/31181044fadba9af7ba43f1c8ce355db.jpg"></p> <p>Copy Bundle Resources</p> <p>(5)、完成添加,进入测试。使用过程中,有模块更新代码后,主工程调用发现功能未更新,这时候需要清理工程,重新编译;或者修改编译包配置,从而及时更新。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/758ac149e65402aefc485b5d70aab6e5.jpg"></p> <p>Edit Scheme</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/7e4eddbab98d491cdd66adbc0ebeb52c.png"></p> <p>Build Options</p> <h2>用例</h2> <ul> <li> <p>使用者模式Sample</p> <p>需要先编译Pods</p> </li> <li> <p>开发者模式DevSample</p> <p>需要去除并行编译模式: Edit Scheme... -> Build -> Build Options -> 口 Parallelize Build (取消选中状态)</p> <p>各个组件需要签名后才支持代码级别更新。示例中更新例子为 xib 内容更新。</p> <p>在没有设置签名之前,请在模拟器上跑示例。</p> </li> </ul> <h2>参考文献</h2> <p><a href="/misc/goto?guid=4959739992606044710" rel="nofollow,noindex">Small--Git传送门</a></p> <p><a href="/misc/goto?guid=4959739992729968912" rel="nofollow,noindex">WWDC2014之iOS使用动态库</a></p> <p><a href="/misc/goto?guid=4959739992855305888" rel="nofollow,noindex">iOS使用small创建iOS工程目录</a></p> <p><a href="/misc/goto?guid=4959739992964803644" rel="nofollow,noindex">Small用例</a></p> <p> </p> <p>来自:http://www.jianshu.com/p/af0013ce00c0</p> <p> </p>