2016 年加入公司接手的第一个开发功能,当时刚学了两周 Swift, 这个项目作为上手项目。
体会到的是”面向协议“与”对象对象“的一点不同之处,另外用 Swift 写的代码,往严谨的方向走,确实会比 OC 舒服很多
也感谢当初 张晓旭, 对我每行代码做的 review, 获益良多
业务倒是不难,简单的做法,调用每个第三方平台的分享 sdk, 然后按着流程执行就好了。
但这也正是繁琐的地方:不同平台接口不同,分享方式不同,对图片视频的限制不同
基本上除了每个平台都能做”分享“以外, 内部调用方式和细节各不相同
(当时 2016 年,对图片视频限制很严格,大于 2M 就有不让上传,下图取于 2016 设计模块重构时)

我们对这样的调用都不满意,也不满意市面上 友盟,ShareSdk 等平台的实现。
简述
流程抽象
利用 swift 协议扩展的特性:
- 先找到,能完整描述所有平台 分享这个行为的共性:
- 都要先做分享能力判断(是否装 APP,是否系统集成)
- 都要鉴权
- 可能涉及先上传 云端 (对于平台不支持的,以云端连接分享)
- 都要执行分享
- 抽象这些共性,用协议描述
- 用协议扩展提供默认实现
- 分享平台都遵循此协议,各自实现同一个流程的差异部分
流程抽象完变成这个样子(图取于 2016 设计模块重构时):

代码实现
基于这样的流程:提供了描述流程的协议 protocol ShareItem (分享能力判断, 认证,分享)
(其中分享步骤又细化了一个协议ShareProtocol)
用 swift 特性:提供了协议的默认实现 extension ShareItem {}
再定义不同平台的类,遵循共同的流程协议,实现每个平台不同的部分:
ShareTwitter.swift,ShareWeChat.swift,ShareFacebook.swift …
最后加些工具类:入参封装:ShareParameter,云端上传封装:ShareNetworkManager

部分实例代码如下:分享步骤抽象层 protocol ShareItem
(ps.这部分内部曾对外开源)
ShareProtocol.swift
public protocol ShareItem: class {
var platform: SharePlatformType { get }
var icon: UIImage { get }
var name: String { get }
var shareMode: ShareMode { get }
var contentType: ShareContentType { get }
init(icon: UIImage, name: String, contentType: ShareContentType)
// MARK: - CanShare
func isCanShare() -> Bool
func canUseCustomShare() -> Bool
// MARK: - Author
func oAuth(complete: @escaping (ShareError?) -> Void)
// MARK: - Share
func openAppliaction(from controller: UIViewController, with params: ShareParameter?)
func share(
fromController controller: UIViewController,
params: ShareParameter,
complete: @escaping ShareComplete)
func customShare(
fromController controller: UIViewController,
params: ShareParameter,
complete: @escaping (ShareError?) -> Void)
// MARK: - Other
static func creatHashtap(hashtap: String, type: HashTagType) -> String
}
extension ShareItem {/* 实现默认行为*/}
“分享”这个行为的抽象:
public protocol ShareProtocol: ShareItem {
var uploadMode: UploadMode { get }
var uploadCancel: Bool { get set }
var progressVC: ShareUploadProgressController? { get set }
func shareVideo(
fromController controller: UIViewController,
params: ShareParameter,
complete: @escaping (ShareError?) -> Void)
func customUploadVideo(fromController controller: UIViewController,
params: ShareParameter,
complete: @escaping (ShareError?, URL?) -> Void)
}
extension ShareProtocol {/*实现默认行为*/}
16 年提交的 MR
ps.很感谢晓旭当时花时间逐行 review
ps2.这部分内部对外开源过,后来因为某些原因没在维护,所以可以放出来,部分评论中涉及的代码被我删除。
