Как интегрировать 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]);
}
Как вы можете видеть, переменная-член resourceDatab > хранит данные файла во время загрузки. Переменная члена filesize содержит полный размер файла, возвращенный моей веб-службой в заголовок Content-Length.
Все работает нормально, я продолжаю получать загруженные данные с несколькими версиями didReceiveDatab > , как и следовало бы, но когда я пытаюсь вычислить значение прогресса, правильное значение не возвращается. Ниже приведен небольшой пример того, что я получаю в своем журнале консоли:
content-length: 4687472 bytes
resourceData length: 2904616
filesize: 4687472
float filesize: -1.000000
progress: -2904616.000000
Для справки, progressView.progress - это float. fileize - это NSNumber, который длится долго. Наконец, resourceLength является NSNumber, в котором содержится NSUInteger.
Что мне здесь не хватает?
Ответы
Ответ 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, сервер не вернул размер файла.