写在前面
苹果在今年WWDC的时候称swift 2.0为面向协议的语言(Protocol-Oriented Programming)。Dave 用了45分钟的时间生动的阐述了什么是POP, 为什么要这么做。没看过的小伙伴建议去看下。
什么是协议(protocol)
协议这个概念在Objective-C中就存在了。所谓协议其实就是一系列可以调用方法的结合。在我们调用的时候就可以将注意力集中在方法本身而不是类的实现。苹果在swift 2.0里面给protocol赋予了更加强大的功能。protocol能够被直接扩展。这样prototol的使用更加灵活方便了。
正题来咯
基于protocol可以被直接扩展的特性,我们可以很方便的实现一些经常被复用的代码。比如上传事件到一些数据分析平台上去。我这里用google analytics作为例子。
让我们先来看下之前是怎么做的。
上传事件在程序中会被调用很多次,为了数据统计的准确性我们会在每个action里面都汇报到server上去。一般会有两种方法。
直接调用sdk的方法
这种一般都是比较简单的sdk,像Yahoo的Flurry,他的方法只有一行Flurry.LogEvent(“message”)对于这类的请求没有必要单独写一个类方法去实现。
写一个类方法,然后调用
有些统计的sdk的实现要稍微多一些,比如google analytics。他的代码看起来是这样的
1 | Google analytics code |
这个代码就有些多,或者我们想同时向几个分析平台发送事件的时候,一般都会写个类方法封装一下。然后用这样的方式在每个需要的地方调用。
Log.sendEvent("category", action: "action", label: "label", value: "value")
现在我们可以用更加优雅的方式实现
Swift 2.0 以后我们可以用另外一种方式来实现上面第二种方法。
定义一个protocol
1 | func logEvent(category: String, action: String, label: String?, value: NSNumber?) |
extension MTLog {
func logEvent(category: String, action: String, label: String? = nil, value: NSNumber? = nil ) {
//Google analytics code
let tracker = GAI.sharedInstance().defaultTracker
let builder = GAIDictionaryBuilder.createEventWithCategory(category, action: action, label: Label, value: Value)
tracker.send(builder.build() as [NSObject : AnyObject])
}
}
1 |
|
protocol MTLog {
var category: String {get}
func logEvent(action: String, label: String?, value: NSNumber?)
}
extension MTLog {
func logEvent(category: String, action: String, label: String? = nil, value: NSNumber? = nil ) {
//Google analytics code
let tracker = GAI.sharedInstance().defaultTracker
let builder = GAIDictionaryBuilder.createEventWithCategory(category, action: action, label: Label, value: Value)
tracker.send(builder.build() as [NSObject : AnyObject])
}
}
1 |
|
extension MTLog where Self: UIViewController {
func errorHandle(error: String) {
let alertController = UIAlertController(title: nil, message: error, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
```
这样就实现一个简单可复用的提示方法。而且这个方法只在继承与UIViewController的类才有效。这样就不需要实现一个难以控制的基类了。
这只是基于protocol的一个简单应用。还有其他的我们可以探讨。
代码我已经上传到github上了。有需要的小伙伴可以下来看看。