views:

539

answers:

1

I've been fooling around with code for ages on this one, I would be very grateful if someone could provide a code sample that downloaded this file from a server http://www.archive.org/download/june_high/june_high_512kb.mp4, (By the way it's not actually this file, it's just a perfect example for anyone trying to help me) and then play it from the documents directory. I know it seems lazy of me to ask this but I have tried so many different variations of NSURLConnection that it's driving me crazy. Also, if I did manage to get the video file downloaded would I be correct in assuming this code would then successfully play it:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"june_high_512kb.mp4"]; 
NSURL *movieURL = [NSURL fileURLWithPath:path]; 
self.theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[_theMovie play];

If the above code would work in playing a video file from the document directory, then I guess the only thing I would need to know is, how to download a video file from a server. Which is what seems to be my major problem. Any help is greatly appreciated.

+2  A: 

Your code will work to play a movie file.

The simplest way to download is synchronously:

NSData *data = [NSData dataWithContentsOfURL:movieUrl];
[data writeToURL:movieUrl atomically:YES];

But it is better (for app responsiveness, etc) to download asynchronously:

    NSURLRequest *theRequest = [NSURLRequest requestWithURL:movieUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
    receivedData = [[NSMutableData alloc] initWithLength:0];
        NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];

This requires implementing the informal NSURLConnection protocol:

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [receivedData setLength:0];
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [receivedData appendData:data];
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [connection release];
}

- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
    return nil;
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [connection release];
    [self movieReceived];
}

and then saving (and playing) the movie file in the movieReceived method.

Paul Lynch
Thanks, Good Answer, really helped me a lot. I made a minor change to your code though, instead of appendData I use writeData, as the app bombs out with appendData when downloading large files. But still excellent code example.
Jessica
Yes, my (simple) example will consume more memory than using NSFileHandle/writeData: will, which will make a difference for large files. Glad it helped.
Paul Lynch