当前位置: 首页 > news >正文

iOS用libcurl发起一个get请求,并保存返回数据到沙盒

这个需求分为: 1.如何接入libcurl库, 2.如何用libcurl发起get请求, 3.如何将数据保存到沙盒路径下

一.第一个需求,由于libcurl只有源码,需要你自己去编译各平台下的库,怎么编译参考下我写的另一篇文章:编译支持iOS的libcurl+OpenSSL库(支持https IPv6)
然后就是引用libcurl.a库了,记得在build phase里面的link binary with ibraries 里面引用libz.tbdlibresolv.tbd这两个系统库

二.第二个需求,发起请求的方法如下

bool getUrl(const char *filename,char *url)
{
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "wt+")) == NULL){
        // 返回结果用文件存储
        return false;
    }
    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_WRITEDATA, fp);
        res = curl_easy_perform(curl);   // 执行
        NSLog(@"请求返回值是%i",res);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    fclose(fp);
    return true;
}
复制代码

特别提醒, curl_global_init(CURL_GLOBAL_ALL);这个函数是全局初始化函数,只能调用一次,所以最好在didFinishLanuch里面调用,如果在curl_easy_init();之前还未实现,那么libcurl会自动执行一次。所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。 这是因为虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,didFinishLanuch里调用一次就行了。

三. 如何上层调用 由于curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 这个方法是c的方法,所以传进来的目录filename也要是c String才行,所以上层调用的时候得这么写:

NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths firstObject];
NSString *filePath = [documentPath stringByAppendingPathComponent:@"wow.log"];
getUrl([filePath cStringUsingEncoding:NSUTF8StringEncoding],"https://www.baidu.com");
复制代码

这样就可以将获取到数据写入到应用的document目录下,保存为wow.log文件。

四. 对请求的返回值的说明 也就是对 curl_easy_perform()函数返回值的说明,0表示请求正常返回,详情看下面

CURLE_OK = 0, 0: no error 
CURLE_UNSUPPORTED_PROTOCOL, 1: unsupported protocol 
CURLE_FAILED_INIT, 2: failed init 
CURLE_URL_MALFORMAT, 3: URL using bad/illegal format or missing URL 
CURLE_URL_MALFORMAT_USER, 4: unknown error 
CURLE_COULDNT_RESOLVE_PROXY, 5: couldn't resolve proxy name 
CURLE_COULDNT_RESOLVE_HOST, 6: couldn't resolve host name 
CURLE_COULDNT_CONNECT, 7: couldn't connect to server 
CURLE_FTP_WEIRD_SERVER_REPLY, 8: FTP: weird server reply 
CURLE_FTP_ACCESS_DENIED, 
CURLE_FTP_USER_PASSWORD_INCORRECT, 10: unknown error 
CURLE_FTP_WEIRD_PASS_REPLY, 11: FTP: unknown PASS reply 
CURLE_FTP_WEIRD_USER_REPLY, 12: FTP: unknown USER reply 
CURLE_FTP_WEIRD_PASV_REPLY, 13: FTP: unknown PASV reply 
CURLE_FTP_WEIRD_227_FORMAT, 14: FTP: unknown 227 response format 
CURLE_FTP_CANT_GET_HOST, 15: FTP: can't figure out the host in the PASV response 
CURLE_FTP_CANT_RECONNECT, 16: FTP: can't connect to server the response code is unknown 
CURLE_FTP_COULDNT_SET_BINARY, 17: FTP: couldn't set binary mode 
CURLE_PARTIAL_FILE, 18: Transferred a partial file 
CURLE_FTP_COULDNT_RETR_FILE, 19: FTP: couldn't retrieve (RETR failed) the specified file 
CURLE_FTP_WRITE_ERROR, 20: FTP: the post-transfer acknowledge response was not OK 
CURLE_FTP_QUOTE_ERROR, 21: FTP: a quote command returned error 
CURLE_HTTP_RETURNED_ERROR, 22: HTTP response code said error 
CURLE_WRITE_ERROR, 23: failed writing received data to disk/application 
CURLE_MALFORMAT_USER, 24: unknown error 
CURLE_UPLOAD_FAILED, 25: upload failed (at start/before it took off) 
CURLE_READ_ERROR, 26: failed to open/read local data from file/application 
CURLE_OUT_OF_MEMORY, 27: out of memory 

CURLE_OPERATION_TIMEOUTED, 28: a timeout was reached 
CURLE_FTP_COULDNT_SET_ASCII, 29: FTP could not set ASCII mode (TYPE A) 
CURLE_FTP_PORT_FAILED, 30: FTP command PORT failed 
CURLE_FTP_COULDNT_USE_REST, 31: FTP command REST failed 
CURLE_FTP_COULDNT_GET_SIZE, 32: FTP command SIZE failed 
CURLE_HTTP_RANGE_ERROR, 33: a range was requested but the server did not deliver it 
CURLE_HTTP_POST_ERROR, 34: internal problem setting up the POST 
CURLE_SSL_CONNECT_ERROR, 35: SSL connect error 
CURLE_BAD_DOWNLOAD_RESUME, 36: couldn't resume download 
CURLE_FILE_COULDNT_READ_FILE, 37: couldn't read a file:// file 
CURLE_LDAP_CANNOT_BIND, 38: LDAP: cannot bind 
CURLE_LDAP_SEARCH_FAILED, 39: LDAP: search failed 
CURLE_LIBRARY_NOT_FOUND, 40: a required shared library was not found
复制代码

五. 单纯地写一个请求 如果你不需要写入本地,只是想发起请求,当然也是可以的,简化上面的代码,结果如下

CURLcode getUrl(char *url)
{
    CURL *curl;
    CURLcode res = CURLE_OK;
    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);
        res = curl_easy_perform(curl);   // 执行
        NSLog(@"res===%i",res);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    return res;
}
复制代码

调用的话就用getUrl("https://www.baidu.com");
打完收工

转载于:https://juejin.im/post/5a405f156fb9a0451b04c5bd

相关文章:

  • Maven系列--安装与部署(Win7)
  • 主键自增设置
  • $L^p$ 调和函数恒为零
  • python3基础(七)函数基础
  • php的命名空间
  • java Web相关零碎整理--厚积薄发
  • Hibernate执行原生SQL返回ListMap类型结果集
  • Android编译过程详解(一)
  • 【bootstrap】modal模态框的几种打开方法+问题集锦
  • denyhost防止SSH暴力破解
  • [国家集训队2012]middle
  • Design Pattern: Prototype 模式
  • Linux环境下shell和vim中乱码原因及消除办法
  • 利用Docker轻松玩转Cassandra
  • 搭建高可用mongodb集群(三)—— 深入副本集内部机制
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Angular6错误 Service: No provider for Renderer2
  • css属性的继承、初识值、计算值、当前值、应用值
  • hadoop集群管理系统搭建规划说明
  • Java深入 - 深入理解Java集合
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • PHP CLI应用的调试原理
  • Python爬虫--- 1.3 BS4库的解析器
  • Python学习之路16-使用API
  • React Native移动开发实战-3-实现页面间的数据传递
  • SpingCloudBus整合RabbitMQ
  • 深度解析利用ES6进行Promise封装总结
  • 算法系列——算法入门之递归分而治之思想的实现
  • 跳前端坑前,先看看这个!!
  • 译自由幺半群
  • 源码安装memcached和php memcache扩展
  • 做一名精致的JavaScripter 01:JavaScript简介
  • Prometheus VS InfluxDB
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (六)vue-router+UI组件库
  • (十一)手动添加用户和文件的特殊权限
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转)JAVA中的堆栈
  • (转)ObjectiveC 深浅拷贝学习
  • ***利用Ms05002溢出找“肉鸡
  • ***详解账号泄露:全球约1亿用户已泄露
  • ../depcomp: line 571: exec: g++: not found
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net 反编译_.net反编译的相关问题
  • .net的socket示例
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .Net语言中的StringBuilder:入门到精通
  • 。Net下Windows服务程序开发疑惑
  • /bin/rm: 参数列表过长"的解决办法
  • @font-face 用字体画图标