I am trying to download a .ashx file from server from my ipad application.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *file = [NSString stringWithFormat:#"http://url/Script.ashx"];
NSURL *fileURL = [NSURL URLWithString:file];
NSURLRequest *req = [NSURLRequest requestWithURL:fileURL];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.fileData setLength:0];
// self.totalFileSize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.fileData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#", [dirArray objectAtIndex:0]);
NSString *path = [dirArray objectAtIndex:0];
NSString *dataPath = [path stringByAppendingPathComponent:#"Script.ashx"];
dataPath = [dataPath stringByStandardizingPath];
if ([self.fileData writeToFile:dataPath options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}
else {
NSLog(#"Written!");
}
}
Any error on the above code? please help.
Related
I use SSZipArchive. After downloading file I want to unzip archive and show image. But code doesn’t work. How to fix it?
download file
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [_session downloadTaskWithURL:_url1];
[_downloadTask1 resume];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
if (downloadTask == _downloadTask1) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSURL *documentsFolder = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *newLocation = [NSURL URLWithString:[NSString stringWithFormat:#"file://%#/2.zip", documentsFolder]];
NSError *error;
[fileManager copyItemAtURL:location toURL:newLocation error:&error];
NSLog(#"file%#", newLocation.absoluteString);
}
unzip file
_documentsDirectory1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_zipPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"2.zip"];
_destinationPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"file://%#/2.zip"];
_fileExists1 = [[NSFileManager defaultManager] fileExistsAtPath:_zipPath1 isDirectory:false];
if( [SSZipArchive unzipFileAtPath:_zipPath1 toDestination:_destinationPath1] != NO ) {
NSLog(#"Dilip Success");
}else{
NSLog(#"Dilip Error");
}
UPD
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [_session downloadTaskWithURL:_url1];
[_downloadTask1 resume];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
if (downloadTask == _downloadTask1) {
_documentsDirectory1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_zipPath1 = [_documentsDirectory1 stringByAppendingPathComponent:#"2.zip"];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (downloadTask == _downloadTask1) { NSData *urlData1 = [NSData dataWithContentsOfURL:_url1]; [urlData1 writeToFile:_zipPath1 atomically:YES];}
});
}
The problem is in saving zip file in DocumentDirectory, _filePath1 is contain the destination folder for unzip, instead of that you need to use filePath that contain zip file name along with path, so use that like this.
[urlData1 writeToFile:filePath atomically:YES];
Also it is batter if you use writeToFile:options:error: method so that you can know it is successfully writing Data or not.
NSError *error = nil;
[self.responseData writeToFile:zipPath options:0 error:&error];
Edit:
You are probably messing with something, so change your code from downloading to saving and unzipping like this.
-(IBAction) downloadButton:(id)sender
{
if (_HighScore == 2) {
_url1 =[NSURL URLWithString:#"link2.zip"];
_downloadTask1 = [session dataTaskWithURL:[NSURL URLWithString:#""] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//Saved in NSDocumentDirectory
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *zipPath = [path stringByAppendingPathComponent:#"2.zip"];
[self.responseData writeToFile:zipPath options:0 error:&error];
//UNZip
NSString *zipPath1 = [path stringByAppendingPathComponent:#"2.zip"];
NSString *destinationPath = [NSString stringWithFormat:#"%#",path];
[SSZipArchive unzipFileAtPath:zipPath1 toDestination:destinationPath];
//Now access the content of zip
}];
[_downloadTask1 resume];
}
}
try like this , its work for me
[SSZipArchive unzipFileAtPath:filePath toDestination:outputPath delegate:self];
after completion of unarchive the following method will call
#pragma mark - Unzipp Delegate
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo: (unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath {
//write code here after unarchive zip file
}
I am developing an iOS app. I download the text file from a URL and save it into a directory, but I can't find the file in the directory, so the code downloads it again. How do I check for the file?
if ([[NSFileManager defaultManager] fileExistsAtPath:localfile]) {
content = [NSString stringWithContentsOfFile:localfile
encoding:NSUTF8StringEncoding
error:NULL];
}else
{
NSURL* url = [NSURL URLWithString:#"http://webapp.opaxweb.net/books/gurugranthsahib.txt"];
NSArray* pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* documentsDir = [pathArray objectAtIndex:0];
localfile =[documentsDir stringByAppendingPathComponent:#"data"];
NSData* data = [NSData dataWithContentsOfURL:url];
[data writeToFile:localfile atomically:YES];
content = [NSString stringWithContentsOfFile:localfile
encoding:NSUTF8StringEncoding
error:NULL];
}
_textfield.text=content;
Your text data is quite big and hence you should use nsurl connection! Your code is totally correct but this is a better approach.
- (void)viewDidLoad
{
[super viewDidLoad];
self.fileName = #"Data";
self.fileData = [NSMutableData data];
[self checkFileExitsorNOt];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.fileData setLength:0];
self.totalFileSize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.fileData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#", [dirArray objectAtIndex:0]);
NSString *path = [NSString stringWithFormat:#"%#/%#", [dirArray objectAtIndex:0],self.fileName];
if ([self.fileData writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}
else {
NSLog(#"Written!");
}
}
-(void) checkFileExitsorNOt
{
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#", [dirArray objectAtIndex:0]);
NSString *path = [NSString stringWithFormat:#"%#/%#", [dirArray objectAtIndex:0],self.fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSString *cont = [NSString stringWithContentsOfFile:localfile
encoding:NSUTF8StringEncoding
error:NULL];
NSLog(#"Content from file : %#",cont);
}
else
{
NSString *file = [NSString stringWithFormat:#"http://webapp.opaxweb.net/books/gurugranthsahib.txt"];
NSURL *fileURL = [NSURL URLWithString:file];
NSURLRequest *req = [NSURLRequest requestWithURL:fileURL];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
}
}
I have a Login page in that when i press "login" button i have to call a webservice and load new view according to the response
it is taking 3 to 4 seconds i want to show activity indicator for loading view
how to show that
i'm using asynchronous NSURLConnection with NSURLConnection delegates
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[conn start];
in didFinishLoading
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *e = nil;
res = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&e];
//[indicator performSelectorOnMainThread:#selector(stopAnimating) withObject:nil waitUntilDone:YES];
NSLog(#"data is %#",res);
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"create.json"];
NSLog(#"file path is %# ",path);
NSFileManager *fileManager=[NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:path])
{
NSString *bundle = [[[NSBundle mainBundle]resourcePath]stringByAppendingString:#"create.json"];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
[res writeToFile:path atomically:YES];
how to show in this view
i stucked here
In your #interface, add:
#property (nonatomic, strong) UIActivityIndicatorView *ai;
When you start your connection, start your spinner:
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[conn start];
_ai = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_ai.frame = CGRectMake(0, 0, 24, 24); // adjust the frame to where you want the spinner to appear
[_ai startAnimating];
[self.view addSubview:_ai];
And when your connection completes, remove it:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[_ai stopAnimating];
[_ai removeFromSuperView];
... // all your other code
}
Make sure you remove it the same way in the connectionDidFailWithError: callback as well.
If you want something prettier, check out the github link #evnaz posted and use that instead of UIActivityIndicatorView with this same flow
I have an app that loops through an array of URLs and downloads all the files in that array (10 small txt files and 1 large image file). I had the app downloading the files ok before but due to a problem with the large image, I had to subclass NSURLConnection and I think I haven't quite got it right as no files are now being downloaded.
For each item of the array getFiles is passed a URL and run:
-(void)getFile:(NSString*)url tag:(NSString*)tag {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
FileURLConnection *connection = [[FileURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:tag];
if (connection) {
[receivedData setObject:[NSMutableData data] forKey:connection.tag];
}
}
Here are the NSURLConnection delegates:
-(NSMutableData*)dataForConnection:(FileURLConnection*)connection {
NSMutableData *data = [receivedData objectForKey:connection.tag];
return data;
}
- (void)connection:(FileURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
NSMutableData *dataForConnection = [self dataForConnection:(FileURLConnection*)connection];
[dataForConnection setLength:0];
}
- (void)connection:(FileURLConnection *)connection didReceiveData:(NSData *)data {
NSMutableData *dataForConnection = [self dataForConnection:(FileURLConnection*)connection];
[dataForConnection appendData:data];
}
- (NSCachedURLResponse *)connection:(FileURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
- (void)connectionDidFinishLoading:(FileURLConnection *)connection {
NSLog(#"connectionDidFinishLoading run");
NSMutableData *dataForConnection = [self dataForConnection:(FileURLConnection *)connection];
NSString *fileName = connection.tag;
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
[file seekToEndOfFile];
[file writeData:dataForConnection];
[file closeFile];
}
EDIT: If I NSLog the receivedData (NSDictionary) in getFile it updates the 'tag' object but no data to go with it:
"accomodation.txt" = <>;
"future-congress-dates.txt" = <>;
"general-file.txt" = <>;
...
I have also tried to NSLog the dataForConnection (NSMutableData) for each delegate but nothing ever gets printed:
NSLog(#"dataForConnection %#", dataForConnection);
Ok, I surrender.
There is full code:
FileURLConnection:
#interface FileURLConnection: NSURLConnection
#property (nonatomic, strong) NSFileHandle *file;
#end
getFile function:
-(void)getFile {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:fullURL]];
FileURLConnection *conn = [[FileURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
- (void)connection:(FileURLConnection*)connection didReceiveResponse:(NSURLResponse *)response {
NSString *fileName = [[response URL] lastPathComponent];
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
connection.file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
}
- (void)connection:(FileURLConnection *)connection didReceiveData:(NSData *)data {
[connection.file writeData:data];
}
- (NSCachedURLResponse *)connection:(FileURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
- (void)connectionDidFinishLoading:(FileURLConnection *)connection {
NSLog(#"Connection is %#", connection);
[connection.file closeFile];
}
- (void)connection:(FileURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"error - %#", error);
}
Original question: App crashing when downloading a large file - NSFileHandle seekToEndOfFile
I create one application that has one page. In that page there is one button, label & a progressview. What I want is starting a download when clicking on the button and show progress & label status download.
I can make progressview but I can not make a label that show download status.
For example, I want my label to show "12 MB downloaded of 100 MB"
This is my code:
view controller.h
#interface ViewController : UIViewController
{
float expectedBytes;
}
#property (weak,nonatomic) IBOutlet UIProgressView *progressView;
#property (strong,nonatomic) IBOutlet UIButton *download;
- (IBAction)download:(id)sender;
#end
view controller.m
#implementation ViewController
{
NSMutableData *receivedData;
NSString *currentURL;
NSString *name;
}
- (void)viewDidLoad
{
currentURL = #"http://192.168.1.100/mamal/Adele%20-%20Someone%20Like%20You%20(MTV%20Video%20Music%20Awards%202011)%20HD%20Live.mkv";
name = [currentURL lastPathComponent];
[super viewDidLoad];
}
#synthesize progressView,download;
-(IBAction)download:(id)sender
{
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:name];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
if (!fileExists)
{
[self downloadWithNsurlconnection];
}
else
{
NSLog(#"FILE EXIST");
}
}
-(void)downloadWithNsurlconnection
{
NSURL *url = [NSURL URLWithString:currentURL];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:600];
receivedData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
[connection start];
}
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
progressView.hidden = NO;
[receivedData setLength:0];
expectedBytes = [response expectedContentLength];
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
float progressive = (float)[receivedData length] / (float)expectedBytes;
[progressView setProgress:progressive];
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#",paths);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:name];
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[receivedData writeToFile:pdfPath atomically:YES];
}
Please guide me how show status download in UILabel with NSURLConnection.
put this syntax in .h file
#property (weak,nonatomic) IBOutlet UILabel *label;
then in .m file
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
float progressive = (float)[receivedData length] / (float)expectedBytes;
[progressView setProgress:progressive];
[lable setText:[NSString stringWithFormat:#"%u MB of %f MB",[receivedData length],expectedBytes]];
}
Create an Outlet for the label
#property (weak,nonatomic) IBOutlet UILabel *label;
then in
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
float progressive = (float)[receivedData length] / (float)expectedBytes;
[progressView setProgress:progressive];
[lable setText:[NSString stringWithFormat:#"%u MB of %f MB",[receivedData length],expectedBytes]];
}
you can change the bytes into MB