Download / retrieve pdf with asihttprequest - ios

I'm trying to download content with an URL to a local file system in my iPad (cachedDir ? )
with this function:
- (IBAction)download:(id)sender {
NSURL *url = [NSURL URLWithString:#"http:www.google.de"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
[request setDownloadDestinationPath:#"/Users/ben/Desktop/my_file.pdf"]; // Which //directory??
}
Which directory do I have to choose for my path if I want to store the data as long as possible without getting rejected by Apple,
and how do I retrieve the data I've saved?
Can somebody help?

The best place to store documents that you want to keep around is your application's Documents directly. You can find the path to it like so:
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
Apple have a useful piece of documentation about the iOS file system and where to store particular types of files: http://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html

Try out this my code for save pdf in document using below code
NSString *downloadUrl=[NSURL URLWithString:#"http:www.google.de"];
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:downloadUrl]];
//Store the Data locally as PDF File
NSString *resourceDocPath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:#"Documents"]];
NSString *pdf1 = #"title.pdf";
NSString *filePath = [resourceDocPath stringByAppendingPathComponent:pdf1];
[pdfData writeToFile:filePath atomically:YES];
and retrive your file using
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSURL *pdfURL = [[NSBundle bundleWithPath:[paths objectAtIndex:0]] URLForResource:[NSString stringWithFormat:#"title.pdf"] withExtension:nil];
NSLog(#"pDF URl %#", pdfURL);
pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);

Related

Objective-C create mapped file for PDF

I am creating a file like so:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,PDFFile];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] createFileAtPath:filePath contents:dataBytes attributes:nil];
}
_previewItemURL = [NSURL fileURLWithPath:filePath];
and I am displaying it in an UIDocumentInteractionController like so:
if (_previewItemURL) {
UIDocumentInteractionController *documentInteractionController =[UIDocumentInteractionController interactionControllerWithURL:_previewItemURL];
documentInteractionController.delegate = self;
[documentInteractionController presentPreviewAnimated:YES];
}
However, sometimes the PDF file I am saving off bytes are way too big, sometimes 5.5MB, which causes UIDocumentInteractionController to some time to load the PDF. I was doing some reading here https://stackoverflow.com/a/27863508/979331 and it is suggested to create a 'mapped' file. My question is I don't understand how to create one. I have been googling like crazy for the past two days and I just don't understand it.
I think the issue is with the PDF because I tried this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pgnPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.pdf", #"example"]];
//filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,PDFFile];
//if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSString *newFile = [[NSBundle mainBundle] pathForResource:#"example" ofType:#"pdf"];
[[NSFileManager defaultManager] copyItemAtPath:newFile toPath:pgnPath error:&error];
//[[NSFileManager defaultManager] createFileAtPath:filePath contents:dataBytes attributes:nil];
//}
//_previewItemURL = [[NSBundle mainBundle] URLForResource:#"example" withExtension:#"pdf"];
_previewItemURL = [NSURL fileURLWithPath:pgnPath];
with a PDF that was 5.5MB and everything seemed fine, could the issue be with how I getting the PDF? I am getting the bytes from a web service, here is my call:
task = [dataSource.areaData GetPDFFileTestTwo:[NSString stringWithFormat:#"%#",encodedUrlStr] completion:^(NSData *data, NSURLResponse *response, NSError *error) {
NSError *myError;
NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
NSData *dataBytes;
for (NSDictionary *dict in tableArray) {
NSString *base64 = dict[#"data"];
dataBytes = [[NSData alloc] initWithBase64EncodedString:base64 options:0];
}
if (dataBytes) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,PDFFile];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] createFileAtPath:filePath contents:dataBytes attributes:nil];
}
_previewItemURL = [NSURL fileURLWithPath:filePath];
if (_previewItemURL) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIDocumentInteractionController *documentInteractionController =[UIDocumentInteractionController interactionControllerWithURL:_previewItemURL];
documentInteractionController.delegate = self;
dispatch_async(dispatch_get_main_queue(), ^{
[documentInteractionController presentPreviewAnimated:YES];
});
});
}
}
}];
And here is GetPDFFileTestTwo
-(NSURLSessionDataTask *)GetPDFFileTestTwo:(NSString *)PDFFile completion:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler{
NSString *FileBrowserRequestString = [NSString stringWithFormat:#"%#?PDFFile=%#",kIP,PDFFile];
NSURL *JSONURL = [NSURL URLWithString:FileBrowserRequestString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if(completionHandler)
{
completionHandler(data, response, error);
}
}];
[dataTask resume];
return dataTask;
}
kIP is a string and that is the web service URL
You're not "creating" a mapped file. You're reading it into NSData as mapped to the bytes in the file. That means, that in-memory NSData bytes are underneath mapped to bytes in the file.
Here is a way to read a file as mapped:
https://github.com/atomicbird/atomictools/blob/master/NSData%2BreallyMapped.h
If you can't pass NSData to the controller for preview, mapping makes no sense. Even if you can, you have to be sure that controller won't copy your data before it is used.
Consider using PDFKit framework, where you can initialize PDFDocument with NSData and display it in PDFView.
Your questions;
create a 'mapped' file. My question is I don't understand how to
create one.
So let me point out that UIDocumentInteractionController has no inputs that accept NSData, so you wouldn't be able to create a memory mapped file to use with it. I also examined the header for any other clues, and didn't find any.
https://developer.apple.com/documentation/uikit/uidocumentinteractioncontroller
In looking for a solution, I saw that QLPreviewController mentions 'data' but I find it didn't accept NSData either.
https://developer.apple.com/documentation/quicklook/qlpreviewcontroller
I finally settled on WKWebView in WebKit, which does support using NSData, that is Memory Mapped, and loads quite quickly with a 15 MB PDF full of pictures and text I made.
I created a project with the large PDF and tried it out, it works fine. Please feel free to examine it.
https://github.com/eSpecialized/PDFDocViewerMapped
How 'mapped' works;
Anything that can take NSData can use a mapped file unless it needs the entire set of data at once. A PDF with a single image vs a multipage PDF are good examples of what can't be mapped and what can be mapped.
NSError *errors;
NSData *docFileData = [NSData dataWithContentsOfFile:docFileWithPath options:NSDataReadingMappedAlways error:&errors];
Options for NSData mapped;
https://developer.apple.com/documentation/foundation/nsdatareadingoptions?language=objc
NSDataReadingMappedIfSafe // Hint to map the file in if possible and safe
NSDataReadingMappedAlways // Hint to map the file in if possible. This takes precedence over NSDataReadingMappedIfSafe if both are given.
could the issue be with how I getting the PDF?
Fetching a PDF remotely means you must download the document.
Think of what you are doing, fetching the Pdf, saving it locally, then opening it in the UIDocument Interaction controller which takes URL's and not NSData.
I hope this meets your criteria for a solution;
UIDocumentInteractionController limitations with requiring URL's
WKWebView - allows using NSData that can be memory mapped.
3rd party options for PDF viewing - anything that can accept NSData is a
candidate for use. Look for CocoaPods and on GitHub for PDF, iOS PDF,
etc.

iOS: Download and save PDF file in Documents app

I want to download a PDF file then open it in a webView. I searched about that then I found this issu. The accepted answer describes how to download and display the file. When I test it, I can not find the file in the Documents because it's stored inside my app. Also I don't think that the file is saved because the pdf is never shown in the webView even if I pass the filePath to be loaded. This is the code of the answer:
// Get the PDF Data from the url in a NSData Object
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[
NSURL URLWithString:#"http://www.example.com/info.pdf"]];
// Store the Data locally as PDF File
NSString *resourceDocPath = [[NSString alloc] initWithString:[
[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"
]];
NSString *filePath = [resourceDocPath
stringByAppendingPathComponent:#"myPDF.pdf"];
[pdfData writeToFile:filePath atomically:YES];
// Now create Request for the file that was saved in your documents folder
NSURL *url = [NSURL fileURLWithPath:filePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView setUserInteractionEnabled:YES];
[webView setDelegate:self];
[webView loadRequest:requestObj];
And this is what I see in the log:
libMobileGestalt MobileGestaltSupport.m:153: pid 2828 (my_app) does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled
2017-08-01 10:29:06.882562+0100 my_app[2828:1334057] libMobileGestalt MobileGestalt.c:550: no access to InverseDeviceID (see <rdar://problem/11744455>)
What is the problem with what I did? And how can I put the downloaded file in the Documents app of my iPhone in order to be checked whenever the user want like any other PDF?
Sandbox path Error
NSString *resourceDocPath = [[NSString alloc] initWithString:[
[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"
]];
Please use your sandbox path instead of bundle path.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

How To Down and store the Text File on Local Cache

I am developing an IOS app..Download data From URL and save on local cache..but i am using this code..first time data can stored in Local cache and also read on the text field..but Delete the app on simulator and run the and again store the text file on local cache..file can't be store..Any help or advice is greatly appreciated. thanks in advance.
NSURL *url = [NSURL URLWithString:#"http://webapp.opaxweb.net/books/"];
NSData *data_file = [[NSData alloc]initWithContentsOfURL:url];
NSString *resourceDocPath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent]stringByAppendingPathComponent:#"Documents"]];
NSString *filepath = [resourceDocPath stringByAppendingPathComponent:#"gurugranthsahib.txt"];
[data_file writeToFile:filepath atomically:YES];
NSLog(#"%#",filepath);
NSString* content = [NSString stringWithContentsOfFile:filepath
encoding:NSUTF8StringEncoding
error:NULL];
iOS does not allow writing to the app bundle.
Generally data is written to the Documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
Note:
It is much better practice to use a method call that has an error parameter so when there is an error the error can be examined. In this case you could use:
NSError *error;
BOOL status = [string writeToFile:filePath options:NSDataWritingAtomic error:&error];
if (status == NO) {
NSLog(#"error: %#", error)
}

store internally a PDF from internet and display into WebView

I'm developing an app for iOS 8.1 using Xcode 6.1.1
And I want to download a PDF from internet, store in to my iPad and then load it into a webview; this is the PDF test:
this is the result I get on iPad after trying to display it on my WebView:
this is my code so far...
// Get the PDF Data from the url in a NSData Object
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.ferc.gov/docs-filing/elibrary/larg-file.pdf"]];
// Store the Data locally as PDF File
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolderPath = searchPaths[0];
NSString *archivePath = [documentFolderPath stringByAppendingPathComponent:#"larg-file.pdf"];
[pdfData writeToFile:archivePath atomically:YES];
// Now create Request for the file that was saved in your documents folder
NSURL *url = [NSURL fileURLWithPath:archivePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView setUserInteractionEnabled:YES];
[_webView setDelegate:self];
[_webView loadRequest:requestObj];
How do I make this work?
EDIT: this is the answer
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolderPath = searchPaths[0];
NSString *archivePath = [documentFolderPath stringByAppendingPathComponent:#"larg-file.pdf"];
if (![Functions isAlreadyStoredinDeviceFileWithName:#"larg-file.pdf"]) {
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.ferc.gov/docs-filing/elibrary/larg-file.pdf"]];
[pdfData writeToFile:archivePath atomically:YES];
}
// Now create Request for the file that was saved in your documents folder
NSURL *url = [NSURL fileURLWithPath:archivePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView setUserInteractionEnabled:YES];
[_webView setDelegate:self];
[_webView loadRequest:requestObj];
This code:
NSString *resourceDocPath = [[NSString alloc] initWithString:[
[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
Attempts to formulate a directory within the application bundle. You do not have write access to the application bundle. Your file therefore isn't saved.
Check out -[NSFileManager URLsForDirectory:inDomains:] or NSSearchPathForDirectoriesInDomains for how to get the path to the user's documents folder.

Download a file from a specific link and store it in device iOS?

I am currently working on a iOS application in which I show a download link to download a Excel sheet. I want to save that downloaded file to a location of my iOS device where all my downloaded applications are stored by default, so that I can access it later form my device without opening the application.
Like in android devices, files are stored in my files from where we can access them later on.
Is there any approach to achieve this in iOS.
You can store directly on Document Directory as below
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"tempfile"]]; // It may change according to your need
NSError * error = nil;
[imageData writeToFile:path options:NSDataWritingAtomic error:&error];
Here ,imageData is my data to be write on Document directory
And by saving on Document Directory you can get it from there
NSString * str = "Your Url"
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:str]
cachePolicy:NSURLCacheStorageAllowed
timeoutInterval:20];
NSURLResponse *response;
NSError *error;
NSData * data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
[data writeToFile:filePath atomically:YES];
You can try with it for once
// NSData downloads any file from an URL
NSURL* url = [NSURL URLWithString:#"http://192.168.0.8/PoweredByMacOSX.gif"];
NSData* data = [NSData dataWithContentsOfURL:url];
// get the documents directory
NSArray* pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* documentsDir = documentsDirectory = [pathArray objectAtIndex:0];
NSString* localFile =
[documentsDir stringByAppendingPathComponent:#"webfile.png"];
// write the downloaded file to documents dir
[data writeToFile:localFile atomically:YES];

Resources