Saving and viewing files in iOS - ios

I'm getting base64-encoded file content from server. Then I'm writing data into file. I checked that file is not empty after that, it means data was successfully written to file. But when I'm trying to present this file, all I get is an empty view. So what am I doin' wrong?
enter image description here
[f getFile:^(NSString * _Nonnull string) {
NSString *docsDir;
NSArray *dirPaths;
NSData *content = [string dataUsingEncoding:NSUTF8StringEncoding];
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"hill.jpg"]];
[content writeToFile:databasePath atomically:YES];
if ([[NSFileManager defaultManager] fileExistsAtPath:databasePath]){
NSURL *url = [NSURL fileURLWithPath:databasePath];
UIDocumentInteractionController *documentInteractionController =[UIDocumentInteractionController interactionControllerWithURL:url];
documentInteractionController.delegate = self;
[documentInteractionController presentPreviewAnimated:YES];
}
} Error:^(NSString * _Nonnull errorMessage) {
}];

Edited your code snippet, Try it
[f getFile:^(NSString * _Nonnull string) {
NSString *docsDir;
NSArray *dirPaths;
NSData *content = [[NSData alloc] initWithBase64EncodedString: string options:0];
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"hill.jpg"]];
[content writeToFile:databasePath atomically:YES];
if ([[NSFileManager defaultManager] fileExistsAtPath:databasePath]){
NSURL *url = [NSURL fileURLWithPath:databasePath];
UIDocumentInteractionController *documentInteractionController =[UIDocumentInteractionController interactionControllerWithURL:url];
documentInteractionController.delegate = self;
[documentInteractionController presentPreviewAnimated:YES];
}
} Error:^(NSString * _Nonnull errorMessage) {
}];

From your code, I see you save a string into a an image file (hill.jpg). The UIDocumentInteractionController read file base on their extension, so they can't read this file. I think if you change your file name to hill.txt, your code could work. Hope this helps.

As you say, the content gets from the server are base64-encode, so you need to decode it.
NSData *imageContent = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions];
if (imageContent) {
// save to file
}

Related

How come writeToFile does not write over original file?

I am saving a file like this in my iOS App in my UIImagePickerDelegate's method didFinishPIckingMediaWithInfo:
// write
NSString* filePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"Documents/invoice.jpeg"]];
NSData *imageData = UIImageJPEGRepresentation(info[UIImagePickerControllerOriginalImage], 0.0);
if (imageData != nil) {
[imageData writeToFile:filePath atomically:YES];
}
Then I am retrieving the file like this:
// load
NSString *searchFilename = #"invoice.jpeg";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:documentsDirectory];
NSString *documentsSubpath;
while (documentsSubpath = [direnum nextObject])
{
if (![documentsSubpath.lastPathComponent isEqual:searchFilename]) {
continue;
}
NSURL *fileURL = [[NSURL alloc]initFileURLWithPath:[NSString stringWithFormat:#"%#/%#",documentsDirectory,documentsSubpath]];
[self.imageContentView setupImageViewerWithImageURL:fileURL onOpen:^{
NSLog(#"open %#",fileURL);
} onClose:^{
NSLog(#"close %#",fileURL);
}];
}
The files do get loaded properly. However, when I update the photo (imageData) in my UIImagePickerDelegate and try to reload the image, I still get the original image written into my app documents.

Saving many pdf locally on device and retrieving it on click

NSURL *url = [NSURL URLWithString:#"PDFLINK"];
// Get the PDF Data from the url in a NSData Object
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:url];
NSString * name = #"First";
// Store the Data locally as PDF File
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *newFilePath = [documentsDirectory stringByAppendingPathComponent:#"my.pdf"];
NSError *error;
if ([fileManager createFileAtPath:newFilePath contents:pdfData attributes:nil])
{
NSLog(#"Create Sucess");
[self loadPDF];
}
else
{
NSLog(#"Create error: %#", error);
}
}
-(void)loadPDF
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSArray *resultArray = [fileManager subpathsOfDirectoryAtPath:documentsDirectory error:nil];
if (![resultArray containsObject:arrObj])
{
// do something
}
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[resultArray objectAtIndex:0]];
// Now create Request for the file that was saved in your documents folder
//NSLog(#"The filePath %#",filePath);
NSURL *url = [NSURL fileURLWithPath:filePath];
NSLog(#"The url %#",url);
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView setUserInteractionEnabled:YES];
[_webView setDelegate:self];
[_webView loadRequest:requestObj];
}
Here is my code.I have more 10 pdf and want to store them locally on device and display next time without download.
It saves the pdf again and i cannot check whether it is downloaded or not ?
Please help me
I am not sure what you mean but, to download a file , you need to use NSData:
NSString *stringURL = #"your file URL";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"filename.extension"];
[urlData writeToFile:filePath atomically:YES];
}
Now the downloaded file exists at filePath and you can get it by using:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"filename with extension"];
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
you can try this to check if file exists at file path:
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* file = [documentsPath stringByAppendingPathComponent:#"filename"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:file];
if(fileExists){
//dont download, just grab it and display it
}
else{
//download and display it
}

ios - cannot decrypt after encryption

I'm having troubles decrypting pdf files and displaying them with presentViewController after they are encrypted.
When I download the pdf files, they are being encrypted like this:
NSData *pdfData = [[NSFileManager defaultManager] contentsAtPath:filePathDocumetFolder];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documents = [paths objectAtIndex:0];
NSString *docFolder = [NSString stringWithFormat:#"/Documents/%#", documentFilePath];
NSString *filePath = [documents stringByAppendingPathComponent:docFolder];
NSString *pdfName = [NSString stringWithString:filename ];
NSError *error;
NSData *encryptedPdf = [RNEncryptor encryptData:pdfData withSettings:kRNCryptorAES256Settings password:#"A_SECRET_PASSWORD" error:&error];
if(error){
NSLog(#"error: %#", error);
}
NSLog(#"where?? FileTra%#", filePath);
[encryptedPdf writeToFile:[filePath stringByAppendingPathComponent:pdfName] atomically:YES];
I know that this encryption above works, as when I browse the filesystem with iExplorer, I cannot open the files because they are protected.
In my DocumentHandle controller I'm trying to decrypt them so that they can be viewed:
NSDictionary* dict = [command.arguments objectAtIndex:0];
NSString* urlStr = dict[#"url"];
NSURL* url = [NSURL URLWithString:urlStr];
NSString* fileName = [url path];
NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent: fileName];
NSData *dataEn = [[NSFileManager defaultManager] contentsAtPath:[path stringByAppendingPathComponent:fileName]];
NSLog(#"this to decrypt%#", [path stringByAppendingPathComponent:fileName]);
NSData *decryp = [RNDecryptor decryptData:dataEn withSettings:kRNCryptorAES256Settings password:#"A_SECRET_PASSWORD" error:nil];
[decryp writeToURL:[[NSURL alloc] initFileURLWithPath:path] atomically:YES];
if(decryp){
NSLog(#"decrypted");
}else{
NSLog(#" not decrypted");
}
weakSelf.fileUrl = [[NSURL alloc] initFileURLWithPath:path];
For some reason, the pdf files are not being decrypted and I'm being presented with a blank file even thought I'm receiving NSLog as decrypted :(
Can anyone help me please? thank you

Download and use .txt file in objective-c iphone app

I am having some problems getting my code to work :(
i am trying to download .txt file from the internet and store it in my iphone for further use but it wont work :/
here is my code :
-(void)DownloadFile
{
//declerations
NSString* TheFile;
NSFileManager* FM = [NSFileManager defaultManager];
//downloading file
NSURL *url = [NSURL URLWithString:#"http://www.myfile.com/apple.txt"];
TheFile = [[NSString alloc] initWithContentsOfURL: url
encoding: NSUTF8StringEncoding
error: nil];
//nsstring to nsdata
NSData* data = [TheFile dataUsingEncoding:NSUTF8StringEncoding];
//saving file
[FM createFileAtPath:[DocumentsDir stringByAppendingString:#"/file.txt"] contents:data attributes:nil];
}
DocumentsDir is defined with this function :
-(void)SetDocuments
{
NSArray* doc;
doc = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
DocumentsDir = [doc objectAtIndex:0];
}
Then i use this function assigne the file to a variable:
-(void)SetFile
{
File = [[NSString alloc]
initWithContentsOfFile:[DocumentsDir stringByAppendingString:#"/file.txt"]
encoding:NSUTF8StringEncoding
error:nil];
}
i would appreciate any tips or corrections etc :) thank you for your time.
Change your SetDocuments like this
-(void)SetDocuments{
NSArray* doc;
//doc = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
DocumentsDir = [doc objectAtIndex:0];
}

How do I load a CSV in IOS after saving it locally

I have a CSV file that I'm downloading from an S3 account and I would like to show it in my ios app by using the Quicklook framework.
The error I'm getting is in my console. It says
QLPreviewController's datasource shouldn't be nil at this point.
This appears after this line of code runs // Set data source
[previewer setDataSource:self];
here's all the code for downloading the file, saving it and then loading with quicklook
-(void)showDocument
{
NSString *stringURL = #"http://jornada.s3.amazonaws.com/Dust.csv";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:nil];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"tempfile.csv"];
//[urlData writeToFile:filePath atomically:YES];
BOOL newFile = [[NSFileManager defaultManager] createFileAtPath:filePath contents:urlData attributes:nil];
arrayOfDocuments = [[NSArray alloc] initWithObjects:
filePath, nil];
QLPreviewController *previewer = [[QLPreviewController alloc] init];
[self addSubview:previewer.view];
// Set data source
[previewer setDataSource:self];
// Which item to preview
[previewer setCurrentPreviewItemIndex:0];
}
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return [arrayOfDocuments count];
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
// Break the path into it's components (filename and extension)
NSArray *fileComponents = [[arrayOfDocuments objectAtIndex: index] componentsSeparatedByString:#"."];
NSArray *filePaths = [[fileComponents objectAtIndex:0] componentsSeparatedByString:#"/"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[((NSString *)[filePaths objectAtIndex:[filePaths count]-1]) stringByAppendingString:(NSString*)[fileComponents objectAtIndex:1]]];
// Use the filename (index 0) and the extension (index 1) to get path
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (fileExists) {
//
}
return [NSURL fileURLWithPath:filePath isDirectory:NO];
}
You don't add a preview controller's view to your view - you present the preview controller. And you should do that after setting the data source! So, in this order:
QLPreviewController* preview = [QLPreviewController new];
preview.dataSource = self;
[self presentViewController:preview animated:YES completion:nil];

Resources