В Xcode установите стек функций curl_easy_setopt для загрузки файла на сервер / API, и (после многих проб и ошибок) все это работает как чудо. После прохождения нескольких других Q&Поскольку мне также удалось настроить простой 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), например. для моего NSProgressIndicator; CURL захватывает мое приложение и не позволяет вводить / выводить данные до тех пор, пока процесс не будет завершен.
Я попытался обновить IBOutlets из my_progress_func (например, [_myLabel setStringValue: globalProgressNumber];), но статическая функция int не позволяет этого.
[Self] также не разрешено, поэтому публикация в NSNotificationCenter невозможна:
[[NSNotificationCenter defaultCenter]
postNotificationName:@"Progressing"object:self];
Моя функция curl запускается из моего основного класса / окна (NSPanel).
Любой хороший совет о том, как получить элемент реального времени / обновления на моем .xib?
CURL […] не разрешает какой-либо другой ввод / вывод, пока процесс не будет завершен.
Ты звонишь curl_easy_perform
из основного потока? Если да, вам не следует этого делать, поскольку эта функция является синхронной, то есть блокируется до завершения передачи.
Другими словами, долго выполняющиеся задачи (например, с сетевым вводом / выводом) должны выполняться в отдельном потоке, в то время как код пользовательского интерфейса (например, обновление текста метки) должен выполняться в основном потоке.
как достичь элемента реального времени / обновления
Обязательно позаботьтесь о том, чтобы выполнить перенос локонов в отдельном потоке.
Это может быть легко достигнуто, оборачивая это в NSOperation
с пользовательским протоколом для уведомления делегата о прогрессе (например, ваш контроллер представления):
NSOperationQueue
,CURLOPT_PROGRESSDATA
скручиваемость Таким образом, каждый раз, когда вызывается функция прогресса, вы можете получить объект операции, приведя void *clientp
непрозрачный указатель. Затем уведомите делегата о текущем прогрессе в основной теме (например, с performSelectorOnMainThread
), чтобы убедиться, что вы можете выполнять обновления пользовательского интерфейса, такие как обновление вашего NSProgressIndicator
,В качестве альтернативы NSOperation
Вы также можете использовать Grand Central Dispatch (GCD) и блоки. Если возможно, я настоятельно рекомендую вам работать с BBHTTP который является клиентом libcurl для iOS 5+ и OSX 10.7+ (BBHTTP использует GCD и блоки).
К вашему сведению: вот пример из BBHTTP это иллюстрирует, как легко выполнить загрузку файла с блоком выполнения загрузки — это для iOS, но должно быть непосредственно повторно использовано для OS X.
Других решений пока нет …