NSMutableData Save to a File - iphone

I downloaed the file using code shown below. Then i am trying to save NSMutableData variable to file, however, the file is not created. What am i doing wrong? Do i need to convert NSMutableData into NSString?
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)_response {
response = [_response retain];
if([response expectedContentLength] < 1) {
data = [[NSMutableData alloc] init];
}
else {
data = [[NSMutableData dataWithCapacity:[response expectedContentLength]] retain];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)_data {
[data appendData:_data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"txt"];
NSLog(#"saved: %#", filePath);
[data writeToFile:filePath atomically:YES];
NSLog(#"downloaded file: %#", data); //all i see in log is some encoded data here
}

You can’t write inside your app’s bundle. You’ll need to save it somewhere else, like your app’s Documents directory:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"file.txt"];
[data writeToFile:filePath atomically:YES];

Related

Download file from URL and place it in Resource folder in iPhone

I am new to iPhone developer,
How can i download the epub file from url and store it in Resource folder ?
Here is my code snippet,
- (void)viewDidLoad
{
[super viewDidLoad];
fileData = [NSMutableData data];
NSString *file = [NSString stringWithFormat:#"http://www.google.co.in/url?sa=t&rct=j&q=sample%20epub%20filetype%3Aepub&source=web&cd=2&ved=0CFMQFjAB&url=http%3A%2F%2Fdl.dropbox.com%2Fu%2F1177388%2Fflagship_july_4_2010_flying_island_press.epub&ei=i5gHUIOWJI3RrQeGro3YAg&usg=AFQjCNFPKsV-tieF4vKv7BXYmS-QEvd7Uw"];
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];
}
- (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]];
if ([self.fileData writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}
else {
NSLog(#"Written!");
}
}
I am not able to see anything in my NSLog.
There is a problem in creation of file path also while writing. you have not specified any filename in the path. In the below line, I have used file name as "filename.txt". Give some proper name and it will write.
NSString *path = [NSString stringWithFormat:#"%#/filename.txt", [dirArray objectAtIndex:0]];
There is a problem in creating URL also. Do it like this,
NSString *file = [NSString stringWithString:#"http://www.google.co.in/url?sa=t&rct=j&q=sample%20epub%20filetype%3Aepub&source=web&cd=2&ved=0CFMQFjAB&url=http%3A%2F%2Fdl.dropbox.com%2Fu%2F1177388%2Fflagship_july_4_2010_flying_island_press.epub&ei=i5gHUIOWJI3RrQeGro3YAg&usg=AFQjCNFPKsV-tieF4vKv7BXYmS-QEvd7Uw"];
NSURL *fileURL = [NSURL URLWithString:file];
You have created your file data with below line.
fileData = [NSMutableData data];
Make it like below,
fileData = [[NSMutableData alloc]init];
OR
self.fileData = [NSMutableData data];
Here iOS releases filedata before your connection delegate get called.

How to save downloaded data to device's filesystem

I'm downloading pdf documents from the server:
- (void)downloadSingleDocument:(NSURL *)url
{
[pdfData release];
pdfData = [[NSMutableData alloc] init];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req addValue:#"Basic **************=" forHTTPHeaderField:#"Authorization"];
downloadConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
NSLog(#"Connection did receive data");
[pdfData appendData:data];
}
On connectionDidFinishLoading I want to save downloaded pdf file to filesystem in Documents directory with the same filename as it was on the server.
What is the best way to do it?
Use this methods if you have large file:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
{
filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name];
[[NSFileManager defaultManager] createFileAtPath:filepath contents:nil attributes:nil];
file = [[NSFileHandle fileHandleForUpdatingAtPath:filepath] retain];// Here file is object of NSFileHandle and its declare in .h File
[file seekToEndOfFile];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[file seekToEndOfFile];
[file writeData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
[file closeFile];
// After you download your data. you can copy your data from here to filesystem. and remove from here
}
Use NSURLDownload.
Sorry, that is only available on the Mac, not for iOS.
Create a temporary file, and append the received data to it in connection:didReceiveData:. In connectionDidFinishLoading:, move the file to the correct place, and in connection:didFailWithError:, remove the temporary file.
This should do it
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSString *filename = [con.originalRequest.URL lastPathComponent];
NSString *path = [documentsDirectory stringByAppendingString:filename];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:path contents:pdfData attributes:nil];
}

Copy XML file from Server to iphone?

I want to copy the xml file from server to save it to locally, because if I will send request to server again and again, it will take time, so I want to copy the xml to local resources whenever app starts, then parse the local xml,
how can I do it?
First of all you need to download the file:
NSURL *url = [NSURL URLWithString:FILEURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
then add in the h file:
NSMutableData *receivedData;
and in the m file:
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (receivedData)
{
[receivedData appendData:data];
}
else
{
receivedData = [[NSMutableData alloc] initWithData:data];
}
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
//saving your data in the local
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullName = [NSString stringWithFormat:#"xmlfile.xml"];
NSString *fullFilePath = [NSString stringWithFormat:#"%#/%#",docDir,fullName];
[receivedData writeToFile:fullFilePath atomically:YES];
}
edit:
get the file from local-
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullName = [NSString stringWithFormat:#"xmlfile.xml"];
NSString *fullFilePath = [NSString stringWithFormat:#"%#/%#",docDir,fullName];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
now you can take the NSData when parse it,there are a lot of examples in the site.

NSurlconncetion received data length always 0 but file saving works

Hi i want to show the received bytes in the console.
(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[receivedData length]];
NSLog(#"resourceData length: %d ", [resourceLength intValue]);
if (file) {
[file seekToEndOfFile];
}
[file writeData:data];
}
the file successfully downloads and safed it into docoument dir but the nslog show always
resourceData length: 0
receivedata is NSMutableData *receivedData; in the .h file
the strange thing is that the exceptedbytes work well. here the code for that:
- (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse)response {
localFilename = [[[url2 absoluteString] lastPathComponent] copy];
NSLog(localFilename);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0] ;
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:localFilename];
[[NSFileManager defaultManager] createFileAtPath:appFile contents:nil attributes:nil];
expectedBytes = [response expectedContentLength];
NSLog(#"content-length: %lli Bytes", expectedBytes);
file = [[NSFileHandle fileHandleForUpdatingAtPath:appFile] retain];
if (file) {
[file seekToEndOfFile];
}
}
can somebody help me. i really dont know what i am doing wrong
kind regards
tammo
Have you allocated and initialised receivedData? One usually does
receivedData = [[NSMutableData data] retain];
right after creating an NSURLConnection instance, and then
[receivedData setLength:0];
upon receiving a response via -connection:didReceiveResponse:, and
[receivedData appendData:data];
upon receiving data via -connection:didReceiveData:. This is exemplified in the URL Loading System Programming Guide. If you haven’t instantiated receivedData, it is probably nil and [receivedData length] returns 0 in that case.

How to download a large file with the iPhone SDK and avoid memory usage issues?

I'm using the NSURLConnection class to download a large file in my iPhone application, but it crashes every so often because it's using too much memory. I'm doing the usual NSURLConnection usage, to append the received data to a NSMutableData object.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.fileData appendData:data];
}
Then after I finish downloading the whole file, I save it to a local temporary file, and read it as a mapped file like this:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// save the downloaded data into a temporary file
NSString *tempPath = NSTemporaryDirectory();
NSString *tempFile = [tempPath stringByAppendingPathComponent:#"temp.pdf"];
[self.fileData writeToFile:tempFile atomically:YES];
NSData *mappedData = [NSData dataWithContentsOfMappedFile:tempFile];
NSURL *baseURL = [NSURL URLWithString:#"http://mydomain.com"];
[webView loadData:mappedData MIMEType:#"application/pdf" textEncodingName:#"UTF-8" baseURL:baseURL];
}
What can I improve here to avoid these memory usage problems?
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response {
filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name]; // filename is in .h file
[[NSFileManager defaultManager] createFileAtPath:filename contents:nil attributes:nil];
file =
[[NSFileHandle fileHandleForUpdatingAtPath:filename] retain];// file is in .h
//if (file) {
//
// [file seekToEndOfFile];
// }
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSD
ata *)data {
if (file) {
[file seekToEndOfFile];
} [file writeData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
[file closeFile];
}
If it's that large, why not write it to the file as it comes in, rather than keeping it in an NSData object?
i'm using
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name];
NSFileHandle *file1 = [NSFileHandle fileHandleForUpdatingAtPath: filename];
[file1 writeData: data];
[file1 closeFile];
}