Alamofire - 优雅的处理 Swift 中的网络操作
网络处理,应该是我们平时开发的时候最常用到的操作。比如读取 JSON 数据,下载图片,这些操作都要和网络打交道,一个高效稳定的网络操作库对于提升我们日常的开发效率有着非常关键的作用。Alamofire 正是这样一个库,成熟,稳定,高效。
关于 Alamofire
如果你使用过 Objective-C 进行开发,那么你一定对 AFNetworking 这个库不陌生,在 Objective-C 生态中,这个库作为做常用的网络操作库之一,被大家广泛使用。Mattt Thompson 作为 AFNetworking 的发起人,在贡献了这个强大的第三方库之后,又基于 Swift 语言开发了一个新的网络操作库 - Alamofire。而 AFNetworking 前面的 AF 正是 Alamofire 的字头缩写。这样说起来就很明白了吧~
开始行动
现在我们就开始尝试使用 Alamofire 进行网络操作。
创建 Playground
首先在一个合适的地方建立一个目录:
$ mkdir alamofire
目录创建好之后,我们在这个目录中创建一个空的 workspace 文件,打开 Xcode 选择 File -> New -> Workspace...
将新建的 workspace 保存到我们刚刚创建的目录中。
然后打开这个 workspace ,点击 File -> New -> Playground... 在这个 workspace 中创建一个新的 Playground,在选项表单中填写如下内容:
然后点击下一步,将新创建的 Playground 存储到我们刚刚创建的目录中。
安装 Alamofire
我们推荐使用 Carthage 包管理的方式来安装 Alamofire,当然你也可以用你喜欢的其他方式来安装 Alamofire。
Alamofire 的 Github 主页上面详细说明了各种安装方法: https://github.com/Alamofire/Alamofire
我们也有一篇文章介绍如何使用 Carthage 包管理: http://swiftcafe.io/2015/10/25/swift-daily-carthage-package
如果需要,可以参考上面列出的内容。那么,我们就正式开始了,首先我们在我们创建的 alamofire 目录中创建一个 Cartfile 文件,里面写入 Carthage 包管理的配置信息:
github "Alamofire/Alamofire" ~> 3.0
配置文件里面非常简单,仅仅将 Alamofire 的 Github 名称和版本写进来。现在我们的 alamofire 目录应该包含这两个文件:
Cartfile
alamofire.playground
一个是 Carthage 的配置文件,另一个是我们刚刚创建的 playground 文件。配置完成后,我们输入:
carthage update
这个命令可以将我们在 Cartfile 中配置的依赖库下载并且构建出来,构建成功后,我们可以在 Carthage/Build/iOS 目录中看到构建出来的 Alamofire.framwork 库:
还可以在 Checkouts 目录中看到 Alamofire 的原始项目:
我们把 Checkouts 中的 Alamofire 目录拖动到我们的 workspace 中:
这样我们的 storyboard 就能够检测到 Alamofire 库了。
开始使用 Alamofire
环境配置好之后,我们可以在 storyboard 中导入 Alamofire 库:
import Alamofire
发送基本请求
导入完成后,我们就可以使用 Alamofire 请求网络了,我们可以发送最基本的 GET 请求:
Alamofire.request(.GET, "https://swiftcafe.io")
当然,我们还可以为请求添加参数,并且处理响应信息,调用方式也很简单:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
print(response.request) // 请求对象
print(response.response) // 响应对象
print(response.data) // 服务端返回的数据
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
Alamofire 提供了多种返回数据的序列化方法,比如刚才我们用到的 responseJSON
, 会返回服务端返回的 JSON 数据,这样就不用我们自己再去解析了。
下面是 Alamofire 目前支持的数据序列化方法:
- response()
- responseData()
- responseString(encoding: NSStringEncoding)
- responseJSON(options: NSJSONReadingOptions)
- responsePropertyList(options: NSPropertyListReadOptions)
支持普通数据,字符串, JSON 和 plist 形式的返回。
上传文件
Alamofire 提供了 upload 方法用于上传本地文件到服务器:
let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
当然,我们还可以获取上传时候的进度:
Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
print(totalBytesWritten)
// This closure is NOT called on the main queue for performance
// reasons. To update your ui, dispatch to the main queue.
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes written on main queue: \(totalBytesWritten)")
}
}
.responseJSON { response in
debugPrint(response)
}
还支持 MultipartFormData 形式的表单数据上传:
Alamofire.upload(
.POST,
"https://httpbin.org/post",
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(fileURL: unicornImageURL, name: "unicorn")
multipartFormData.appendBodyPart(fileURL: rainbowImageURL, name: "rainbow")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
下载文件
Alamofire 同样也提供了文件下载的方法:
Alamofire.download(.GET, "https://httpbin.org/stream/100") { temporaryURL, response in
let fileManager = NSFileManager.defaultManager()
let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let pathComponent = response.suggestedFilename
return directoryURL.URLByAppendingPathComponent(pathComponent!)
}
还可以设置默认的下载存储位置:
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
Alamofire.download(.GET, "https://httpbin.org/stream/100", destination: destination)
也提供了 progress 方法检测下载的进度:
Alamofire.download(.GET, "https://httpbin.org/stream/100", destination: destination)
.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print(totalBytesRead)
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes read on main queue: \(totalBytesRead)")
}
}
.response { _, _, _, error in
if let error = error {
print("Failed with error: \(error)")
} else {
print("Downloaded file successfully")
}
}
HTTP 验证
Alamofire 还很提供了一个非常方便的 authenticate 方法提供了 HTTP 验证:
let user = "user"
let password = "password"
Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
.authenticate(user: user, password: password)
.responseJSON { response in
debugPrint(response)
}
HTTP 响应状态信息识别
Alamofire 还提供了 HTTP 响应状态的判断识别,通过 validate 方法,对于在我们期望之外的 HTTP 响应状态信息,Alamofire 会提供报错信息:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { response in
print(response)
}
validate 方法还提供自动识别机制,我们调用 validate 方法时不传入任何参数,则会自动认为 200...299 的状态吗为正常:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.validate()
.responseJSON { response in
switch response.result {
case .Success:
print("Validation Successful")
case .Failure(let error):
print(error)
}
}
调试状态
我们通过使用 debugPrint 函数,可以打印出请求的详细信息,这样对我们调试非常的方便:
let request = Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
debugPrint(request)
这样就会产生如下输出:
$ curl -i \
-H "User-Agent: Alamofire" \
-H "Accept-Encoding: Accept-Encoding: gzip;q=1.0,compress;q=0.5" \
-H "Accept-Language: en;q=1.0,fr;q=0.9,de;q=0.8,zh-Hans;q=0.7,zh-Hant;q=0.6,ja;q=0.5" \
"https://httpbin.org/get?foo=bar"
结语
Alamofire 是一个非常强大并且使用简洁的网络操作库,接口非常的简单,而且稳定。关于 Alamofire 的更多信息,大家还可以到它的 Github 主页上面了解到更多。大家也可以下载我们这里个 playground 演示示例: https://github.com/swiftcafex/alamofireSamples
Alamofire - 优雅的处理 Swift 中的网络操作的更多相关文章
- swift中第三方网络请求库Alamofire的安装与使用
swift中第三方网络请求库Alamofire的安装与使用 Alamofire是swift中一个比较流行的网络请求库:https://github.com/Alamofire/Alamofire.下面 ...
- swift 中String常用操作
1. 字符串定义 var s = "aaaaaa" // 两个字符串均为空并等价. var emptyString = "" var anotherEmp ...
- 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON
项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...
- 如何在 Swift 中优雅地处理 JSON
阅读目录 在Swift中使用JSON的问题 开始 基础用法 枚举(Enumeration) 下标(Subscripts) 打印 调试与错误处理 后记 因为Swift对于类型有非常严格的控制,它在处 ...
- iOS: 在Swift中优雅的实现Substring
在Swift中,当我们想要截取某个字符串时,方法如下: let carNumber = "沪A12345" let startIndex = advance(userCar.car ...
- 怎样在Swift中使用CocoaPods-b
最近关于CocoaPods有很多的议论.你可能从别的开发者那里听到过,或者在Github的目录中看到过.如果你之前从来没有用过,你可能会问,"CocoaPods到底是什么?" 它不 ...
- 怎样在Swift中使用CocoaPods
怎样在Swift中使用CocoaPods 它不是神秘的亚马逊区域的部落人用手捡出来的生可可的豆荚,肯定不是!让CocoaPods website来回答可能是最好的: CocoaPods是Cocoa项目 ...
- 在Swift中应用Grand Central Dispatch(下)
在第一部分中, 你学到了并发,线程以及GCD的工作原理.通过使用dispatch_barrrier和dispatch_sync,你做到了让 PhotoManager单例在读写照片时是线程安全的.除此之 ...
- 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客
尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...
随机推荐
- 【2006】求N!的精确值
Time Limit: 3 second Memory Limit: 2 MB 对于阶乘函数,即使自变量较小,其函数值也会相当大.例如: 10!=3628800 25!=155112100433309 ...
- Java 学习(21):Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...
- [D3] Create Labels from Numeric Data with Quantize Scales in D3 v4
Sometimes data needs to be converted from a continuous range, like test scores, to a discrete set of ...
- 《大型网站技术架构》1:概述 分类: C_OHTERS 2014-05-07 20:40 664人阅读 评论(0) 收藏
参考自<大型网站技术架构>第1~3章 1.大型网站架构演化发展历程 (1)初始阶段的网站架构:一台服务器分别作为应用.数据.文件服务器 (2)应用服务和数据服务分离:三台服务器分别承担上述 ...
- USB 3.0规范中译本 第4章 超高速数据流模型
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章展示数据和信息如何在超高速上通过的一种高层次的描述.请阅读协议层一章关于低层次协议的细节.本章提供设备架 ...
- Android程序解析XML文件的方法及使用PULL解析XML案例
一.一般解析XML文件的方法有SAX和DOM.PULL (1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信 ...
- web.xml 中的listener、 filter、servlet 加载顺序及其详解(转)
在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是 ...
- 行列式(determinant)的物理意义及性质
1. 物理(几何)意义 detA=output areainput area 首选,矩阵代表的是线性变换(linear transformation).上式说明一个矩阵的行列式(detA)几何意义上, ...
- MKNetWorkKit的使用(1)
在整个程序中只有一个全局队列 MKNetWorkKit中主要有两个类,MKNetworkEngine和 MKNetworkOperation,MKNetworkOperation就是一个操作,是NSO ...
- 【BZOJ 1019】 [SHOI2008]汉诺塔
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1019 [题意] [题解] 这个题解讲得很清楚了 http://blog.sina.co ...