iOS 使用 libcurl

libcurl 简介

libcurl 是用C语言写的一套 开源 库,是为网络客户端提供数据传输功能的函数库。

libcurl 支持 SMTP、HTTP、HTTPS、FTP、TELNET 等协议和各种 SSL 安全认证,支持 Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS 等平台,在 Android 和 iOS 上面也可以使用 libcurl 这个库。

下面是官网的英文简介:

1
2
3
4
5
6
libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP.
libcurl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos), file transfer resume, http proxy tunneling and more!
libcurl is highly portable, it builds and works identically on numerous platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS and more...
libcurl is free, thread-safe, IPv6 compatible, feature rich, well supported, fast, thoroughly documented and is already used by many known, big and successful companies.

分享内容

今天跟大家分享 libcurl 在 iOS 上面如何使用,主要分享内容如下:

1、iOS 工程集成 libcurl以及集成注意事项。
2、利用 libcurl 发送 HTTP GET 和 POST 请求。
3、使用 springboot 搭建本地服务,这个只是为了演示不是分享的重点。

搭建本地服务

本地服务采用 Spring Boot 开发,开发语言是 Java,JDK 版本1.8,Spring Boot 版本是 v2.1.3.RELEASE,集成 Web 组件即可,比较简单。关于如何搭建 Spring Boot的开发环境,大家自行搜索解决,也可以直接使用我的 git 工程,猛戳前往 即可获取完整代码示例。

工程结构如下图所示:

关键代码如下:

该工程只是为了配合 libcurl 的使用而诞生的,没有什么难度。

集成 libcurl

1、新建 iOS 工程

这里工程为 tutorial_libcurl_iOS

2、准备库文件、头文件

libcurl 可以自己编译,也可以使用别人编译好的二进制文件。我使用的是 curl-android-ios 这个工程里面编译好的文件。

3、给工程 tutorial_libcurl_iOS 添加库和头文件

将上面的文件拷贝至工程目录即可,现在工程目录如下:

4、设置路径

在 xcode 中 Building Settings 找到 User Header Search Paths 为如下内容:

1
$(SRCROOT)/tutorial_libcurl_iOS/Classes

这一步不是必须的,我个人比较喜欢这样整理和设置目录。

5、添加 libz.tbd

如果不添加这个库,编译无法通过,会显示如下错误:

发送 HTTP 请求

下面说一下如何使用 libcurl 来发送 HTTP 的 GET 和 POST 请求。只给出核心示例代码,其余的大家去 tutorial_libcurl 获取完整示例代码,包括 Spring Boot 的。

ViewController.m

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#import "ViewController.h"
#import "curl/curl.h"
// 我本机的 IP 和端口,实际你要换成你自己的
#define HOST_URL @"http://172.20.10.2:8080/user"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)doHTTPGETToFileAction:(id)sender
{
NSString *reqUrl = [NSString stringWithFormat:@"%@%@", HOST_URL, @"?id=1&name=veryitman"];
const char *url = [reqUrl cStringUsingEncoding:NSUTF8StringEncoding];
http_get_req(url);
}
- (IBAction)doHTTPPOSTToFileAction:(id)sender
{
const char *url = [HOST_URL cStringUsingEncoding:NSUTF8StringEncoding];
const char *data = "id=2&name=veryitman";
http_post_req(url, data);
}
#pragma mark - C
void http_get_req(const char *url)
{
CURL *curl;
const char *fpath = rspDataPath(@"http_get_rsp_data.log");
FILE *fp;
fp = fopen(fpath, "wt+");
struct curl_slist *headers = NULL;
//增加HTTP header
headers = curl_slist_append(headers, "Accept:application/json");
headers = curl_slist_append(headers, "Content-Type:application/json");
headers = curl_slist_append(headers, "charset:utf-8");
//初始化
curl = curl_easy_init();
if (curl) {
//改协议头
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, url);
//wt+:读写打开或着建立一个文本文件;允许读写
if (NULL != fp) {
// 请求结果写入到文件当中
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
}
CURLcode rsp_code = curl_easy_perform(curl);
if (CURLE_OK == rsp_code) {
NSLog(@"请求返回成功");
} else {
NSLog(@"请求返回失败,返回码是 %i", rsp_code);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
fclose(fp);
}
void http_post_req(const char *url, const char *req_data)
{
const char *fpath = rspDataPath(@"http_post_rsp_data.log");
FILE *fp;
fp = fopen(fpath, "wt+");
CURL *curl;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
NSLog(@"length: %ld", strlen(req_data));
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(req_data) + 1);
/* pass in a pointer to the data - libcurl will not copy */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_data);
if (NULL != fp) {
// 请求结果写入到文件当中
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
}
CURLcode rsp_code = curl_easy_perform(curl);
if (CURLE_OK == rsp_code) {
NSLog(@"请求返回成功");
} else {
NSLog(@"请求返回失败,返回码是 %i", rsp_code);
}
curl_easy_cleanup(curl);
}
fclose(fp);
}
@end

启动 Spring Boot 项目,启动成功后,再运行 xcode 工程,可以测试。

点击对应的按钮就可以发送 GET 和 POST 请求了。

请求返回的结果被写入到了沙盒文件中,可以在终端使用 cat 命令查看对应的响应结果。

GET 响应结果:

1
cat ~/Library/Developer/CoreSimulator/Devices/BA882AC3-7977-49C7-8B0D-65EFD1541B68/data/Containers/Data/Application/3A21CFC5-3044-4FC0-9BFA-B311A59187AF/Documents/http_get_rsp_data.log
1
user info: id=2 name=veryitman

POST 响应结果:

1
cat ~/Library/Developer/CoreSimulator/Devices/BA882AC3-7977-49C7-8B0D-65EFD1541B68/data/Containers/Data/Application/86E7D457-97B1-4D8C-80D5-E8179B691F76/Documents/http_post_rsp_data.log
1
user info: id=2 name=veryitman

后续为大家分享如何使用回调来接收 HTTP 响应数据、其他网络请求的情况以及 Android 上面如何使用 libcurl 库。


扫码关注,期待与你的交流~

坚持原创技术分享!