1月 04, 2016发布在Swift
写在前面苹果在今年WWDC的时候称swift 2.0为面向协议的语言(Protocol-Oriented Programming)。Dave 用了45分钟的时间生动的阐述了什么是POP, 为什么要这么做。没看过的小伙伴建议去看下。
Session 408: Protocol-Oriented Programming in Swift
什么是协议(protocol)
协议这个概念在Objective-C中就存在了。所谓协议其实就是一系列可以调用方法的结合。在我们调用的时候就可以将注意力集中在方法本身而不是类的实现。苹果在swift 2.0里面给protocol赋予了更加强大的功能。protocol能够被直接扩展。这样prototol的使用更加灵活方便了。
正题来咯基于protocol可以被直接扩展的特性,我们可以很方便的实现一些经常被复用的代码。比如上传事件到一些数据分析平台上去。我这里用google analytics作为例子。
让我们先来看下之前是怎么做的。上传事件在程序中会被调用很多次,为了数据统计的准确性我们会在每个action里面都汇报到server上去。一般会有两种方法。
直接调用sdk的方法
这种一般都是比较简单的sdk,像Yahoo的Flurry,他的方法只有一行
Flurry.LogEvent("message")
对于这类的请求没有必要单独写一个类方法去实现。写一个类方法,然后调用
有些统计的sdk的实现要稍微多一些,比如google analytics。他的代码看起来是这样的
Googleanalyticscode vartracker=GAI.sharedInstance().defaultTracker tracker.set(kGAIScreenName,value:name) varbuilder=GAIDictionaryBuilder.createScreenView() tracker.send(builder.build()as[NSObject:AnyObject])
这个代码就有些多,或者我们想同时向几个分析平台发送事件的时候,一般都会写个类方法封装一下。然后用这样的方式在每个需要的地方调用。
Log.sendEvent("category",action:"action",label:"label",value:"value")
Swift 2.0 以后我们可以用另外一种方式来实现上面第二种方法。
定义一个protocol
protocolMTLog{ funclogEvent(category:String,action:String,label:String?,value:NSNumber?) }
扩展protocol,实现默认实现
extensionMTLog{ funclogEvent(category:String,action:String,label:String?=nil,value:NSNumber?=nil){ //Googleanalyticscode lettracker=GAI.sharedInstance().defaultTracker letbuilder=GAIDictionaryBuilder.createEventWithCategory(category,action:action,label:Label,value:Value) tracker.send(builder.build()as[NSObject:AnyObject]) } }
调用方法
现在我们可以用一种优雅的方式来调用了
logEvent("category",action:"action",label:"label",value:1)
如果不需要后面的参数也可以写成
logEvent("category",action:"action")
很多时候我们会将同一个view实现的事件作为同一个category来对待。为了避免错误,我们可以在定义protocol的时候定义一个变量作为一个view的默认category。代码可以修改为:
protocolMTLog{varcategory:String{get}funclogEvent(action:String,label:String?,value:NSNumber?)}extensionMTLog{funclogEvent(category:String,action:String,label:String?=nil,value:NSNumber?=nil){//Googleanalyticscodelettracker=GAI.sharedInstance().defaultTrackerletbuilder=GAIDictionaryBuilder.createEventWithCategory(category,action:action,label:Label,value:Value)tracker.send(builder.build()as[NSObject:AnyObject])}}
这样我们就不用担心因为typo的问题导致最终的统计结果出现偏差了。
有人会说这样的修改并没有给我们开发带来多大的便利。那么下面这个特性才是protocol的核心了。
我们的程序会有很多popup的信息,错误信息,版本提示信息等等等等。这时候我们不得不在每个需要用到的viewcontroller中都实现一遍。想不重复代码? 可以! 要么我们写一个UIViewController的基类。要么将viewController作为参数传进函数中。
现在我们可以这么做:
extensionMTLogwhereSelf:UIViewController{ funcerrorHandle(error:String){ letalertController=UIAlertController(title:nil,message:error,preferredStyle:.Alert) letcancelAction=UIAlertAction(title:"OK",style:.Cancel,handler:nil) alertController.addAction(cancelAction) self.presentViewController(alertController,animated:true,completion:nil) } }
这样就实现一个简单可复用的提示方法。而且这个方法只在继承与UIViewController的类才有效。这样就不需要实现一个难以控制的基类了。
这只是基于protocol的一个简单应用。还有其他的我们可以探讨。
代码我已经上传到github上了。有需要的小伙伴可以下来看看。
原文发表在我的blog中,欢迎大家访问。
I 相关 / Other
所有人都在说,用数据说话。运营有运营数据,营销有营销数据,产品肯定也有产品数据,各自的出发点不同,关
运筹大局 “文”者谋天下 CHIC2016春季展助推中国服装文化创意软实力
有人说,这是一个你醒来太慢,干脆就不用醒来的时代;也有人说,这是一个对手太强,但你连对手是谁
2016小熊B琪河南林州京新购物中心专卖店盛大开业!2016春装新品/冬装全场低至3.8折!众多礼品等您来抢!!!
2016春装新品/部分冬装全场3.8折起!全场3.8折起哦!
工厂直销,高质低价!
撼动全城,真正惠民
新春脚步临近 狄梵思黛恭祝大家万事如意!财源广进!新年快乐!
当1月1日00:00的钟声敲响时,我们就正式迈进了新年的大门。新的一年开启新的希望,新的一年承载新
《极品模王》为什么未播先火 《极品模王》播出时间演员及剧情介绍
1月18日,乐视超级网剧《极品模王》官微发布了主视觉海报,几大主演悉数出镜,以卖萌耍宝的表情神态展