2013-04-15 5 views
1

В настоящее время я работаю над приложением Cocoa, которое работает с PDF-файлами, и я использую PDFKit от Apple для выполнения этой работы. Сохранение PDF-файла является проблемой, так как я хочу показать индикатор выполнения, пока это происходит, что кажется невозможным с использованием стандартного метода writeToURL:. Итак, я пошел и использовал Grand Central Dispatch вместо этого.PDFDocument dataRepresentation медленный ... Как показать прогресс?

Проблема в том, что метод dataRepresentation, используемый для получения NSData для записи, очень медленный в преобразовании любого PDF-файла, большего чем ~ 3 МБ в NSData, и поэтому индикатор выполнения останавливается на несколько секунд, пока моя программа ждет данные, которые, похоже, заставляют пользователей думать, что программа полностью застопорилась. И я не хочу, чтобы они думали об этом.

Мой вопрос: есть ли что-нибудь, что я могу сделать, чтобы ускорить метод dataRepresentation или сообщить о его прогрессе для пользователя?

Вот код Grand Central Dispatch я в конечном итоге написание:

NSData *pdf = [doc dataRepresentation]; // R-e-a-l-l-y S-l-o-w 

dispatch_queue_t queue = dispatch_get_current_queue(); 
dispatch_data_t dat = dispatch_data_create([pdf bytes], [pdf length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT); 

__block dispatch_io_t channel = 
dispatch_io_create_with_path(DISPATCH_IO_STREAM, 
          [path UTF8String],  // Convert to C-string 
          O_WRONLY,    // Open for writing 
          0,      // No extra flags 
          queue, 
          ^(int error){ 
           // Cleanup code for normal channel operation. 
           // Assumes that dispatch_io_close was called elsewhere. 
           if (error == 0) { 
            dispatch_release(channel); 
            channel = NULL; 
           } 
          }); 
// The next two lines make sure that the block in dispatch_io_write 
// gets called about 60 times, so that it can update the progress bar. 
dispatch_io_set_low_water(channel,[pdf length]/60); 
dispatch_io_set_high_water(channel,[pdf length]/60); 

dispatch_io_write(channel, 
        0, 
        dat, 
        queue, 
        ^(bool done, dispatch_data_t data, int error) { 
         if (data) { 
          // Increment progress bar 
         } 
         if (error) { 
          // Handle errors 
         } 
         if (done) { 
          dispatch_io_close(channel, NULL); 
         } 
        }); 
dispatch_release(dat); 
dispatch_release(queue); 

ответ

2

Используйте эти PDFDocumentDidBeginPageWriteNotification and PDFDocumentDidEndPageWriteNotification уведомления, отправляемые во время -writeToURL:. Уведомления сообщают вам, какая страница обрабатывает, что вы можете сравнить с общим количеством страниц в документе, чтобы показать прогресс.

+0

Должен был подумать о поиске уведомления ... Спасибо! –