区块链技术博客
www.b2bchain.cn

基于Swift Package Manager模块化解决方案求职学习资料

本文介绍了基于Swift Package Manager模块化解决方案求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

基于Swift Package Manager模块化解决方案

⚠️注意,就连即将9月10号发布正式版本的Swift5.3都无法支持二进制库互相依赖的关系,所以就算利用XCFramework也无法左右有一些第三方库可以支持Swift Package Manager

要求

  • iOS支持Swift Package Manager (最低Xcode11.4)
  • Swift Package Manager支持二进制库 (最低Xcode12

9月10号就发布Xcode12正式版本,所以这个模块化方案可行的。

目前模块化进展

基于Swift Package Manager模块化解决方案

image-20200904190746545

上面图是我们公司项目基于Swift Package Manager模块化的进展图,已经只有七八个界面还没模块化。其他的已经做成了模块化,从这个进展看来,这种模块化思想没有任何问题。

需要胶水代码和代码体验很差

胶水代码

因为并不是所有的目前Cocoapods库都可以支持Swift Package Manager,所以有一些调用Cocoapods的代码需要用胶水代码和模块交互。

我觉得并不是大问题,因为Flutter也需要一些胶水代码和原生代码交互。

代码体验差

这个主要在模块之间的通信,通过Key-Value进行通信,所以这个Key是字符串,所以编写代码体验十分差。

Swift Package Manager每次下来依赖慢

内网GitLab

对于依赖GitHub的依赖分析下来十分的缓慢问题,可以将依赖的库放在内网GitLab托管。因为第三方库也不需要经常更新,所以有的话大胆的去做吧。

本地依赖

对于没有内网GitLab的,可以采用本地依赖的形式。但是基于需要依赖版本的,所以有一个思路就是下载依赖的库存在本地,让依赖变成本地依赖。

~/path/Library/Name/1.0.2/Package.swift

这种依赖我之前写过命令行

https://github.com/Vapor4/SPMLocalMirror

当时是学习Vapor服务器框架,觉得下载依赖慢,影响学习。就写了这个工具,利用本地版本镜像加速依赖。

模块化过程遇到的问题

从A到B模块,我怎么可以获取B模块的对应跳转,而不需要依赖B呢?

我是通过一个全局的字段,保存一个App中注册的模块。在其他模块进行调用时候,在全局字段获取对应注册的模块,通过配置的参数,让对应模块返回自己的实例。

public mutating func register<T:ModifyModule>(_ controllerType:T.Type, customModify block:((Modify) -> Modify)? = nil) {     let block:((Modify) -> ModifyModule?) = { modify in         var _modify = modify         if let block = block {             _modify = block(_modify)         }         return T.make(_modify)     }     self.registerControllers[T.identifier] = block }

我们需要在App初始化注册所有用到的模块,用于中心转发。

ControllerCenter.center.register(ShareViewController.self) ControllerCenter.center.register(InformationViewController.self) ControllerCenter.center.register(InformationDetailViewController.self) ControllerCenter.center.register(SearchViewController.self) ControllerCenter.center.register(CollectListViewController.self) ControllerCenter.center.register(GuideViewController.self) ControllerCenter.center.register(MyViewController.self) ControllerCenter.center.register(AboutUsViewController.self) ControllerCenter.center.register(EditNameViewController.self) ControllerCenter.center.register(EditPhoneViewController.self) ControllerCenter.center.register(PhoneLoginViewController.self) ControllerCenter.center.register(BondViewController.self) ControllerCenter.center.register(RemindPopViewController.self) ControllerCenter.center.register(RemindAllViewController.self) ControllerCenter.center.register(TypeSelectionViewController.self)

上面就是我们App注册模块。

对应我们模块会用到App外部的全局变量,或者一些参数,或者更新App的一些参数,怎么做呢?

在ControllerCenter这个库里面,有一个全局的字典,用来获取App的一些全局参数,或者其他参数,可以用于和App进行交互。

ControllerCenter.center.set(globaleParameter: { modify in         return modify }

获取一个只读的参数

比如获取App内部一个常量是否开启关闭微信和QQ登录

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isHiddenWeixinQQ", block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)}) }

获取和设置一个不可选参数

比如App内部一个参数是是否登录,A模块用来判断是否登录,B模块登录之后设置更新这个值

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isLogin", block: {$0.parameter(modify: USER.isLogin)}) }

获取和设置一个可选参数

比如App内部一个用户Token,在其他模块推出可能会清空

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "token", block: {$0.parameter(modifyOptional: USER.token)}) }

比如其他模块需要和Cocoapods一些库交互或者和App交互

可以通过回掉进行交互

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "block", block: {$0.parameter(value: {          })}) }

我们项目目前的一些胶水代码

“`swift
ControllerCenter.center.set(globaleParameter: { modify in
return modify.parameter(key: “isLogin”, block: {$0.parameter(value: USER.isLogin)})
.parameter(key: “userId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “isHiddenWeixinQQ”, block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)})
.parameter(key: “dataCollection”, block: {$0.parameter(value: DATA_COLLECTION)})
.parameter(key: “memoryUserHeadImage”, block: {$0.parameter(modifyOptional: &USER.memoryUserHeadImage)})
.parameter(key: “headPic”, block: {$0.parameter(modifyOptional: &self.headPic)})
.parameter(key: “name”, block: {$0.parameter(modifyOptional: &self.name)})
.parameter(key: “serializeId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “token”, block: {$0.parameter(modifyOptional: &USER.jwtToken)})
.parameter(key: “needLoginCompletion”, block: {$0.parameter(value: { (controller:UIViewController,completion:@escaping(() -> Void)) in
USER.needLoginCompletion(loginController: controller, completion)
})})

基于Swift Package Manager模块化解决方案

⚠️注意,就连即将9月10号发布正式版本的Swift5.3都无法支持二进制库互相依赖的关系,所以就算利用XCFramework也无法左右有一些第三方库可以支持Swift Package Manager

要求

  • iOS支持Swift Package Manager (最低Xcode11.4)
  • Swift Package Manager支持二进制库 (最低Xcode12

9月10号就发布Xcode12正式版本,所以这个模块化方案可行的。

目前模块化进展

基于Swift Package Manager模块化解决方案

image-20200904190746545

上面图是我们公司项目基于Swift Package Manager模块化的进展图,已经只有七八个界面还没模块化。其他的已经做成了模块化,从这个进展看来,这种模块化思想没有任何问题。

需要胶水代码和代码体验很差

胶水代码

因为并不是所有的目前Cocoapods库都可以支持Swift Package Manager,所以有一些调用Cocoapods的代码需要用胶水代码和模块交互。

我觉得并不是大问题,因为Flutter也需要一些胶水代码和原生代码交互。

代码体验差

这个主要在模块之间的通信,通过Key-Value进行通信,所以这个Key是字符串,所以编写代码体验十分差。

Swift Package Manager每次下来依赖慢

内网GitLab

对于依赖GitHub的依赖分析下来十分的缓慢问题,可以将依赖的库放在内网GitLab托管。因为第三方库也不需要经常更新,所以有的话大胆的去做吧。

本地依赖

对于没有内网GitLab的,可以采用本地依赖的形式。但是基于需要依赖版本的,所以有一个思路就是下载依赖的库存在本地,让依赖变成本地依赖。

~/path/Library/Name/1.0.2/Package.swift

这种依赖我之前写过命令行

https://github.com/Vapor4/SPMLocalMirror

当时是学习Vapor服务器框架,觉得下载依赖慢,影响学习。就写了这个工具,利用本地版本镜像加速依赖。

模块化过程遇到的问题

从A到B模块,我怎么可以获取B模块的对应跳转,而不需要依赖B呢?

我是通过一个全局的字段,保存一个App中注册的模块。在其他模块进行调用时候,在全局字段获取对应注册的模块,通过配置的参数,让对应模块返回自己的实例。

public mutating func register<T:ModifyModule>(_ controllerType:T.Type, customModify block:((Modify) -> Modify)? = nil) {     let block:((Modify) -> ModifyModule?) = { modify in         var _modify = modify         if let block = block {             _modify = block(_modify)         }         return T.make(_modify)     }     self.registerControllers[T.identifier] = block }

我们需要在App初始化注册所有用到的模块,用于中心转发。

ControllerCenter.center.register(ShareViewController.self) ControllerCenter.center.register(InformationViewController.self) ControllerCenter.center.register(InformationDetailViewController.self) ControllerCenter.center.register(SearchViewController.self) ControllerCenter.center.register(CollectListViewController.self) ControllerCenter.center.register(GuideViewController.self) ControllerCenter.center.register(MyViewController.self) ControllerCenter.center.register(AboutUsViewController.self) ControllerCenter.center.register(EditNameViewController.self) ControllerCenter.center.register(EditPhoneViewController.self) ControllerCenter.center.register(PhoneLoginViewController.self) ControllerCenter.center.register(BondViewController.self) ControllerCenter.center.register(RemindPopViewController.self) ControllerCenter.center.register(RemindAllViewController.self) ControllerCenter.center.register(TypeSelectionViewController.self)

上面就是我们App注册模块。

对应我们模块会用到App外部的全局变量,或者一些参数,或者更新App的一些参数,怎么做呢?

在ControllerCenter这个库里面,有一个全局的字典,用来获取App的一些全局参数,或者其他参数,可以用于和App进行交互。

ControllerCenter.center.set(globaleParameter: { modify in         return modify }

获取一个只读的参数

比如获取App内部一个常量是否开启关闭微信和QQ登录

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isHiddenWeixinQQ", block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)}) }

获取和设置一个不可选参数

比如App内部一个参数是是否登录,A模块用来判断是否登录,B模块登录之后设置更新这个值

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isLogin", block: {$0.parameter(modify: USER.isLogin)}) }

获取和设置一个可选参数

比如App内部一个用户Token,在其他模块推出可能会清空

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "token", block: {$0.parameter(modifyOptional: USER.token)}) }

比如其他模块需要和Cocoapods一些库交互或者和App交互

可以通过回掉进行交互

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "block", block: {$0.parameter(value: {          })}) }

我们项目目前的一些胶水代码

“`swift
ControllerCenter.center.set(globaleParameter: { modify in
return modify.parameter(key: “isLogin”, block: {$0.parameter(value: USER.isLogin)})
.parameter(key: “userId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “isHiddenWeixinQQ”, block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)})
.parameter(key: “dataCollection”, block: {$0.parameter(value: DATA_COLLECTION)})
.parameter(key: “memoryUserHeadImage”, block: {$0.parameter(modifyOptional: &USER.memoryUserHeadImage)})
.parameter(key: “headPic”, block: {$0.parameter(modifyOptional: &self.headPic)})
.parameter(key: “name”, block: {$0.parameter(modifyOptional: &self.name)})
.parameter(key: “serializeId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “token”, block: {$0.parameter(modifyOptional: &USER.jwtToken)})
.parameter(key: “needLoginCompletion”, block: {$0.parameter(value: { (controller:UIViewController,completion:@escaping(() -> Void)) in
USER.needLoginCompletion(loginController: controller, completion)
})})

基于Swift Package Manager模块化解决方案

⚠️注意,就连即将9月10号发布正式版本的Swift5.3都无法支持二进制库互相依赖的关系,所以就算利用XCFramework也无法左右有一些第三方库可以支持Swift Package Manager

要求

  • iOS支持Swift Package Manager (最低Xcode11.4)
  • Swift Package Manager支持二进制库 (最低Xcode12

9月10号就发布Xcode12正式版本,所以这个模块化方案可行的。

目前模块化进展

基于Swift Package Manager模块化解决方案

image-20200904190746545

上面图是我们公司项目基于Swift Package Manager模块化的进展图,已经只有七八个界面还没模块化。其他的已经做成了模块化,从这个进展看来,这种模块化思想没有任何问题。

需要胶水代码和代码体验很差

胶水代码

因为并不是所有的目前Cocoapods库都可以支持Swift Package Manager,所以有一些调用Cocoapods的代码需要用胶水代码和模块交互。

我觉得并不是大问题,因为Flutter也需要一些胶水代码和原生代码交互。

代码体验差

这个主要在模块之间的通信,通过Key-Value进行通信,所以这个Key是字符串,所以编写代码体验十分差。

Swift Package Manager每次下来依赖慢

内网GitLab

对于依赖GitHub的依赖分析下来十分的缓慢问题,可以将依赖的库放在内网GitLab托管。因为第三方库也不需要经常更新,所以有的话大胆的去做吧。

本地依赖

对于没有内网GitLab的,可以采用本地依赖的形式。但是基于需要依赖版本的,所以有一个思路就是下载依赖的库存在本地,让依赖变成本地依赖。

~/path/Library/Name/1.0.2/Package.swift

这种依赖我之前写过命令行

https://github.com/Vapor4/SPMLocalMirror

当时是学习Vapor服务器框架,觉得下载依赖慢,影响学习。就写了这个工具,利用本地版本镜像加速依赖。

模块化过程遇到的问题

从A到B模块,我怎么可以获取B模块的对应跳转,而不需要依赖B呢?

我是通过一个全局的字段,保存一个App中注册的模块。在其他模块进行调用时候,在全局字段获取对应注册的模块,通过配置的参数,让对应模块返回自己的实例。

public mutating func register<T:ModifyModule>(_ controllerType:T.Type, customModify block:((Modify) -> Modify)? = nil) {     let block:((Modify) -> ModifyModule?) = { modify in         var _modify = modify         if let block = block {             _modify = block(_modify)         }         return T.make(_modify)     }     self.registerControllers[T.identifier] = block }

我们需要在App初始化注册所有用到的模块,用于中心转发。

ControllerCenter.center.register(ShareViewController.self) ControllerCenter.center.register(InformationViewController.self) ControllerCenter.center.register(InformationDetailViewController.self) ControllerCenter.center.register(SearchViewController.self) ControllerCenter.center.register(CollectListViewController.self) ControllerCenter.center.register(GuideViewController.self) ControllerCenter.center.register(MyViewController.self) ControllerCenter.center.register(AboutUsViewController.self) ControllerCenter.center.register(EditNameViewController.self) ControllerCenter.center.register(EditPhoneViewController.self) ControllerCenter.center.register(PhoneLoginViewController.self) ControllerCenter.center.register(BondViewController.self) ControllerCenter.center.register(RemindPopViewController.self) ControllerCenter.center.register(RemindAllViewController.self) ControllerCenter.center.register(TypeSelectionViewController.self)

上面就是我们App注册模块。

对应我们模块会用到App外部的全局变量,或者一些参数,或者更新App的一些参数,怎么做呢?

在ControllerCenter这个库里面,有一个全局的字典,用来获取App的一些全局参数,或者其他参数,可以用于和App进行交互。

ControllerCenter.center.set(globaleParameter: { modify in         return modify }

获取一个只读的参数

比如获取App内部一个常量是否开启关闭微信和QQ登录

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isHiddenWeixinQQ", block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)}) }

获取和设置一个不可选参数

比如App内部一个参数是是否登录,A模块用来判断是否登录,B模块登录之后设置更新这个值

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "isLogin", block: {$0.parameter(modify: USER.isLogin)}) }

获取和设置一个可选参数

比如App内部一个用户Token,在其他模块推出可能会清空

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "token", block: {$0.parameter(modifyOptional: USER.token)}) }

比如其他模块需要和Cocoapods一些库交互或者和App交互

可以通过回掉进行交互

ControllerCenter.center.set(globaleParameter: { modify in         return modify.parameter(key: "block", block: {$0.parameter(value: {          })}) }

我们项目目前的一些胶水代码

“`swift
ControllerCenter.center.set(globaleParameter: { modify in
return modify.parameter(key: “isLogin”, block: {$0.parameter(value: USER.isLogin)})
.parameter(key: “userId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “isHiddenWeixinQQ”, block: {$0.parameter(value: IS_HIDDEN_WEIXIN_QQ)})
.parameter(key: “dataCollection”, block: {$0.parameter(value: DATA_COLLECTION)})
.parameter(key: “memoryUserHeadImage”, block: {$0.parameter(modifyOptional: &USER.memoryUserHeadImage)})
.parameter(key: “headPic”, block: {$0.parameter(modifyOptional: &self.headPic)})
.parameter(key: “name”, block: {$0.parameter(modifyOptional: &self.name)})
.parameter(key: “serializeId”, block: {$0.parameter(value: USER.userInfo?.serializeId)})
.parameter(key: “token”, block: {$0.parameter(modifyOptional: &USER.jwtToken)})
.parameter(key: “needLoginCompletion”, block: {$0.parameter(value: { (controller:UIViewController,completion:@escaping(() -> Void)) in
USER.needLoginCompletion(loginController: controller, completion)
})})

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 基于Swift Package Manager模块化解决方案求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们