Знать ход загрузки для обновления UIprogressView - PullRequest
2 голосов
/ 21 июля 2011

мое приложение загружает видео из Интернета и сохраняет его на iPhone.

Я использую этот код

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];

[request setHTTPMethod:@"GET"];
NSError *error;
NSURLResponse *response;


NSString *documentFolderPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *videosFolderPath = [documentFolderPath stringByAppendingPathComponent:@"videos"]; 

//Check if the videos folder already exists, if not, create it!!!
BOOL isDir;
if (([fileManager fileExistsAtPath:videosFolderPath isDirectory:&isDir] && isDir) == FALSE) {
    [[NSFileManager defaultManager] createDirectoryAtPath:videosFolderPath withIntermediateDirectories:YES attributes:nil error:nil];
}

NSString *filePath = [videosFolderPath stringByAppendingPathComponent:@"name.mp4"];

if ([fileManager fileExistsAtPath:filePath ] == YES) {
    NSLog (@"File exists");
}
else {
    NSLog (@"File not found");
    NSData *urlData;
    NSString *downloadPath = @"http://www.mywebsite.com/name.mp4";
    [request setURL:[NSURL URLWithString:downloadPath]];
    urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    BOOL written = [urlData writeToFile:filePath atomically:NO];
    if (written)
        NSLog(@"Saved to file: %@", filePath);
    else {NSLog(@"problem");}
}

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

Проблема (я думаю, но я не уверен) состоит в том, что мой NSURLConnection сам по себе не является делегатом, поэтому такие методы, как

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data 

или

-(void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite{

никогда не вызывается.

Я пытался использовать

urlData = [[NSURLConnection alloc] initWithRequest:request delegate:self];

, но приложение вылетает при попытке записать файл

[urlData writeToFile:filePath atomically:NO];

Что я могу сделать?Спасибо

Ответы [ 2 ]

5 голосов
/ 21 июля 2011

То, что вы делаете, отправляет «синхронный» запрос, то есть поток, который загружает HTTP-ответ, будет зависать до тех пор, пока не будут получены все данные. Это никогда не полезно делать в потоке пользовательского интерфейса, даже если вы не хотите отображать какой-либо индикатор прогресса загрузки. Я предлагаю использовать класс NSURLConnection, установить его делегат и отвечать на методы делегата. Небольшое руководство по этому вопросу можно найти по адресу http://snippets.aktagon.com/snippets/350-How-to-make-asynchronous-HTTP-requests-with-NSURLConnection.

Когда вы являетесь делегатом соединения, вы можете получить длину контента, когда соединение получает ответ:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;   
    contentSize = [httpResponse expectedContentLength];
}

Затем, чтобы рассчитать общий прогресс загрузки при поступлении новых данных, выполните что-то вроде этого:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // download data is our global NSMutableData object that contains the
    // fetched HTTP data.
    [downloadData appendData:data];
    float progress = (float)[downloadData length] / (float)contentSize;
    [progressView setValue:progress];
}

UPDATE:

Еще один пример выполнения асинхронного HTTP с помощью Foundation: http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/

1 голос
/ 21 июля 2011

Здесь вы используете синхронный запрос.

В документе говорится - Синхронная загрузка создается поверх кода асинхронной загрузки, предоставленного классом.Вызывающий поток блокируется, пока асинхронная система загрузки выполняет загрузку URL-адреса для потока, созданного специально для этого запроса загрузки.Для выполнения синхронной загрузки в вызывающем потоке не требуется никакой специальной конфигурации потоков или цикла выполнения.

См. Ссылку на класс здесь

После того, как выпрочитав ссылку на класс, вы можете отправить асинхронный запрос или инициализировать запрос, установить делегат и запустить.

...