Как интегрировать NSURLConnection с UIProgressView? - PullRequest
24 голосов
/ 23 ноября 2008

Я пытаюсь интегрировать объект NSURLConnection с UIProgressView, чтобы я мог обновить пользователя, пока загрузка файла происходит в фоновом режиме.

Я создал отдельный объект для загрузки файла в фоновом режиме, и у меня возникают проблемы с выяснением, как обновить свойство progress в объекте UIProgressView с правильным значением. Возможно, это что-то очень простое, но я не могу понять это с помощью Google.

Вот код, который у меня есть:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [self.resourceData setLength:0];
    self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
    NSLog(@"content-length: %d bytes", self.filesize);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.resourceData appendData:data];

    NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
    NSLog(@"resourceData length: %d", [resourceLength intValue]);
    NSLog(@"filesize: %d", self.filesize);
    NSLog(@"float filesize: %f", [self.filesize floatValue]);
    progressView.progress = [resourceLength floatValue] / [self.filesize floatValue];
    NSLog(@"progress: %f", [resourceLength floatValue] / [self.filesize floatValue]);
}

Как видите, переменная-член resourceData хранит данные файла во время его загрузки. Переменная filesize содержит полный размер файла, который был возвращен моим веб-сервисом в заголовке Content-Length.

Все работает вроде нормально, я продолжаю получать загруженные данные с несколькими выполнениями didReceiveData , как и должен, но когда я пытаюсь вычислить значение прогресса, правильное значение не возвращается. Ниже приведен небольшой пример того, что я получаю в журнале консоли:

content-length: 4687472 bytes
resourceData length: 2904616
filesize: 4687472
float filesize: -1.000000
progress: -2904616.000000

Для справки, progressView.progress - это число с плавающей точкой. размер файла - это NSNumber, который содержит long long. Наконец, resourceLength - это NSNumber, содержащий NSUInteger.

Что мне здесь не хватает?

Ответы [ 3 ]

29 голосов
/ 23 ноября 2008

Не уверен, что мне здесь не хватает, но ваша filesize, равная -1, кажется, ваша проблема. В API-документах четко указано, что expectedContentLength может быть недоступно и в этих случаях возвращается NSURLResponseUnknownLength. NSURLResponseUnknownLength определяется как:

#define NSURLResponseUnknownLength ((long long)-1)

В этих случаях вы не можете получить точный прогресс. Вам нужно будет обработать это и отобразить какой-то неопределенный индикатор прогресса.

6 голосов
/ 24 ноября 2008

Я думаю, что вы печатаете неправильный размер файла. Если self.filesize действительно NSNumber, вы печатаете его в формате %@, потому что это объект, а не примитив:

NSLog(@"filesize: %@", self.filesize);

Используя %d, вы просто печатаете указатель значение self.filesize. Чтобы распечатать фактическое длинное длинное значение, используйте %lli (%d только для 32-битных значений):

NSLog(@"filesize: %lli", [self.filesize longLongValue]);

Таким образом, ваш self.filesize равен на самом деле -1, и деление правильное.

0 голосов
/ 25 июля 2010

В вашем коде размер файла выглядит как объект NSNumber (!). Так

NSLog(@"filesize: %d", self.filesize);

и

NSLog(@"content-length: %d bytes", self.filesize);

скорее всего сообщит что-то вроде адреса (идентификатора) этого объекта (или что-то еще). Это

filesize: 4687472

вы видите. Как указывалось другими, размер файла, возвращаемого ответом, действительно равен -1, т.е.

NSURLResponseUnknownLength

То есть сервер не вернул размер файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...