Swift - GCDWebServer使用详解1(介绍、安装配置、HTTP服务实现)
作者:hangge | 2017-03-15 08:10
一、GCDWebServer介绍
GCDWebServer 是一个基于 GCD 的轻量级服务器框架,用于内嵌到 MacOS 或者 iOS 系统的应用中提供 HTTP1.1 的服务。使用 GCDWebServer 我们可以很轻松的在我们的应用中搭建一个 HTTP 服务器,让用户可以通过浏览器访问我们应用中的数据。或者使用 GCDWebServer 来实现一个无线U盘 App。
1,特点
- 设计优雅,易于使用。仅仅包含4个核心类:server, connection, request 和 response
- 设计良好的 API。头文件注释齐全,非常易于继承和定制个性化需求。
- 事件驱动模型。基于 GCD 框架,实现最佳性能和并发。
- 不依赖任何第三方源码。
- 符合新的 BSD 许可协议。
2,支持的功能
- 针对 http 请求,支持完全异步处理
- 针对较大 HTTP 请求和响应流,采用内存最优化策略
- 支持解析使用"application/x-www-form-urlencoded" 或者 "multipart/form-data"编码格式提交的 html 表单
- 支持对 json 格式的请求或响应进行解析和序列化
- HTTP 请求或响应采用分块传输编码
- HTTP 请求和响应采用 gzip 方式压缩
- 对本地文件的请求支持多种 HTTP 类型
- 采用通用、简单的密码保护访问认证机制
- 支持在 app 前台、后台或挂起时自动处理事务
- 完全支持 ipv4 和 ipv6
- 支持文件上传功能。提供通过浏览器实现文件上传和下载的接口。(GCDWebUploader -> GCDWebServer)
- 支持文件系统服务。DAV 不仅被看作 HTTP 的扩展,甚至被看作一种网络文件系统。(GCDWebDAVServer -> GCDWebServer)
3,不支持的功能
- 长连接
- https 请求
二、安装配置
(1)首先我们需要在:Target > Build Phases > Link Binary With Libraries 中添加动态库 libz

(2)将 GCDWebServer 整个源码包下载下来,然后将其中的 GCDWebServer 子文件夹添加到我们项目中来。

(3)创建并配置个桥接头文件,并将相关的库引入进来。
#import "GCDWebServer.h" #import "GCDWebServerDataResponse.h"
三、实现一个简单的HTTP服务器
下面程序启动的时候会自动运行个 HTTP 服务,端口 8080。当用户访问这个服务时,会返回一个显示欢迎信息的 html 页面。import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
webServer?.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self,
processBlock: {request in
let html = "<html><body>欢迎访问 <b>hangge.com</b></body></html>"
return GCDWebServerDataResponse(html: html)
})
webServer?.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer?.serverURL)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

由于我程序中没有对不同的请求分别做处理,所以无论任何请求服务器都会返回同样的 HTML 页面。
四、异步响应HTTP请求
上面的样例中我们是同步处理响应 HTTP 请求, GCDWebServer 3.0 起新增了异步地处理 HTTP 请求的特性,方便我们在响应中进行比较耗时的操作(如网路请求、I/O读写操作)。
1,样例代码
使用时只需将 processBlock 方法改成 asyncProcessBlock 方法即可。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
//异步响应HTTP
webServer?.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self,
asyncProcessBlock: { (request, completionBlock) in
//5秒后返回响应(模拟网络请求、I/O读写等耗时操作)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
let html = "<html><body>欢迎访问 <b>hangge.com</b></body></html>"
let response = GCDWebServerDataResponse(html: html)
//处理结束后回调GCDWebServer
completionBlock!(response)
}
})
webServer?.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer?.serverURL)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
2,运行效果
上面代码启动服务后,我们访问 http://localhost:8080 要等个 5 秒钟才回显示结果。五、HTTP请求重定向
1,样例代码
下面实现了一个从“/”到“/index.html”的页面重定向样例(客户端跳转)。
webServer?.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self,
processBlock: { (request) -> GCDWebServerResponse? in
let url = URL(string: "index.html", relativeTo: request?.url)
return GCDWebServerResponse.init(redirect: url, permanent: false)
})
2,运行效果
上面代码启动服务后,我们访问 http://localhost:8080 时,便自动重定向到 http://localhost:8080/index.html。

六、实现Form表单功能
1,样例说明
下面实现一个 HTTP 表单,一共用到了两个 handlers:
- GET handler:产生一个包含一个简单的 HTML 表单响应。由于不需要 HTTP 请求中的 body 信息,因此直接采用 GCDWebServerRequest 类。
- POST handler:从用户提交的表单中获取值,并将处理结果返回。由于需要得到 HTTP 请求中经过 encode 后的 body 信息中的表单值,就要借助于 GCDWebServerURLEncodedFormRequest 类。
2,相关配置
由于获取 form 表单数据用到了 GCDWebServerURLEncodedFormRequest,所以我们需要在桥接头文件中将相关的头文件引入。
#import "GCDWebServer.h" #import "GCDWebServerDataResponse.h" #import "GCDWebServerURLEncodedFormRequest.h"
3,样例代码
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
//处理get请求:/(返回一个提交表单)
webServer?.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self,
processBlock: { (request) -> GCDWebServerResponse? in
let html = "<html><body>" +
"<form name=\"input\" action=\"/\" method=\"post\" " +
"enctype=\"application/x-www-form-urlencoded\"> " +
"用户名: <input type=\"text\" name=\"username\">" +
"<input type=\"submit\" value=\"提交\">" +
"</form>" +
"</body></html>"
return GCDWebServerDataResponse(html: html)
})
//处理post请求:/(获取提交的表单数据,并返回结果)
webServer?.addHandler(forMethod: "POST", path: "/",
request: GCDWebServerURLEncodedFormRequest.self,
processBlock: { (request) -> GCDWebServerResponse? in
let formRequest = request as! GCDWebServerURLEncodedFormRequest
let value = formRequest.arguments["username"]
let html = "<html><body>\(value)</body></html>"
return GCDWebServerDataResponse(html: html)
})
webServer?.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer?.serverURL)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
4,效果图
(1)程序启动后,我们使用电脑浏览器访问 http://localhost 会显示出一个 form 表单。
(2)填写内容并提交后,会返回显示刚才我们提交的值。
全部评论(1)
我想知道这个东西的使用场景会是什么
站长回复: