说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

在Swift中,如何更优雅地处理网络返回数据?

HTML文档下载 WORD文档下载 PDF文档下载
在iOS开发中进行网络请求时,一般是获取到服务器返回的data后,再根据需求转换成JSON,图像等信息。在Swift时代,如何使用泛型和extension来让数据解析工作更加优雅?且看本文详解。

一、过去这么干

我们在iOS开发中进行网络请求的时候,一般是获取到服务器返回的data后,再根据我们的需要转换成JSON,图像等信息:

 let myURL = NSURL(string: "http://imgs.xkcd.com/comics/scrabble.png")!        let task = NSURLSession.sharedSession().dataTaskWithURL(myURL, completionHandler: { (data, response, error) -> Void in            let image = UIImage(data: data)            //use the image        })

但如果你的应用中存在各种类型的返回数据,那么你可能就要在各个网络请求的中进行重复的处理了。

二、在Swift-beta时代

下面,我们使用swift中的泛型和extension让你的数据解析工作更优雅。

首先我们建立一个protocol:

public protocol ResponseConvertible{    class func convertFromData(data:NSData!) -> (Self?,NSError?)}

这个protocol负责把网络请求返回的NSData转化成我们想要的任何类型。 相信大家应该注意到了返回中的Self了,把返回定义为Self是因为这个接口本身是没有包含类型信息的,我们并不知道哪个类会实现这个接口,所以我们使用Self来指代将要实现这个接口的类。 接着,我们使用extension来为JSON(我使用的是SwiftJSON),UIImage,NSData这三个类实现我们的ResponseConvertible接口:

extension JSON:ResponseConvertible{    public static func convertFromData(data:NSData!) -> (JSON?, NSError?){        let value = JSON(data: data, options: NSJSONReadingOptions.MutableContainers, error: nil)        switch value.type{        case .Null:            return (value, value.error)        default:            return (value, nil)        }    }}extension NSData:ResponseConvertible{    public class func convertFromData(data: NSData!) -> (NSData?, NSError?) {        return (data,nil)    }}extension UIImage:ResponseConvertible{    public typealias Result = UIImage    public class func convertFromData(data: NSData!) -> (UIImage?, NSError?) {        return (UIImage(data: data),nil)    }}

然后,我们再新建一个名为MyRequest的自定义的网络请求类:

class MyRequest <  T:ResponseConvertible> {      var url:NSURL      init(url:NSURL) {          self.url = url      }      //这里用一个简单的请求进行说明,实际应用中可以构建一个最适合你的网络请求框架      func aSimpleRequest(completionHandler:(T?,NSError!) -> ()){          let session = NSURLSession.sharedSession()          let task = session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in              if error == nil{                  //用ResponseConvertible接口进行数据转换                  let(object, converError) = T.convertFromData(data)                  completionHandler(object,converError)              }          })          task.resume()      }  }  

好了,准备工作完成,我们终于可以使用优化后的请求方法了。请求时,< T:ResponseConvertible>接受一个实现了ResponseConvertible接口的类型,例如UIImage:

let myURL = NSURL(string: "http://imgs.xkcd.com/comics/scrabble.png")!        MyRequest<  UIImage>(url: myURL).aSimpleRequest({image,error in            self.imageView.image = image        })

这样,我们只要在发起请求前定义好我们需要返回的类型,接口就会如愿地为你返回该类型的数据了。是不是比文章一开始的方法优雅多了?

三、现在应该这么干

不过,如果你现在把以上代码拷贝进你运行在Xcode6正式版的项目,你会发现Xcode会报错:


错误详情:

Protocol 'ResponseConvertible' requirement 'convertFromData' cannot be satisfied by a non-final class ('NSData') because it uses 'Self' in a non-parameter, non-result type position

而这些代码在Swift-beta时代是能正常运行的。看来苹果在Swift1.0中对Self的用法进行了修改。

根据错误的提示,我们需要把使用了Self的类定义为final,而这在自定义的类中的确有用:

final class MyClass: {    //...}

但是对于UIImage,NSData这些系统的类就无能为力了。这个问题困扰了我好一会,stackoverflow无果,请教一些盆友都表示对Self的用法不熟或压根没动过Swift。

最后,还是在typealias的帮助下绕过了,typealias 可以为已经存在的类型和方法重新定义一个快捷名字,比如:

typealias Result = UIImage

这里的Result就相当于UIImage类型了。 引入typealias后,以上的代码做如下修改,就能在新版本的Xcode下运行了:

public protocol ResponseConvertible{    typealias Result    class func convertFromData(data:NSData!) -> (Result?,NSError?)}
extension JSON:ResponseConvertible{    public typealias Result = JSON    public static func convertFromData(data:NSData!) -> (Result?, NSError?){        let value = JSON(data: data, options: NSJSONReadingOptions.MutableContainers, error: nil)        switch value.type{        case .Null:            return (value, value.error)        default:            return (value, nil)        }    }}extension NSData:ResponseConvertible{    public typealias Result = NSData    public class func convertFromData(data: NSData!) -> (NSData?, NSError?) {        return (data,nil)    }}extension UIImage:ResponseConvertible{    public typealias Result = UIImage    public class func convertFromData(data: NSData!) -> (UIImage?, NSError?) {        return (UIImage(data: data),nil)    }}
class MyRequest< T:ResponseConvertible> {    //这里用一个简单的请求说明,实际应用中可以构建一个最适合你的网络请求框架    var url:NSURL    init(url:NSURL) {        self.url = url    }    func aSimpleRequest(completionHandler:(T.Result?,NSError!) -> ()){        let session = NSURLSession.sharedSession()        let task = session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in            if error == nil{                let(object, converError) = T.convertFromData(data)                completionHandler(object,converError)            }        })        task.resume()    }}

使用:

let myURL = NSURL(string: "http://imgs.xkcd.com/comics/scrabble.png")!        MyRequest<  UIImage>(url: myURL).aSimpleRequest({image,error in            self.imageView.image = image        })

本文转载自:简书

(责编/唐小引)

新车间李大维:到集装箱里来看创客嘉年华 亚马逊推“登录与支付”功能 直接冲击PayPal Google编程之夏新里程碑:5000万行源代码 8500名学生开发者 非常实用的15款开源PHP类库 Runnable:一站式代码片段服务平台,打造编程界的YouTube 谷歌向所有开发者开放Google App Engine PHP Runtime “沟通”电子表格和矢量图形的“桥梁”:在线可视化工具Raw Facebook北极圈数据中心,Open Compute Project的力作! 最后三天!4折抢购2013移动开发者大会门票 电子书追踪统计,App Annie for eBooks上线 先驱还是模仿者?细数海外移动应用推广平台 IDC:PC出货量下滑终于放缓 联想销量再次第一 为什么说,用一块屏幕玩游戏是远远不够的? 编写代码?先熟悉一下编程语言界限吧! Spanner vs. F1:谷歌两大数据管理利器的整体对比及关联 移动设计需摒弃的几大PC应用设计方法 响应式导航设计案例解析(多图) 所见即所得:七大无需编程的DIY开发工具 前Google员工发布无痕搜索产品,阻老东家财路 VMware推出vCloud Suite及vSphere新版:可用性及性能双丰收 TIOBE 2013年10月编程语言排行榜:Groovy首次挤进Top 20 Cookie时代将结束:微软将开发跨PC、移动和Xbox跟踪技术 Web设计里需要避免的八大糟糕趋势 Groupon从ROR迁移至Node.js,响应速度大幅提升 腾讯云的Container实现 专为物联网打造的数据库TempoDB获得320万美元投资 MongoDB成为首位10亿美元初创,功臣可归功于Oracle? 程序员遇到Bug后的30种常见反应 扎克伯格豪掷3000万美元购四套房 梅耶尔和拉里佩奇也居于此 IBM研究人员:仅200条微博 就可构建人格剖析图 MDCC重磅讲师:Pebble CEO Eric Migicovsky 数据的合计怎么做? 多少钱 关于SQL语句问题 有关Table控件中动态添加的控件使用问题!!!!!!!!! 请问如何在局域网里面测算每个计算机分配的速度或数据流量? VC/MFC--是否是你的唯一选择? OA系统中的一个大问题,大难题, 四川五粮液将隆重推出一款CPU:"五粮液 Inside",促销口号:“买一块五粮CPU 送一瓶五粮液”,预购从速 请问用Swing,有第三方提供给XML显示/编辑好的组件么? 帮忙请教一个问题,计算机应用专业的英文全称怎么写? 打扰一下:第一次加,请各位多多指教 ! 明天高考了,祝福所有莘莘学子:金榜提名! dll 中的共享内存段 大家帮我推荐一本VC++快速入门的书,来者有分!! php 与 sql server2000 如何将char数组的某一段拷贝到另一个char数组里面?在线等待啊!急啊 大家有谁用过eclipse2.1+lomboz+jboss-3.2.1_tomcat-4.1.24呀!我怎么配置都不成功! 请教一个简单的SQL语句 问几个初级一点的问题:) 关于win2000server服务器安全的一个问题。 高分求助?获取用户IP并存在文件里的代码! 帮帮忙 获取DATAGRID中的更新列的数据发现只能得到更新前的数据 怎样用C或C++实现一个sql语言简单编译器 求一个特效:当鼠标停留在任务栏图标上,显示当前程序状态 在线等待,关于帮助文件的问题,急! 男人一定要看--打消那些有想娶美女的念头的男人 如何用C#在没有安装过office的机器上使用word功能 如何选择开发平台? 大家知道哪有买类似于阿里巴巴那种商城程序啊? 关于c/s的问题 如何用evb显示tip呢? 数据环境设计器怎么样去用? 文档保存时隐藏某一域的ls如何写? 视频点播怎么做啊?用什么服务器好?自己做收看WEB页怎么办啊? 怎样才能输出正确的书名号 ADO调用数据源,如何实现相对路径? 请问怎么让一个MDI子窗体永远保持非最大化并且在所有子窗体最后 一个简单的问题,看哪位兄弟可以解决 EDIT MASK的问题,在线等待。。。 关于winamp skins的问题 atmel的c51单片机是多少钱啊 怎样在程序启动时判断已经有一个程序副本正在执行? 求教:关于VC书籍 想从98升级到2K,如何实现? 高分寻找sqlserver2000的ppt文档!!!(不够再加) 调用MoveMemory,提示内存只读!急,在线等待! 高手请进,我自会给高分!!! 请教高手,谁会用BCB中的implib和tlib工具? 高分寻找sqlserver2000的ppt文档!!!(不够再加) 初学BC,提两个简单的问题 法罗斯岛灯塔在哪 No one spoke as the professor faced the class with the papers in her hand 为什么水银柱的高度就等于大气压别跟我说什么“因为管外的大气压支持着管内的水银柱,所以水银柱产生的压强,就等于大气压强”请给我一个详细的分析不要给我算式,我要知道原理 双氧水的溶解性求二氧化硫,二氧化氮,二氧化硫,三氧化硫,水 ,双氧水,一氧化氮,一氧化碳,氧化钠,氧化钡,氧化钙,氧化铜,氧化铁,氧化亚铁,氧化铝 ,氧化锌的溶解性. 尽量详细一点 I drop into desperation什么意思? 下面那个物质氧化性最强氯气 稀硫酸 硫酸铜 硫磺 全部都要. 小儿强酸强碱中毒怎么办 世界管理界的三大名言是? 关于水的古诗 要两首 强酸、强碱中毒 爸爸的灯塔的 读后感 请(分别)写出带山、鸟、水,这3个字的古诗!别弄错了,是带“山”字的一句,‘鸟’字的一句没,“水”字的一句,不是3个字同在一句诗内, 如图,在半径为4cm的圆中,有两条互相垂直的线段,圆心为o,并且oa=1cm,ab=2cm,那么,阴影部分面积和两块空白部分面积,谁大?大多少平方厘米? 如图,a//b.根据"两直线平行,同位角相等",得∠1=∠2.能说∠2通过平移得到∠1吗?∠1与∠3呢?如图,a//b.根据"两直线平行,同位角相等",得∠1=∠2.能说∠2通过平移得到∠1吗?∠1与∠3呢? 爸爸的灯塔 读后感600字 不要抄的 帮写出描写山,鸟,水和花的诗(各两首) 如图,直线A平行于B,点A在直线A上,点BC在直线B上,点D在直线BC上 爸爸 灯塔读后感 卫星云图怎么看云是从哪往哪流动的? usually i wear a sweater and an overcoatb in decmber.but now i 爸爸的灯塔读后感 云为什么会走 如何预防亚硝酸盐中毒 把这四个句子翻译成英文,谢谢了忘写句子了1、安排在明天的会议被推迟了2、劣质的食物有碍儿童的生长发育3、火车什么时候到达上海4、把这些文件传阅一下 主要是第二问 wear an overcoat an是宾语吗我的英语不好,造句或填空的时候谓语和宾语不会填!可以好心讲解一下吗(简单点)再顺便造几个例句呗.我英语实在是不会啊 英语翻译1.So if you want to save money ,try to choose clothes thst can be wahed.2.They thought there wsa a god up there who was in charge of the moon.3.Actually ,I notice adults all the time who cough and sneeze in public without placing a hand o 求各位讲几道难题,在一张平行四边形纸上剪下一个最大的三角形(不准拼接),这张平行四边形的利用率将达到多少?走同一段路,小飞要16分钟,小倩要12分钟,小倩的速度比小飞快几分之几?两 践华为城,因河为池?啥意思?偶的大名是"华池",偶祖父给起的,不过偶祖父去世的比较早,记得小时候他说偶的名字是根据这句古语,来的.各位能帮我解释一下吗?这古语的来历什么的.详细点的.谢 量子数的确定:,我(自学的学生)是这样想的:例如氯17个电子,电子排布为1s2,2s2,2p6,3s2,3p5,因为电子层数是3,所以主量子数n=3,故角量子数l可取0,1,2.又因为最后一个电子填入p层,所以l=1,故磁量 关于农时、气象、做人的谚语 关于春天的诗关于农时、气象、做人的谚语 关于春天的诗 He is finding his new work far more exciting能否改成:He is finding that his new work is far more exciting.请问,句意和语法有什么变化,他俩可以互换么? 硫化金属 颜色是否大多硫化金属是黑色的?不是的请举例~谢 世界上最容易被忘记的东西,就是爱情不好意思啊``` 要的是英文`` He is finding his new work far more exciting.这句话中的finding是进行时还是动名词?若是在别的例句中又该如何区分? 硫化盐一般是什么颜色的颜色 ln autumn,it is cool .l wear trousers and jackets .的汉语意思 为什么两条线平行时内错角,同位角,同旁内角相同?急需啊,2月4号就要~~~~~~~~~~~~~~~~~~``快~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``为什么两条线平行时,各队内错角,同位角,同旁内角相 UG中如何复制外部几何体 英语:snake,sofa,spider,street,sweater,table,television,towel,toy,trousers,watch,wear的中文意思是 he is finding his new work far more exciting.为什么这里有is,find不就是动词么,那find也可以做谓语啊 ug中从另外一个ug图复制过来的实体,在该图中为什么不能进行特征操作,比如实例几何体操作比如图中的吊耳,是从另外一个图中复制粘贴过来的,现在我想进实例几何特征,可是选不到该实体,因 数学书上写向量的表示方法:a ,AB ,请问a和AB上面是不是都得有箭头啊? I do not know.I wear size 19.这句英语的问句是什么(急用!拜托各位了)9点之前,明天我们就叫了。拜托了各位!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 遗传信息的传递路径... 快 在数学中P(AB)表示什么意思 氧化性最强的物质是什么?还原性最强的物质又是什么? 忆秦娥 娄山关 中文翻译 请教一个数学向问题 (-AB)+AB 是什么意思 结果 是多少 俺还没学 根据答语 写出相应的问句 1、I’m42kg 2、Amy is12 years old 3、I’m165 cm tall 4、I wear size 36还有5、My legs are 75 cm long 英语翻译 “渊”意思是什么?走向天底深渊的渊是什么意思? 什么物质氧化性最强 关于x的分式方程x减3分之2等于1加(3减x分之m)无解,那么m的值为(),3Q~ “深渊”的“渊”是什么意思 i wear size 18(改为一般疑问句) 要过程,要详细点谢谢 when I drop into the cliff I konw what is called heratbreak是什么意思 格林斯潘新书反思金融危机:我为何没能为何中美趋同反而滋生冲突?日本佐贺县秋季祭孔英媒:中国首支核潜艇部队在海上巡逻以色列拟释放第二批26名长期关押巴勒多地密集推高考改革 十年寒窗学数学只安倍称不容中国“武力崛起” 外媒称中胡万林治死者父亲:胡万林是杀人应关一大学生召妓嫌对方太丑 被逼下跪道歉还中国海警编队10月28日在中国钓鱼岛上海自贸区基本运行制度创新框架已建立伊利方舟安全演练推动内蒙“平安校园”宗庆后支招新浙商创业重在创新 不要走马尼拉拟筹800至1600万赔款 多吴伯雄盼两岸主管部门负责人借设办事处南京一司机装“自动翻转号牌框”遮蔽号国民党庆祝建党119周年 推出“党证雾霾笼罩三亚令人震惊 美报称中国降低外媒:安倍告诫中国勿以武力夺岛东道主哈萨克斯坦成世界拳击锦标赛最大谁拥有小布什政府最终决定权?———新金融服务团走进开发区曼联老板格雷泽过世农产品电商,尝试新玩法萌娃们为什么这么红潮起瓯江 水秀侨乡学生重新认识自我免费纸巾:出行路上的广告新媒体霍金为英格兰队“算命”澳大利亚队第一个到了助推实体经济和金融服务互动对接严控会议范围 避免重复参会凝望湘湖漫长婚姻幸福秘诀:《百年潮·中国梦》第四集:中国力量局部主题投资奥巴马西点演讲:美一直要当老大国外萌娃怎么穿桑巴闪耀,各路豪强备战忙■公告快讯王诗龄的待遇让明星阿姨们捶胸偶像还要中考
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘