Can anyone please provide or show me how to download a PDF asynchronously if a local file doesnt exist.
My code is as follows:
NSURL *url = [NSURL URLWithString:#"http://www.url.com"];
NSString *tempDownloadPath = [[self documentsDirectory]
stringByAppendingString:#"test.pdf"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:[self documentsDirectory]];
[request setTemporaryFileDownloadPath:tempDownloadPath];
[request setDelegate:self];
[request startAsynchronous];
Once it is complete I try and call this
[aWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[self documentsDirectory] pathForResource:#"test" ofType:#"pdf"]isDirectory:NO]]];
however it either crashes or doesn't load anything inside my web view.
Any suggestions?
EDIT WITH SELF DOCUMENTSDIRECTORY
You need to put your file in some place accessible to the UIWebView and then point it there. You've not included how you're creating [self documentsDirectory] and you're just appending a string rather than using the path append for your temporary location. You're also not telling ASIHTTPRequest what actual file name to use for the final document, just the directory to put it in, so it's likely not even being saved. Additionally, the UIWebView load request is incorrect.
Here's how to create your path for telling ASIHTTPRequest where to put the file.
EDITED to change temporary file location to the NSCachesDirectory instead, so that it will be automatically cleared out if the download fails with partial data
// SAVED PDF PATH
// Get the Document directory
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your saved pdf location
NSString *pdfLocation = [documentDirectory stringByAppendingPathComponent:#"test.pdf"];
// TEMPORARY PDF PATH
// Get the Caches directory
NSString *cachesDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your temp pdf location
NSString *tempPdfLocation = [cachesDirectory stringByAppendingPathComponent:#"test.pdf"];
// Tell ASIHTTPRequest where to save things:
[request setTemporaryFileDownloadPath:tempPdfLocation];
[request setDownloadDestinationPath:pdfLocation];
Then when your delegate receives notification of the file download being complete, tell the UIWebView where to find the file, again using the proper methods.
// If you've stored documentDirectory or pdfLocation somewhere you won't need one or both of these lines
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *pdfLocation = [documentDirectory stringByAppendingPathComponent:#"test.pdf"];
// Now tell your UIWebView to load that file
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:pdfLocation]]];
I think the error is that you're downloading the file to the documents directory and then you're looking for the file in the main bundle. You should look for it in the documents directory.
Related
1) I want to download the data of any kind like the files of type .text, .png, .jpg, .docx, .xls, .pdf, .mp4, or whatever be the kind of files, Then i want to save it to the application sandboxs document directorys any of the sub directories that i have created under document directory of application sandbox.
2) Again whenever the user want to upload the files saved in the subdirectories of the application sandboxs document directory, The user will be able to browse through the data in the different directories of application sandboxs document directory, For that i have listed the data in the subdirectories of document directory of application sandbox in UITableView so that the user should be able to choose any of the file from the particular directory.
Problems/ things where i have stucked
I am using ASIHttpRequest for the upload and download , Where
1) For first need , means for downloading data i am using the methods -(void)grabURLInBackground to download the data from web and if its downloaded successfully then in the method -(void)requestFinished:(ASIHTTPRequest *)request i am saving that data to the subdirectory of the document directory of application sandbox with the particular name. The working code is below
-(void)grabURLInBackground
{
NSURL *url = [NSURL URLWithString:#"http://wordpress.org/plugins/about/readme.txt"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
-(void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSLog(#"responseString:%#",responseString);
UIAlertView *alt = [[UIAlertView alloc] initWithTitle:#"Download Status" message:#"Download finished" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alt show];
//Use when fetching binary data
//NSData *responseData = [request responseData];
//NSLog(#"responseData:%#",responseData);
//For storing the data to the subdirectory of the document directory named Doc the following code is used.
NSArray *paths;
NSString *documentsDirectory,*docDirectoryPath,*docFilePath;
//NSString *imageCachePath,*imageDicPath;
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSLog(#"documentsDirectory:%#",documentsDirectory);
docDirectoryPath = [documentsDirectory stringByAppendingPathComponent:#"/Docs"];
NSLog(#"docDirectoryPath:%#",docDirectoryPath);
docFilePath = [docDirectoryPath stringByAppendingPathComponent:#"textFileTwo"];
NSLog(#"docFilePath:%#",docFilePath);
if (![[NSFileManager defaultManager] fileExistsAtPath:docFilePath])
[[NSFileManager defaultManager] createFileAtPath:docFilePath
contents:[NSData dataWithContentsOfFile:responseString]
attributes:nil];
//************************************//
Here what i want after the download finishes we have the two option the way to fetch the text data and the way to fetch the binary data, Thats what is the thing , Here in my case the data will be of any kind, And i want to save that to particular directory, I will save it on my own but i want the Unique way to fetch the any kind of data and to save it to particular directory .
//************************************//
}
-(void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(#"error:%#",error);
}
2) For the 2nd need means for the uploading data to any URL m using the same ASIHttpRequest like
-(void)uploadData {
//Suppose i want to upload the file that i have juz downloaded by the download code above.
// i fetched the path of the file i just saved with download code above, See the code below.
NSArray *paths;
NSString *documentsDirectory,*docDirectoryPath,*docFilePath;
//NSString *imageCachePath,*imageDicPath;
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSLog(#"documentsDirectory:%#",documentsDirectory);
docDirectoryPath = [documentsDirectory stringByAppendingPathComponent:#"/Docs"];
NSLog(#"docDirectoryPath:%#",docDirectoryPath);
docFilePath = [docDirectoryPath stringByAppendingPathComponent:#"textFileTwo"];
NSLog(#"docFilePath:%#",docFilePath);
// Upload Code
NSString *strURL = #"http://192.168.1.201/MyLegalNetMobile/MyLegalNetService.svc/FileUpload";
ASIFormDataRequest *uploadRequest = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:strURL]]; // Upload a file on disk
// Upload image data using asihttprequest
//UIImage *tempImg=[UIImage imageWithContentsOfFile:[NSString stringWithContentsOfURL:[NSURL URLWithString:imageCachePath] encoding:NSUTF8StringEncoding error:nil]];
//NSData *imageData1=UIImageJPEGRepresentation(tempImg, 1.0);
NSString *fetchedDataOfTxtFiles = [NSString stringWithContentsOfURL:[NSURL URLWithString:docFilePath] encoding:NSUTF8StringEncoding error:nil];
NSData *textData = [NSData dataWithContentsOfFile:fetchedDataOfTxtFiles];
NSLog(#"fetchedDataOfTxtFiles:%#",fetchedDataOfTxtFiles);
NSLog(#"textData:%#",textData);
[uploadRequest setData:textData withFileName:#"textFileTrialThree" andContentType:#"txt" forKey:#"txtData"];
[uploadRequest setRequestMethod:#"POST"];
[uploadRequest setDelegate:self];
[uploadRequest setTimeOutSeconds:10.0];
uploadRequest.shouldAttemptPersistentConnection = NO;
[uploadRequest setDidFinishSelector:#selector(uploadRequestFinished:)];
[uploadRequest setDidFailSelector:#selector(uploadRequestFailed:)];
[uploadRequest startAsynchronous];
//************************************//
Here again i have the different ways to upload the different kind of data, like for uploading the text data, different, ways is there same for the pdf, and image data is also, here i want the unique way to upload any kind of data to server, Also here I tried the image data uploading and text data uploading , Means i uploaded the files that i download from the any url. At the time of saving that downloaded files i converted them to NSData and saved to particular path of application sandboxs belonging directories. So while uploading again i got that path and for image data i converted the nsdata to uiimage , for the text file i only gave the path of file and uploaded the fiels to somewhere , The Files get uploaded on server, but there size was 0 bytes only, and the formate was different.
//************************************//
}
-(void)uploadRequestFinished:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
NSLog(#"Upload response %#", responseString);
}
-(void)uploadRequestFailed:(ASIHTTPRequest *)request{
NSLog(#" Error - Statistics file upload failed: \"%#\"",[[request error] localizedDescription]);
}
// Exact Problem.
/*
Any data that we download from the web using ASIHttpRequest before saving it to any path to application sandbox we convert some kind of data to NSData, And it get saved .
On the click of Browse button i have populated the data from different different subdirectories of the Document directory of the application sandbox in the UITableView, So I want to show the names of files with their extensions means with type that files were downloaded [as we save all data with converting to NSData it get saved with the names we give while saving only].
And then the time comes for the users to upload that data to any of the URL at that time also the files should get stored with their original formates means with which we downloaded the, */
To get list of files in directory try
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error
To get file extension take a look on responce headers. They can contain ContentType which was downloaded.
why not use the request property called downloadDestinationPath?? If you use it, you don´t need to do anything in RequestFinished method because the ASIHTTPRequest library keeps the type of the files what you have downloaded.
The request finished method is always for doing something with the data you have downloaded, as parsing an html file for remove the html headers. If you don´t want to modify the file that you are downloading you should use this method for show download status only.
Edit the download path before start the request:
NSArray *paths;
NSString *documentsDirectory,*docDirectoryPath,*docFilePath;
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
docDirectoryPath = [documentsDirectory stringByAppendingPathComponent:#"Docs"];// Remove the "/" from the string paths because you are using "stringByAppendingPathComponent"
docFilePath = [docDirectoryPath stringByAppendingPathComponent:#"textFileTwo"];
request = [ASIHTTPRequest requestWithURL:YOUR URL];
[request setDownloadDestinationPath:docFilePath];
[request startAsynchronous];
To list the content:
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error2];
for (int i = 0; i<[directoryContent count]; i++){
NSLog(#"content == %d", [directoryContent objectAtIndex:i];
}
I am using the following lines of code to download and save an html page ::
NSURL *goo = [[NSURL alloc] initWithString:#"http://www.google.com"];
NSData *data = [[NSData alloc] initWithContentsOfURL:goo];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //Remove the autorelease if using ARC
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSLog(#"%#", documentsDirectory);
NSString *htmlFilePath = [documentsDirectory stringByAppendingPathComponent:#"file.html"];
[html writeToFile:htmlFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
After downloading and saving it, I need to re-use it i.e. upload it. But, I am unable to download the css and image files alongwith the html page i.e. while re-uploading it .. I am not getting the images that should have been displayed on the google home page ..
Can someone help me sort out the issue ?? Thanks and Regards.
The data that is being downloaded is just what the web server returns - pure html. If you need the resources from inside - images/sounds/flash/css/javascripts/etc.. you have parse this html and download all other resources.. Your html may also contain the full path of those resources so you may need to change their urls to be relative (if you want to display it offline or upload it to another server). Parsing can be done with regular expressions or some other 3rd party parsers or libraries that can download the whole web page...
You may take a look at ASIWebPageRequest, which claims to be able to download a whole website, but I haven't tried this functionality...
Use of ASIWebPageRequest will solve problem :
- (void)downloadHtml:(NSURL *)url
{
// Assume request is a property of our controller
// First, we'll cancel any in-progress page load
[[self request] setDelegate:nil];
[[self request] cancel];
[self setRequest:[ASIWebPageRequest requestWithURL:url]];
[[self request] setDelegate:self];
[[self request] setDidFailSelector:#selector(webPageFetchFailed:)];
[[self request] setDidFinishSelector:#selector(webPageFetchSucceeded:)];
// Tell the request to embed external resources directly in the page
[[self request] setUrlReplacementMode:ASIReplaceExternalResourcesWithData];
// It is strongly recommended you use a download cache with ASIWebPageRequest
// When using a cache, external resources are automatically stored in the cache
// and can be pulled from the cache on subsequent page loads
[[self request] setDownloadCache:[ASIDownloadCache sharedCache]];
// Ask the download cache for a place to store the cached data
// This is the most efficient way for an ASIWebPageRequest to store a web page
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[[self request] setDownloadDestinationPath:documentsDirectory] // downloaded path
//[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:[self request]]]; use this instead of documentsDirectory if u want to cache the page
[[self request] startAsynchronous];
}
//These are delegates methods:
- (void)webPageFetchFailed:(ASIHTTPRequest *)theRequest
{
// Obviously you should handle the error properly...
NSLog(#"%#",[theRequest error]);
}
- (void)webPageFetchSucceeded:(ASIHTTPRequest *)theRequest
{
NSString *response = [NSString stringWithContentsOfFile:
[theRequest downloadDestinationPath] encoding:[theRequest responseEncoding] error:nil];
// Note we're setting the baseURL to the url of the page we downloaded. This is important!
[webView loadHTMLString:response baseURL:[request url]];
}
- (void)viewDidLoad {
/// js=yourHtmlSring;
NSString *js; (.h)
[self.myWebView loadHTMLString:js baseURL:nil];
}
//delegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[myWebView stringByEvaluatingJavaScriptFromString:js];
}`
Hey I don't think you can download all the files from google just try with any other url . And you can directly write the NSData to your file htmlFilePath.
[data writeToFile:htmlFilePath atomically:YES];
iPhone App
I am currently trying to understand how i can store a file from a URL to the documents directory and then read the file from the documents directory..
NSURL *url = [NSURL URLWithString:#"http://some.website.com/file"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSString *applicationDocumentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:#"Timetable.ics"];
[data writeToFile:storePath atomically:TRUE];
I got this code from http://swatiardeshna.blogspot.com/2010/06/how-to-save-file-to-iphone-documents.html
I want to know if this is the correct way to do this and i want to know how i can load the file from the documents directory into an NSString..
Any help will be greatly appreciated.
What you have looks correct, to read that file back into a string use:
EDIT: (changed usedEncoding to encoding)
NSError *error = nil;
NSString *fileContents = [NSString stringWithContentsOfFile:storePath encoding:NSUTF8StringEncoding error:&error];
Of course you should change the string encoding type if you are using a specific encoding type, but UTF8 is likely correct.
If you're doing this on your main thread, then no it's not correct. Any sort of network connection should be done in the background so you don't lock up the interface. For that, you can create a new thread (NSThread, performSelectorInBackground:, NSOperation+NSOperationQueue) or schedule it on the run loop (NSURLConnection).
can anyone tell how to add html in my iphone project??
And their is no html option which i click on add new file in class group...why is that???
simply create a blank file and rename it to html or add existing html file to the project.
the next step depends on how you wish to use the html file.
Say if you want to load a local file called page.html, first you add the file to project,and in the build phases of your project, and the page.html to Copy Bundle Resources, and run this in your app, it writes the file to the documents dictionary of your app/
NSString *Html = [[NSString alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"page" ofType:#"html"] encoding:NSUTF8StringEncoding error:NULL];
[Html writeToFile:[[self docPath]stringByAppendingPathComponent:#"page.html"] atomically:YES encoding:NSUTF8StringEncoding error:NULL];
[Html release];
and your webview should call this to load the file:
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [docPaths objectAtIndex:0];
[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[docPath stringByAppendingPathComponent:#"page.html"]]]];
and it's done.
What you might be looking for is documentation and example code for the UIWebView class of UIKit.
You can use UIWebView to show your html file like this
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
[webView loadRequest:request];
where URLString contains is your file url.
How do I get an NSArray of the NAMES of all files stored in a specific directory such as: "http://www.someurl/somedirectory/"?
That's really something that has to be generated server-side, then parsed on the device. I know Apache has an option where you can turn on Directory Indexes, so you could do that, then download the generated directory index and parse the HTML (using an NSXMLParser or some other parsing library), adding an NSString to an NSMutableArray every time you find a file name.
Should be something along these lines..
NSURL* url = [NSURL URLWithString: #"http://address.tld/path/files.txt"];
NSString* data = [NSString stringWithContentsOfURL: url];
if(data)
{
NSArray* files = [data componentsSeparatedByString: #"\n"];
for(NSString* filename in files)
{
NSLog(#"%#", filename);
}
}