使用libcurl进度数据
making use of libcurl progress data
在Xcode中设置一堆curl_easy_setopt函数用于上传文件到服务器/API,并且(经过大量的试验和错误)它都像魅力一样工作。在经历了其他几个问题之后,我也设法设置了一个简单的CURLOPT_PROGRESSFUNCTION,看起来像这样:
static int my_progress_func(void *p,
double t,
double d,
double ultotal,
double ulnow)
{
printf("(%g %%)n", ulnow*100.0/ultotal);
// globalProgressNumber = ulnow*100.0/ultotal;
return 0;
}
随着上传的进行"0%.. "16% . .58% . .100%"是输出到控制台;灿烂的。我不能做的是实际使用这个数据(globalProgressNumber) eg。for我的NSProgressIndicator;CURL劫持了我的应用程序,不允许任何其他输入/输出,直到进度完成。
我尝试从my_progress_func更新IBOutlets(例如。[_myLabel setStringValue:globalProgressNumber];),但静态int函数不允许这样做。也不允许[self],所以发送到NSNotificationCenter是不可能的:[[NSNotificationCenter defaultCenter]
postNotificationName:@"Progressing"
object:self];
我的curl函数从我的主类/window (NSPanel)运行。
关于如何在我的。xib上实现实时/更新元素有什么好的建议吗?
旋度[…在进度完成之前,不允许任何其他输入/输出。
你是从主线程调用curl_easy_perform
吗?如果是,你不应该这样做,因为这个函数是同步的,也就是说,它会阻塞直到传输完成。
换句话说,长时间运行的任务(例如网络I/O)必须在单独的线程上运行,而UI代码(例如更新标签的文本)必须在主线程上运行。
如何实现实时/更新元素
你一定要注意在一个单独的线程中执行curl传输。
这可以很容易地实现,通过包装到一个自定义协议的NSOperation
通知进度委托(例如你的视图控制器):
- 将您的操作推入
NSOperationQueue
, - 操作队列将注意分离传输并将其运行到另一个线程中,
- 在操作端,您仍然应该使用进度函数,并通过
CURLOPT_PROGRESSDATA
curl选项将操作对象设置为不透明对象。这样,每次调用progress函数时,都可以通过强制转换void *clientp
不透明指针来检索操作对象。然后通知委托当前进程在主线程(例如performSelectorOnMainThread
),以确保您可以执行UI更新,如刷新您的NSProgressIndicator
。
作为NSOperation
的替代方案,您还可以使用大中央调度(GCD)和块。如果可能的话,我强烈建议你使用BBHTTP,这是一个ios5 +和OSX 10.7+的libcurl客户端(BBHTTP使用GCD和块)。
供参考:这里有一个来自BBHTTP的例子,说明了如何使用上载进度块轻松执行文件上传-这是针对iOS的,但应该可以直接用于OS x。
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- libCURL:上传数据崩溃(Qt,SMTP)
- 如何用libcurl定义元数据
- 如何发布数据,包括使用libcurl(用于InfuxDB)的线路中断
- libcurl错误失败的写作已接收到磁盘/应用程序的数据
- 创建一个 C++ 类以使用 libcurl 将数据从网站读取到字符串
- libCurl FTP 身份验证数据包未发送
- 使用libcurl发布数据
- libCurl 上传数据不活动超时不起作用
- 使用libcurl进度数据
- Libcurl HTTP post发送数据到服务器
- 在c++应用程序中使用libcurl从. ini文件中的值发送POST数据
- libcurl发送格式错误的数据
- XML格式的数据与libcurl
- Libcurl将数据写入数组
- 使用libcurl c++将响应数据存储到post上的变量中