网络处理,应该是我们平时开发的时候最常用到的操作。比如读取 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 目前支持的数据序列化方法:

  1. response()
  2. responseData()
  3. responseString(encoding: NSStringEncoding)
  4. responseJSON(options: NSJSONReadingOptions)
  5. 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 中的网络操作的更多相关文章

  1. swift中第三方网络请求库Alamofire的安装与使用

    swift中第三方网络请求库Alamofire的安装与使用 Alamofire是swift中一个比较流行的网络请求库:https://github.com/Alamofire/Alamofire.下面 ...

  2. swift 中String常用操作

    1.  字符串定义 var s = "aaaaaa" // 两个字符串均为空并等价. var emptyString = ""   var anotherEmp ...

  3. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  4. 如何在 Swift 中优雅地处理 JSON

    阅读目录 在Swift中使用JSON的问题 开始 基础用法 枚举(Enumeration) 下标(Subscripts) 打印 调试与错误处理 后记   因为Swift对于类型有非常严格的控制,它在处 ...

  5. iOS: 在Swift中优雅的实现Substring

    在Swift中,当我们想要截取某个字符串时,方法如下: let carNumber = "沪A12345" let startIndex = advance(userCar.car ...

  6. 怎样在Swift中使用CocoaPods-b

    最近关于CocoaPods有很多的议论.你可能从别的开发者那里听到过,或者在Github的目录中看到过.如果你之前从来没有用过,你可能会问,"CocoaPods到底是什么?" 它不 ...

  7. 怎样在Swift中使用CocoaPods

    怎样在Swift中使用CocoaPods 它不是神秘的亚马逊区域的部落人用手捡出来的生可可的豆荚,肯定不是!让CocoaPods website来回答可能是最好的: CocoaPods是Cocoa项目 ...

  8. 在Swift中应用Grand Central Dispatch(下)

    在第一部分中, 你学到了并发,线程以及GCD的工作原理.通过使用dispatch_barrrier和dispatch_sync,你做到了让 PhotoManager单例在读写照片时是线程安全的.除此之 ...

  9. 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客

    尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...

随机推荐

  1. iOS开发Quartz2D之十二:手势解锁实例

    一:效果如图: 二:代码: #import "ClockView.h" @interface ClockView() /** 存放的都是当前选中的按钮 */ @property ( ...

  2. ArcGIS Engine 编辑介绍

    转自原文 ArcGIS Engine 编辑介绍 IWorkspaceEdit接口是ArcGIS Engine 实现空间数据编辑的重要接口,它让程序启动或者停止一个编辑流程,在这个编辑流程内,可以对数据 ...

  3. 检测dll是32/64位?(直接读dll文件包含的某几个字节进行判断)

    检查dll是32位还是64位? #include "stdafx.h" #include <Windows.h> int _tmain(int argc, _TCHAR ...

  4. jquery的mouseover和mouseout闪烁问题

    $(document).ready(function(){ $(".anli").hover( function(){ var $div = $(this); t = setInt ...

  5. 数据序列化之protobuf

    数据序列化之protobuf 很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理.最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并 ...

  6. OSGi开发环境的建立

    1 OSGi开发环境的建立 1.1 Equinox是什么 从代码角度来看,Equinox其实就是OSGi核心标准的完整实现,并且还在这个基础上增加了一些额外的功能(比如为框架增加了命令行和程序执行的入 ...

  7. [Ramda] Pick and Omit Properties from Objects Using Ramda

    Sometimes you just need a subset of an object. In this lesson, we'll cover how you can accomplish th ...

  8. NSString与int和float的相互转换

    NSString *tempA = @"123"; NSString *tempB = @"456"; 1,字符串拼接 NSString *newString ...

  9. 毕设三: spark与phoenix集成插入数据/解析json数组

    需求:将前些日子采集的评论存储到hbase中 思路: 先用fastjson解析评论,然后构造rdd,最后使用spark与phoenix交互,把数据存储到hbase中 部分数据: [ { "r ...

  10. sparksql parquet 分区推断Partition Discovery

    网上找的大部分资料都很旧,最后翻了下文档只找到了说明 大概意思是1.6之后如果想要使用分区推断就要设置数据源的basePath,因此代码如下 java public class ParitionInf ...