Подтвердить что ты не робот

Как интегрировать NSURLConnection с UIProgressView?

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

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

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

- (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​​b > хранит данные файла во время загрузки. Переменная члена filesize содержит полный размер файла, возвращенный моей веб-службой в заголовок Content-Length.

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

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

Для справки, progressView.progress - это float. fileize - это NSNumber, который длится долго. Наконец, resourceLength является NSNumber, в котором содержится NSUInteger.

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

4b9b3361

Ответ 1

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

#define NSURLResponseUnknownLength ((long long)-1)

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

и

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

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

filesize: 4687472

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

NSURLResponseUnknownLength

i.e, сервер не вернул размер файла.