美文网首页
iOS Swift Protocol的多种应用场景

iOS Swift Protocol的多种应用场景

作者: 落夏简叶 | 来源:发表于2020-02-03 11:56 被阅读0次

Swift 是面向协议编程 (Protocol Oriented Programming,以下简称 POP) 的。使用非常灵活,扩展性非常强。

项目中用到的Protocol很多,将应用的场景总结一下。(开始时不知其滋味,细细品味后欲罢不能,夸,总之是很好用就是了)
优点:

  • 代码复用
  • 功能模块清晰

Protocol 作为类型

  1. 数组中可以包含多种类型的数据
private protocol DBAvailableType {}
extension Bool: DBAvailableType {}
extension String: DBAvailableType {}
extension Int: DBAvailableType {}
extension Int16: DBAvailableType {}
extension Double: DBAvailableType {}
extension NSNull: DBAvailableType {}
var arguments: [DBAvailableType] = []
  1. 相似但不同的数据模型,给同一UI赋值(数据是协议类型:有时可能用ABtest两种方式获取的数据,为了兼容和复用)。
protocol MapRoute {
    var length: UInt { get }
    var duration: TimeInterval { get }
}

extension NMARoute: MapRoute {
    var length: UInt {
        return route.length
    }
    
    var duration: TimeInterval {
        return route.duration
    }
}

extension TPPRoute: MapRoute {
    var length: UInt {
        return route.length
    }
    
    var duration: TimeInterval {
        return route.duration
    }
}

埋点

虽然有些埋点可以通过hook的方式无侵入地添加,但是有些业务埋点代码被塞进逻辑中无可避免。开始时是直接写在控制器中调用,但是这样会让控制器变得臃肿。后来想到可以用Protocol,总结一下好处:

  • 减少控制器的埋点实现代码,在Protocol中定义好方法,并给出方法的默认实现。
  • 复用率高,不同地方都要埋点时,遵守协议即可。
  • 埋点也可以写在分类中,分散在不同的文件中。 但是复用率就不够高了。
  • 打点可以些在父控制器UIViewController中,也可以复用。但会加深代码层级,逻辑变得更加复杂。
  • Demo
protocol TPPSubscriptionPromoAnalyticProtocal {
    func logCompaignOctPageViewEvent(source: TPPCompaignOctPageViewEvent.Source) //定义方法
}


extension TPPSubscriptionPromoAnalyticProtocal {
//利用extension给出默认实现。
    func logCompaignOctPageViewEvent(source: TPPCompaignOctPageViewEvent.Source) {
        let event = TPPCompaignOctPageViewEvent(source: source)
        AnalyticsManager.log(event: event)
    }
}

// 使用时,遵守协议。在需要的地方调用方法即可
class TPPSubscriptionPromoVC: TPPSubscriptionPromoAnalyticProtocal {
}

Protocol 扩展方法和属性

  1. 为UIButton 或者特定的UIView的类添加放大效果
protocol TPPBigEffectProtocol: class {
    func biggerEffect()
}

//为UIButton添加方法效果方法。
extension UIButton: TPPBigEffectProtocol {
    func biggerEffect() {
        UIView.animate(withDuration: 0.25, animations: {
            self.transform = CGAffineTransform.init(scaleX: 1.5, y: 1.5)
        }) { (_) in
            self.transform = CGAffineTransform.identity
        }
    }
}
  1. 获取不同设备横竖屏状态下的有效内容高度(只要遵守了TPPDisplayViewProtocol的类对象都可以直接通过getViewWidth方法获取)
protocol TPPDisplayViewProtocol: AnyObject {
    func getViewWidth() -> CGFloat
}

extension TPPDisplayViewProtocol {
    func getViewWidth() -> CGFloat {
        let orientation = UIApplication.shared.statusBarOrientation
        if orientation == .portrait || orientation == .portraitUpsideDown {
            return UIScreen.main.bounds.width
        } else {
            if iPhoneXSeries {
                return (UIScreen.main.bounds.width - 88)
            } else {
                return UIScreen.main.bounds.width
            }
        }
    }
}
  1. 为一个tableViewCell设置一个唯一标志符,通常让cell 遵循一个协议,在协议里面定义一个uniqueIdentifier。用自己的类名作为唯一标识符。
// 1. 定义一个协议
protocol CellProtocol: class {
    static var uniqueIdentifier: String {get}
}

// 2. 协议扩展来实现属性
extension CellProtocol {
    static var uniqueIdentifier: String {
        return String(describing: type(of: self)).components(separatedBy: ".").first!
    }
}

// 3.调用
// 先遵守协议
class TPPReviewCell: UITableViewCell, CellProtocol {
}
// 在用到这个cell的cellForRow里面
let cell = tableView.dequeueReusableCell(withIdentifier: TPPReviewCell.uniqueIdentifier) as! TPPReviewCell

Protocol 和Delegate的配合使用

  1. 定义协议方法
protocol DropDownMenuDelegate: NSObjectProtocol {
    func menuView(_ menuView: DropdownMenuView, didSelectColumnAt index: Int)
}
  1. 设置delegate属性,调用
DropdownMenuView.swift

weak open var delegate: DropDownMenuDelegate?

if let delegate = delegate {
    delegate.menuView(self, didSelectColumnAt: index)
}
  1. 遵守协议,实现协议方法
TPPTruckDealerDetailController.swift
lazy private var dropMenuView = DropdownMenuView()

dropMenuView.delegate = self

extension TPPTruckDealerDetailController: DropDownMenuDelegate {
    func menuView(_ menuView: DropdownMenuView, didSelectColumnAt index: Int) {
        eventRecord(outcome: "Sort")
    }
}

相关文章

网友评论

      本文标题:iOS Swift Protocol的多种应用场景

      本文链接:https://www.haomeiwen.com/subject/mfcdactx.html