简体   繁体   English

了解更新 UIprogressView 的下载进度

[英]Know the download progress for update an UIprogressView

my app downloads a video from internet and saves it in the iPhone.我的应用程序从 Internet 下载视频并将其保存在 iPhone 中。

I'm using this code我正在使用此代码

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");}
}

All works fine, but I want to add a progress View, to indicate the status of the download.一切正常,但我想添加一个进度视图,以指示下载状态。

The problem (I think but I'm not sure) is that my NSURLConnection hasn't itself as delegate, so methods like问题(我认为但我不确定)是我的 NSURLConnection 本身并没有作为委托,所以像这样的方法

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

or或者

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

are never called.永远不会被调用。

I tried to use我试着用

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

but the app crashes when I try to write the file但是当我尝试写入文件时应用程序崩溃

[urlData writeToFile:filePath atomically:NO];

What can I do?我能做些什么? Thanks谢谢

What you are doing is sending a "synchronous" request, meaning that the thread that is downloading the HTTP response will hang until all data has been fetched.您正在做的是发送“同步”请求,这意味着正在下载 HTTP 响应的线程将挂起,直到获取所有数据。 It is never good to do this on a UI thread, even when you do not want display any indicator of the download's progress.在 UI 线程上执行此操作绝不是好事,即使您不想显示任何下载进度指示器。 I suggest using the NSURLConnection class, setting it's delegate, and responding to delegate methods.我建议使用 NSURLConnection class,设置它的委托,并响应委托方法。 A small tutorial for this can be found at http://snippets.aktagon.com/snippets/350-How-to-make-asynchronous-HTTP-requests-with-NSURLConnection .可以在http://snippets.aktagon.com/snippets/350-How-to-make-asynchronous-HTTP-requests-with-NSURLConnection找到一个小教程。

Once you are a connection's delegate, you can get the content length when the connection receives a response:一旦您成为连接的委托人,您就可以在连接收到响应时获取内容长度:

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

Then, to calculate the total progress of the download whenever new data arrives, do something like this:然后,要计算新数据到达时的下载总进度,请执行以下操作:

- (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:更新:

Another example on how to do async HTTP with Foundation: http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/关于如何使用 Foundation 进行异步 HTTP 的另一个示例: http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/

You are using synchronous request here.您在这里使用同步请求。

The document says - A synchronous load is built on top of the asynchronous loading code made available by the class.该文档说 -同步加载建立在 class 提供的异步加载代码之上。 The calling thread is blocked while the asynchronous loading system performs the URL load on a thread spawned specifically for this load request.当异步加载系统在专门为此加载请求生成的线程上执行 URL 加载时,调用线程被阻塞。 No special threading or run loop configuration is necessary in the calling thread in order to perform a synchronous load.为了执行同步加载,调用线程中不需要特殊的线程或运行循环配置。

Refer the class reference here请参阅此处的 class 参考

After you have read the class reference, you can either send asynchronous request or initialize the request, set delegate, and start.阅读 class 参考后,您可以发送异步请求或初始化请求、设置委托并启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM