используя данные о прогрессе libcurl

В 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?

0

Решение

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.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector