GCDWebServer 使用详解

本文转载自 航歌 - 做最好的开发者知识平台,原博分为三篇讲解,我这里就合并成一篇进行转载,有一些部分做了一些改动,博文内的代码我使用OC和Swift 重新写了一遍,使用的是 Xcode 10.1

Swift - GCDWebServer使用详解1(介绍、安装配置、HTTP服务实现)

Swift - GCDWebServer使用详解2(实现静态、动态网站,Web服务器)

Swift - GCDWebServer使用详解3(文件传输、WebDav服务器实现)

一、GCDWebServer介绍

GCDWebServer 是一个基于 GCD 的轻量级服务器框架,用于内嵌到 MacOS 或者 iOS 系统的应用中提供 HTTP1.1 的服务。使用 GCDWebServer 我们可以很轻松的在我们的应用中搭建一个 HTTP 服务器,让用户可以通过浏览器访问我们应用中的数据。或者使用 GCDWebServer 来实现一个无线U盘 App。这个框架有什么使用场景呢,摘录博主在原博的评论,比如下面几个场景可以使用:

  1. 做个无线U盘这样的App(AppStore里搜一下就有好多)
  2. 做个无线相册这样的App(电脑使用浏览器直接访问到手机里的照片)
  3. 你的App如果需要用户导入一些文件进来
  4. 你的App如果需要导出一些文件到用户电脑上

Github主页:https://github.com/swisspol/GCDWebServer

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 请求

二、安装配置

原博是使用Swift,但是框架是使用OC编写的,并且原博是直接导入框架,所以需要配置一些东西,详情请参考原博第一篇的这部分内容,我这边直接使用 CocoaPods 导入框架,把一下内容加入到 Podfile中,然后运行 pod install 即可

1
2
3
pod "GCDWebServer", "~> 3.0"
pod "GCDWebServer/WebUploader", "~> 3.0"
pod "GCDWebServer/WebDAV", "~> 3.0"

三、实现一个简单的HTTP服务器

下面程序启动的时候会自动运行个 HTTP 服务,端口 8080。当用户访问这个服务时,会返回一个显示欢迎信息的 html 页面。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
webServer.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, processBlock: { (request) -> GCDWebServerResponse? 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!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
[webServer addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSString *html = @"<html><body>欢迎访问 <b>hangge.com</b></body></html>";
return [GCDWebServerDataResponse responseWithHTML:html];
}];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

我这里使用模拟器运行程序,让后使用电脑浏览器访问 http://localhost:8080 就可以看到效果了。由于我程序中没有对不同的请求分别做处理,所以无论任何请求服务器都会返回同样的 HTML 页面。

四、异步响应HTTP请求

上面的样例中我们是同步处理响应 HTTP 请求, GCDWebServer 3.0 起新增了异步地处理 HTTP 请求的特性,方便我们在响应中进行比较耗时的操作(如网路请求、I/O读写操作)。使用时只需将processBlock 方法改成 asyncProcessBlock 方法即可。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
webServer.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, asyncProcessBlock: { (request, completionBlock) in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5, execute: {
let html = "<html><body>欢迎访问 <b>hangge.com</b></body></html>"
let response = GCDWebServerDataResponse(html: html)
completionBlock(response)
})
})
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
[webServer addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] asyncProcessBlock:^(__kindof GCDWebServerRequest * _Nonnull request, GCDWebServerCompletionBlock _Nonnull completionBlock) {
//5秒后返回响应(模拟网络请求、I/O读写等耗时操作)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSString *html = @"<html><body>欢迎访问 <b>xiaovv.me</b></body></html>";
GCDWebServerDataResponse *reponse = [GCDWebServerDataResponse responseWithHTML:html];
completionBlock(reponse);
});
}];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

上面代码启动服务后,我们访问 http://localhost:8080 要等个 5 秒钟才回显示结果。

五、HTTP请求重定向

下面实现了一个从“/”“/index.html”的页面重定向样例(客户端跳转)。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
webServer.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, processBlock: { (request) -> GCDWebServerResponse? in
let html = "<html><body>欢迎访问 <b>hangge.com</b></body></html>"
return GCDWebServerDataResponse(html: html)
})
webServer.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self, processBlock: { (request) -> GCDWebServerResponse? in
let url = URL(string: "index.html", relativeTo: request.url)
return GCDWebServerResponse(redirect: url!, permanent: false)
});
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
[webServer addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSString *html = @"<html><body>欢迎访问 <b>xiaovv.me</b></body></html>";
return [GCDWebServerDataResponse responseWithHTML:html];
}];
[webServer addHandlerForMethod:@"GET" path:@"/" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSURL *url = [NSURL URLWithString:@"index.html" relativeToURL:request.URL];
return [GCDWebServerResponse responseWithRedirect:url permanent:NO];
}];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

上面代码启动服务后,我们访问 http://localhost:8080 时,便自动重定向到 http://localhost:8080/index.html。

六、实现Form表单功能

下面实现一个 HTTP 表单,一共用到了两个 handlers:

  • GET handler:产生一个包含一个简单的 HTML 表单响应。由于不需要 HTTP 请求中的 body 信息,因此直接采用 GCDWebServerRequest 类。
  • POST handler:从用户提交的表单中获取值,并将处理结果返回。由于需要得到 HTTP 请求中经过 encode 后的 body 信息中的表单值,就要借助于 GCDWebServerURLEncodedFormRequest 类。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
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>\(String(describing: value))</body></html>"
return GCDWebServerDataResponse(html: html)
});
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
[webServer addHandlerForMethod:@"GET" path:@"/" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSString *html = [NSString stringWithFormat:@"%@%@%@%@%@%@%@",@"<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 responseWithHTML:html];
}];
[webServer addHandlerForMethod:@"POST" path:@"/" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
GCDWebServerURLEncodedFormRequest *formRequest = (GCDWebServerURLEncodedFormRequest *)request;
NSString *value = [formRequest.arguments objectForKey:@"username"];
NSString *html = [NSString stringWithFormat:@"<html><body>%@</body></html>",value];
return [GCDWebServerDataResponse responseWithHTML:html];
}];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

程序启动后,我们使用电脑浏览器访问http://localhost:8080 会显示出一个 form 表单。

填写内容并提交后,会返回显示刚才我们提交的值。

七、实现一个静态的文件目录网站(Static Website)

GCDWebServer 内置的处理程序可以递归服务端目录,从而实现一个静态的文件目录浏览功能(只读)。同时我们还可以自由设置 “Cache - Control”头。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webServer = GCDWebServer()
webServer.addGETHandler(forBasePath: "/", directoryPath: NSHomeDirectory(), indexFilename: nil, cacheAge: 3600, allowRangeRequests: true)
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
[webServer addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:true];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

用模拟器运行程序,然后使用电脑浏览器访问 http://localhost:8080 便会显示出 App 的沙盒目录。我们可以点击浏览里面各个文件和文件夹,或者对文件进行下载操作。

八、实现动态网站(Dynamic Website)

有时候简单的静态页面浏览并不能满足我们的需求,我们可能需要页面能够根据不同的条件动态显示内容,这时可以借助 GCDWebServerDataResponse 类来实现。

GCDWebServerDataResponse 继承自 GCDWebServerResponse 类,它为我们提供了一套基本的模板技术。即根据模板和一组变量(格式为 %variable%)来生成 HTML 内容并返回。下面通过一个样例作为演示。

  1. 程序启动后,我们使用浏览器访问 http://localhost:8080 即可显示网站首页内容。(程序会自动重定向到 index.html 页面上)
  2. 点击网页左侧的图片列表,右侧 image 组件会显示响应的图片内容。这里注意的是:左侧的图片列表、以及标题并不是写死在 html 页面上的,而是通过程序里的变量填充到模版中生成的。
  3. 也就是说整个网站的 js、css、图片是静态的。而网页是动态的。

网站相关代码如下:

整个项目结构如下,其中 Website 文件夹(注意是文件夹,不是组)下放置的是网站中用到的所有页面和资源。

default.css 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.left {
float:left;
width:150px;
margin-right: 10px;
}
.title {
background-color: #339718;
color: #FFFFFF;
padding: 10px;
text-align: center;
}
li {
cursor:pointer;
}

index.html 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hangge.com</title>
<link rel="stylesheet" href="default.css" type="text/css">
<script src="jquery.js" charset="utf-8"></script>
<script>
$(document).ready(function(){
$("li").click(function(){
var data = $(this).attr("data");
$("#image1").attr("src","imgs/"+data);
});
});
</script>
</head>
<body>
<div class="left">
<div class="title">
%var_title%
</div>
<ul>
%var_li%
<ul>
</div>
<img id="image1" src="imgs/1.png">
</body>
</html>

Website 内全部内容请参考 源码 hangge_1563.zip,程序的具体代码:

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//获取网站文件夹路径
let websitePath = Bundle.main.path(forResource: "Website", ofType: nil)
let webServer = GCDWebServer()
//先设置个默认的handler处理静态文件(比如css、js、图片等)
webServer.addGETHandler(forBasePath: "/", directoryPath: websitePath!, indexFilename: nil, cacheAge: 3600, allowRangeRequests: true)
//再覆盖个新的handler处理动态页面(html页面)
webServer.addHandler(forMethod: "GET", pathRegex: "^/.*\\.html$", request: GCDWebServerRequest.self, processBlock: { (request) -> GCDWebServerResponse? in
let var_li = "<li data='1.png'>图片1</li>" +
"<li data='2.png'>图片2</li>" +
"<li data='3.png'>图片3</li>" +
"<li data='4.png'>图片4</li>"
let variables = [
"var_title": "点击切换图片",
"var_li": var_li,
]
let htmlTemplate = websitePath?.appending(request.path)
return GCDWebServerDataResponse(htmlTemplate: htmlTemplate!, variables: variables)
})
webServer.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self, processBlock: { (request) -> GCDWebServerResponse? in
let url = URL(string: "index.html", relativeTo: request.url)
return GCDWebServerDataResponse(redirect: url!, permanent: false)
});
//服务器启动
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("服务启动成功,使用你的浏览器访问:\(webServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *websitePath = [[NSBundle mainBundle] pathForResource:@"Website" ofType:nil];
GCDWebServer *webServer = [[GCDWebServer alloc] init];
//先设置个默认的handler处理静态文件(比如css、js、图片等)
[webServer addGETHandlerForBasePath:@"/" directoryPath:websitePath indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
//再覆盖个新的handler处理动态页面(html页面)
[webServer addHandlerForMethod:@"GET" pathRegex:@"^/.*\\.html$" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSString *var_li = [NSString stringWithFormat:@"%@%@%@%@",@"<li data='1.png'>图片1</li>",@"<li data='2.png'>图片2</li>",@"<li data='3.png'>图片3</li>",@"<li data='4.png'>图片4</li>"];
NSDictionary *variables = @{@"var_title": @"点击切换图片",
@"var_li": var_li};
NSString *htmlTemplate = [websitePath stringByAppendingString:request.path];
return [GCDWebServerDataResponse responseWithHTMLTemplate:htmlTemplate variables:variables];
}];
//HTTP请求重定向(/从定向到/index.html)
[webServer addHandlerForMethod:@"GET" path:@"/" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
NSURL *url = [NSURL URLWithString:@"index.html" relativeToURL:request.URL];
return [GCDWebServerResponse responseWithRedirect:url permanent:NO];
}];
[webServer startWithPort:8080 bonjourName:@"GCD Web Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webServer.serverURL);
}
@end

九、实现文件的上传下载服务

GCDWebUploaderGCDWebServer 的子类,它提供了一个现成的 HTML5 形式的文件上传下载器。GCDWebUploader 自带 UI 界面,让用户可以在浏览器里上传,下载,删除文件,以及在 iOS 应用的沙盒中创建目录文件夹。

在我们程序启动的时候会自动运行个 HTTP 服务,端口 8080。用户访问这个地址时,会显示一个进行文件管理的页面。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let documentsPath = NSHomeDirectory() + "/Documents"
let webUploader = GCDWebUploader(uploadDirectory: documentsPath)
webUploader.start(withPort: 8080, bonjourName: "Web Based Uploads")
print("服务启动成功,使用你的浏览器访问:\(webUploader.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *documentsPath = [NSString stringWithFormat:@"%@%@",NSHomeDirectory(),@"/Documents"];
GCDWebUploader *webuploader = [[GCDWebUploader alloc] initWithUploadDirectory:documentsPath];
[webuploader startWithPort:8080 bonjourName:@"Web Based Uploads"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webuploader.serverURL);
}
@end

我这里使用模拟器运行程序,然后使用电脑浏览器访问 http://localhost:8080 就可以看到效果了。在这里我们可以进行文件的上传、下载、重命名、删除,以及文件夹的创建、删除、重命名等操作。

十、实现一个WebDAV服务器

前面我们通过 GCDWebUploader 来实现一个基于 HTTP 的文件服务器,用户通过浏览器可以进行文件的上传下载等操作。

这次我们通过 GCDWebServer 来实现一个 WebDAV 服务器,让用户可以使用任意的 WebDAV 客户端,比如: Transmit (Mac),ForkLift (Mac) 或者 CyberDuck (Mac / Windows),来访问我们 App 的沙盒目录文件。

当我们程序启动的时候会自动运行个 WebDAV 服务,端口 8080。

Swift 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import UIKit
import GCDWebServer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let documentsPath = NSHomeDirectory() + "/Documents"
let wedDAVServer = GCDWebDAVServer(uploadDirectory: documentsPath)
wedDAVServer.start(withPort: 8080, bonjourName: "WebDAV Server")
print("服务启动成功,使用你的浏览器访问:\(wedDAVServer.serverURL!)")
}
}

OC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#import "ViewController.h"
#import <GCDWebServer.h>
#import <GCDWebServerDataResponse.h>
#import <GCDWebServerURLEncodedFormRequest.h>
#import <GCDWebUploader.h>
#import <GCDWebDAVServer.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *documentsPath = [NSString stringWithFormat:@"%@%@",NSHomeDirectory(),@"/Documents"];
GCDWebDAVServer *webDavServer = [[GCDWebDAVServer alloc] initWithUploadDirectory:documentsPath];
[webDavServer startWithPort:8080 bonjourName:@"WebDAV Server"];
NSLog(@"服务启动成功,使用你的浏览器访问:%@",webDavServer.serverURL);
}
@end

我这里使用模拟器运行程序,然后使用 WebDAV 客户端 Transmit 进行连接。

连接成功后,可以看到这个 App 的 Documents 目录下的所有文件,并可以进行相关操作。

如果是 Windows 系统,可以使用 Cyberduck 这个客户端工具进行连接操作。

以上就是GCDWebServer 的基本使用。