【设计总结】将各有不同实现的分享平台,做统一化抽象(含 swift 代码)

2016 年加入公司接手的第一个开发功能,当时刚学了两周 Swift, 这个项目作为上手项目。
体会到的是”面向协议“与”对象对象“的一点不同之处,另外用 Swift 写的代码,往严谨的方向走,确实会比 OC 舒服很多
也感谢当初 张晓旭, 对我每行代码做的 review, 获益良多

业务倒是不难,简单的做法,调用每个第三方平台的分享 sdk, 然后按着流程执行就好了。
但这也正是繁琐的地方:不同平台接口不同,分享方式不同,对图片视频的限制不同
基本上除了每个平台都能做”分享“以外, 内部调用方式和细节各不相同
(当时 2016 年,对图片视频限制很严格,大于 2M 就有不让上传,下图取于 2016 设计模块重构时)

我们对这样的调用都不满意,也不满意市面上 友盟,ShareSdk 等平台的实现。

简述

流程抽象

利用 swift 协议扩展的特性:

  1. 先找到,能完整描述所有平台 分享这个行为的共性
    • 都要先做分享能力判断(是否装 APP,是否系统集成)
    • 都要鉴权
    • 可能涉及先上传 云端 (对于平台不支持的,以云端连接分享)
    • 都要执行分享
  2. 抽象这些共性,用协议描述
  3. 用协议扩展提供默认实现
  4. 分享平台都遵循此协议,各自实现同一个流程的差异部分





流程抽象完变成这个样子(图取于 2016 设计模块重构时):

代码实现

基于这样的流程:提供了描述流程的协议 protocol ShareItem分享能力判断认证分享
(其中分享步骤又细化了一个协议ShareProtocol

用 swift 特性:提供了协议的默认实现 extension ShareItem {}

再定义不同平台的类,遵循共同的流程协议,实现每个平台不同的部分:
ShareTwitter.swiftShareWeChat.swiftShareFacebook.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.这部分内部对外开源过,后来因为某些原因没在维护,所以可以放出来,部分评论中涉及的代码被我删除。