Swift 优雅的协议扩展

it2022-05-05  150

Swift 优雅的协议扩展

仿view.snp.xxx的调用形式如何实现核心完整代码如下Swift 5.0协议扩展 Cocoapods下载

仿view.snp.xxx的调用形式

先看调用效果:“123456”.yy_Str.MD5ForLower32Bate()

"123456".yy_Str.MD5ForLower32Bate() //类似:view.snp.xxx

为什么要这么做呢?好处在哪呢?

降低耦合度:传统的写法,直接在类别中添加一个方法或属性例如: extension String { ///验证身份证号 func validateidnum() -> Bool { let idRegex = "^(\\d{14}|\\d{17})(\\d|[xX])$" let idTest:NSPredicate = NSPredicate(format: "SELF MATCHES %@", idRegex) return idTest.evaluate(with: self) } } 降低不必要的冲突:当另一个工程师也有类似的需求时,他也新建文件写啦同样的方法,这就会有冲突,然后排查…只需要一个属性,就能实现想要的扩展功能,代码简洁

如何实现

定义协议:YProtocolExtension.swift

//协议扩展 protocol YExtensionProtocol { associatedtype YExtensionType //给谁写扩展例如:UIView、String、UIButton var value: YExtensionType { get } } 定义一个实现该协议的结构体 struct YExtensionKitStructTypeEncodable<T>: YExtensionProtocol { ///实现协议的属性 var value: T typealias YExtensionType = T //指定类型(传入泛型) /// 构造方法 init(kit: T) { self.value = kit } } 同样我们也可以直接指定类型 struct YExtensionStringEncodable: YExtensionProtocol { ///实现协议的属性 var value: String typealias YExtensionType = String //指定类型 /// 构造方法 init(kit: String) { self.value = kit } } 扩展YExtensionProtocol,实现相关String中MD5加密的功能

注意:凡是协议中定义的函数自己在协议中实现啦,他就是可选的类型,反之,是继承协议着必须实现。

以String为例:MD5加密

import CommonCrypto //MARK:String-MD5加密32位 //where YExtensionType == String 指定YExtensionType:为那种类型 extension YExtensionProtocol where YExtensionType == String { ///MD5加密32位小写 func MD5ForLower32Bate() -> String { let str = value.cString(using: .utf8) let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8)) let digestLen = Int(CC_MD5_DIGEST_LENGTH) let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) CC_MD5(str!, strLen, result) let hash = NSMutableString.init() for i in 0..<digestLen { hash.appendFormat("x", result[i]) } result.deinitialize(count: digestLen) return String(hash) } ///MD5加密32位大写 func MD5ForUpper32Bate() -> String { let str = value.cString(using: .utf8) let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8)) let digestLen = Int(CC_MD5_DIGEST_LENGTH) let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) CC_MD5(str!, strLen, result) let hash = NSMutableString() for i in 0..<digestLen { hash.appendFormat("X", result[i]) } result.deinitialize(count: digestLen) return String(hash) } } 给String新增扩展:添加属性 //MARKL:有关字符串的扩展 extension String { ///第一种:直接指定类型的 var yy_Str: YExtensionStringEncodable { return YExtensionStringEncodable.init(kit: self) } ///第二种:泛型传递 var yy_kit: YExtensionKitStructTypeEncodable<String> { return YExtensionKitStructTypeEncodable.init(kit: self) } } 在ViewController测试结果如下 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. print("123456".yy_kit.MD5ForLower32Bate()) print("123456".yy_kit.MD5ForUpper32Bate()) print("——————————————————————————————————") print("123456".yy_Str.MD5ForLower32Bate()) print("123456".yy_Str.MD5ForUpper32Bate()) } // 输出结果如下: e10adc3949ba59abbe56e057f20f883e E10ADC3949BA59ABBE56E057F20F883E —————————————————————————————————— e10adc3949ba59abbe56e057f20f883e E10ADC3949BA59ABBE56E057F20F883E

核心完整代码如下

// // YExtensionProtocol.swift // YExtentionDemo // // Created by bruce yao on 2019/7/18. // Copyright © 2019 bruce yao. All rights reserved. // import Foundation import UIKit import CommonCrypto //协议扩展 protocol YExtensionProtocol { associatedtype YExtensionType var value: YExtensionType { get } } ///Struct类型的扩展基础 struct YExtensionKitStructTypeEncodable<T>: YExtensionProtocol { var value: T typealias YExtensionType = T /// 构造方法 init(kit: T) { self.value = kit } } struct YExtensionStringEncodable: YExtensionProtocol { ///实现协议的属性 var value: String typealias YExtensionType = String //指定类型(传入泛型) /// 构造方法 init(kit: String) { self.value = kit } } /Class类型的扩展基础 //final class YExtensionKitClassTypeEncodable<T>: YExtensionProtocol { // /// 泛型 // var value: T // typealias YExtensionType = T // /// 构造方法 // init(kit: T) { // self.value = kit // } //} //MARK:String-MD5加密32位 extension YExtensionProtocol where YExtensionType == String { ///MD5加密32位小写 func MD5ForLower32Bate() -> String { let str = value.cString(using: .utf8) let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8)) let digestLen = Int(CC_MD5_DIGEST_LENGTH) let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) CC_MD5(str!, strLen, result) let hash = NSMutableString.init() for i in 0..<digestLen { hash.appendFormat("x", result[i]) } result.deinitialize(count: digestLen) return String(hash) } ///MD5加密32位大写 func MD5ForUpper32Bate() -> String { let str = value.cString(using: .utf8) let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8)) let digestLen = Int(CC_MD5_DIGEST_LENGTH) let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) CC_MD5(str!, strLen, result) let hash = NSMutableString() for i in 0..<digestLen { hash.appendFormat("X", result[i]) } result.deinitialize(count: digestLen) return String(hash) } } //MARK:有关字符串的扩展 extension String { var yy_Str: YExtensionStringEncodable { return YExtensionStringEncodable.init(kit: self) } var yy_kit: YExtensionKitStructTypeEncodable<String> { return YExtensionKitStructTypeEncodable.init(kit: self) } }

Swift 5.0协议扩展 Cocoapods下载

链接:https://github.com/YaoChengZhen/YYExtentions.git

source 'https://github.com/CocoaPods/Specs.git' platform :ios, '9.0' target 'TargetName' do pod 'YYExtentions', end

最新回复(0)