如何在Swift 中使用AFNetworking
苹果于2014年WWDC发布Swift全新语言,前不久2.0也正式发布,作为一个iOS开发人员,也一定要跟上节奏,因此最近在平时的闲暇时间,开始把自己做过的项目尝试用swift语言写了一遍,学习全新的语法和设计模式,由于学习Swift的时间比较短,今天主要简单说一下如何在Swift工程中使用时下比较流行的AFNetworking请求框架。
由于目前AFNetworking目前还没有Swift版本,因此我们的工程使用cocoapod来安装AFNetworking。
这是我的Prodfile文件,cocoapod的使用方法跟使用OC是时候是一模一样的,为了方便,我们在工程中随便创建一个类,选择语言OC,我们会发现工程中会多出来一个SwiftStudy-Bridging-Header.h文件,删除创建的oc类,在这里引入
好了,可以在swift文件使用AFNetworking
platform :ios, '7.0' pod 'SDWebImage', '~> 3.7.1' pod 'CocoaHTTPServer', '~> 2.3' pod 'RoutingHTTPServer', '~> 1.0.0' pod 'Masonry', '~> 0.6.1' pod 'ASIHTTPRequest', '~> 1.8.2' pod 'MBProgressHUD', '~> 0.9.1' pod 'AFNetworking', '~> 2.5.4'
在使用OC进行项目开发时,对AFNetworking做了一层简单的外部封装,今天我们就把它用Swift实现。
使用过新版AFNetworking的都知道它有一个AFHTTPSessionManager,在这里我们继承AFHTTPSessionManager使用单例模式返回一个该类的实例,
来进行网络操作在swift中单例的写法跟OC语法差别很大,Swift语法在这里不多讲解,请参考《The Swift Programming Language》,我们来看下代码
// // RequestClient.swift // SwiftStudy // // Created by 杨雯德 on 15/8/19. // Copyright (c) 2015年 杨雯德. All rights reserved. //
import UIKit class RequestClient: AFHTTPSessionManager { class var sharedInstance :RequestClient { struct Static { static var onceToken:dispatch_once_t = 0 static var instance:RequestClient? = nil } dispatch_once(&Static.onceToken, { () -> Void in //string填写相应的baseUrl即可 var url:NSURL = NSURL(string: "")! Static.instance = RequestClient(baseURL: url) }) //返回本类的一个实例 return Static.instance! } }
拿到RequestClient的实例我们就可以进行post、get以及上传图片文件的封装了
在OC中使用AFNetworking习惯使用block来进行数据的传递等,在Swift我们使用闭包来进行数据的传输
这是我的文件目录
SwiftStudy ------------工程目录
AppDelegate.swift
myViewController.swift
ViewController.swift
NetWork ------------网络相关
RequestClient.swift
RequestAPI.swift
CustomVC ------------VC的封装,
CostomNavigationVC.swift
BaseViewController.swift
在这里我们主要拿中国天气网的API测试一个PUT请求,来看下RequestAPI.swift。
override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.brownColor() var image:UIImage //Navigationbar 左侧返回按钮自定义,参考文件BaseViewController.swift self.leftButton(nil, hlIimage: nil, title: "返回", size: CGSize(width: 38, height: 30), action: "buttonClick", target: self) var dic:Dictionary= ["A":"a","B":"b","C":"c"]; //post测试 RequestAPI.POST("List", body: dic, succeed: succeed, failed:failed) //get测试 var getUrl:String = "http://m.weather.com.cn/atad/101190101.html" RequestAPI.GET(getUrl, body: nil, succeed: succeed, failed: failed) //文件上传 // Do any additional setup after loading the view. } func succeed(task:NSURLSessionDataTask!,responseObject:AnyObject!)->Void{ println("oh my god 成功了+\(responseObject)") } func failed(task:NSURLSessionDataTask!,error:NSError!)->Void{ println("oh shit 失败了") }
在ViewController我们通过调用RequestAPI的类方法GET来获取数据,同时我们定义了两个方法succeed和failed,注意看方法中得参数和AFHTTPSessionManager
返回数据的参数是一样的,这样我们的拿到的数据就是服务器给我们返回的全部数据,调用equestAPI的GET方法将讲个函数指针传递过去,网络请求成功之后会通过函数指针将数据返回。
然后我们就可以进行其他的工作了。
使用过新版AFNetworking会经常遇到3084 1011和1016错误,出现这几个错误一般是数据解析错误,更改AFNetworking里面相应的数据类型即可,也可以根据实际情况自己定义。
/** RequestClient.sharedInstance.requestSerializer = AFJSONRequestSerializer() RequestClient.sharedInstance.responseSerializer = AFJSONResponseSerializer() RequestClient.sharedInstance.requestSerializer.setValue("application/json,text/html", forHTTPHeaderField: "Accept") RequestClient.sharedInstance.requestSerializer.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") */
总结,AFNetworking已经是用的最多的网络的框架,对AFNetworking的进一步的简单外层封装,我们就可以避免网络请求时大量初始化工作,直接使用单例即可,这样提高了