iOS QLPreviewController load file from remote server URL - ios

What is approach should be used while loading files from remote server on QLPreviewController?
When should we download files using my server API to load them on QLPreviewController.
I am adding QLPreviewController as subview to my current view.
I can use datasource method to make call to download file from server.
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
But once file is downloaded i need to reload QLPreviewController, where this should be done
For images i would like to image gallery view so that swipe to view images downloaded from server.
Can anyone point me to any tutorial to load images from remote server URL

To show any file that supports QLPreviewController, the url should
be the fileURL.
(id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
It always returns fileURL - if you will use any other URL, it will crash. After downloading is over save the file in documents directory and then push to preview.
- (void)saveFileInDocDirectoryWithFileName:(NSString *)title{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath_ = [paths objectAtIndex:0];
NSString *filePath = [ docPath_ stringByAppendingPathComponent:title];
self.fileURL = [NSURL fileURLWithPath:filePath];
[self pushToPreViewWithURL:fileURL];
}
- (void)pushToPreViewWithURL:(NSURL *)filePathURL{
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
// start previewing the document at the current section index
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.navigationController pushViewController:previewController animated:YES];
}];
}
Then in delegate method, return fileURL:
- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx {
return self.fileURL;
}

Related

How to read files in iOS

I have a file on the iOS iPhone emulator (Download folder).
How can my app get the permission to read this file, in Objective-C?
I can get the file path with the following:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentsDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docsDirectory stringByAppendingPathComponent:#"file.txt"];
NSLog(#"%#", filePath);
But how can I read it?
Your application is sandboxed and can access files freely only within its own container. For accessing user personal files, you should leverage UIDocumentPickerViewController class, and let the user pick the file (him/her)self:
UIDocumentPickerViewController *pickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:#[
[UTType typeWithFilenameExtension:#"xml"]
]];
pickerVC.delegate = self;
[self presentViewController:pickerVC animated:YES completion:nil];
Then you can access whatever the user selected in the delegate method:
#pragma mark UIDocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller
didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
NSLog(#"%#", [NSString stringWithContentsOfURL:urls.firstObject
encoding:NSUTF8StringEncoding
error:nil]);
}

presentOpenInMenuFromRect not working DocumentHandler.h - QuickLook

I'm using documenthandler cordova plugin in where if I click the button I get the pdf in the document handler from the url which works fine, so that I can save the pdf into iBooks.
Now, instead of opening the document in the viewer and clicking the share button and then click again to save into iBooks I need to be able to trigger the share button without opening the document. I know this can be done using presentOpenInMenuFromRect instead of presentViewControllerbut it does not work for some reason, code below:
#import "DocumentHandler.h"
#implementation DocumentHandler
- (void)HandleDocumentWithURL:(CDVInvokedUrlCommand*)command;
{
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:#""];
__weak DocumentHandler* weakSelf = self;
dispatch_queue_t asyncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(asyncQueue, ^{
NSDictionary* dict = [command.arguments objectAtIndex:0];
NSString* urlStr = dict[#"url"];
NSURL* url = [NSURL URLWithString:urlStr];
NSData* dat = [NSData dataWithContentsOfURL:url];
NSString* fileName = [url lastPathComponent];
NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent: fileName];
NSURL* tmpFileUrl = [[NSURL alloc] initFileURLWithPath:path];
[dat writeToURL:tmpFileUrl atomically:YES];
weakSelf.fileUrl = tmpFileUrl;
dispatch_async(dispatch_get_main_queue(), ^{
QLPreviewController* cntr = [[QLPreviewController alloc] init];
cntr.delegate = weakSelf;
cntr.dataSource = weakSelf;
UIViewController* root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
[root presentViewController:cntr animated:YES completion:nil];//this works fine and open the document with share button
CGRect rect = CGRectMake(0, 0, 1024, 768);
[root presentOpenInMenuFromRect:rect inView:self.view animated:YES]; // this doesn't work where
//I want to see only sharing options
//here are errors,one of them is /Property'view' not found on object of type ''DocumentHandler
});
[weakSelf.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
});
}
#pragma mark - QLPreviewController data source
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return 1;
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index
{
return self;
}
#pragma mark - QLPreviewItem protocol
- (NSURL*)previewItemURL
{
return self.fileUrl;
}
#end
I need help please :(
EDIT: see the image what I'm trying to achieve:
presentOpenInMenuFromRect is a UIDocumentInteractionController method. I do not think you are using one in this code, unless your root view controller is a UIDocumentInteractionController, which would be very very weird.
Instead of instantiating and presenting a QLPreviewController, instantiate an UIDocumentInteractionController and present the popover from the rect corresponding to the document's icon.
To do this, check out the UIDocumentInteractionController documentation. You'll see there is an interactionControllerWithURL: method that you can use to instantiate an UIDocumentInteractionController pointed at your file. You can then call
presentOpenInMenuFromRect:inView:animated: to show the popover you want.

How to upload image either .png or .jpg on ftp server in ios.?

I want to upload or save image to FTP server from my iOS app. but every time I get error that ftp not connected
I use SCRFTPRequest library.
here is my code...
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData * imageData = UIImagePNGRepresentation(image);
NSFileManager * fileManager = [NSFileManager defaultManager];
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",image]];
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
NSLog(#"image saved");
[picker dismissViewControllerAnimated:YES completion:nil];
ftpRequest = [SCRFTPRequest requestWithURL:[NSURL URLWithString:#"ftp://myURL"] toUploadFile:fullPath];
ftpRequest.username = #"DemoUser";
ftpRequest.password = #"DemoUser";
ftpRequest.customUploadFileName = #"inapp";
ftpRequest.delegate = self;
[ftpRequest startAsynchronous];
From White Raccoon,
Just Drag and Drop the WhiteRaccoon.h and WhiteRaccoon.m file and import CFNetwork framework in your project.
- (void) upload
{
//the upload request needs the input data to be NSData
//so we first convert the image to NSData
UIImage * ourImage = [UIImage imageNamed:#"space.jpg"];
NSData * ourImageData = UIImageJPEGRepresentation(ourImage, 100);
//we create the upload request
//we don't autorelease the object so that it will be around when the callback gets called
//this is not a good practice, in real life development you should use a retain property to store a reference to the request
WRRequestUpload * uploadImage = [[WRRequestUpload alloc] init];
uploadImage.delegate = self;
//for anonymous login just leave the username and password nil
uploadImage.hostname = #"xxx.xxx.xxx.xxx";
uploadImage.username = #"myuser";
uploadImage.password = #"mypass";
//we set our data
uploadImage.sentData = ourImageData;
//the path needs to be absolute to the FTP root folder.
//full URL would be ftp://xxx.xxx.xxx.xxx/space.jpg
uploadImage.path = #"/space.jpg";
//we start the request
[uploadImage start];
}
-(void) requestCompleted:(WRRequest *) request{
//called if 'request' is completed successfully
NSLog(#"%# completed!", request);
}
-(void) requestFailed:(WRRequest *) request{
//called after 'request' ends in error
//we can print the error message
NSLog(#"%#", request.error.message);
}
-(BOOL) shouldOverwriteFileWithRequest:(WRRequest *)request {
//if the file (ftp://xxx.xxx.xxx.xxx/space.jpg) is already on the FTP server,the delegate is asked if the file should be overwritten
//'request' is the request that intended to create the file
return YES;
}
Finally i got success to upload image file on ftp server.
To upload image on ftp i used Gold Raccoon external library.with this library you can easily upload image to ftp server.
https://github.com/albertodebortoli/GoldRaccoon

Open a pdf saved in my documents folder in Xcode project

I have made an app that creates a pdf and stores it in the apps documents folder. I would now like to open it and view it from within the app when a 'View pdf' UIButton is pressed.
I have already looked at a few questions on here and I have considered either a separate view controller or perhaps a scroll view.
What is the best method to use?
UPDATE:
I have followed advice and I am trying to use QLPreviewController. I have added QuickLook framework and now have the following, but I am stuck on how to get the path recognised in the pathForResource. Any suggestions?
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
NSString *path=[[NSBundle mainBundle] pathForResource:[pdfPathWithFileName] ofType:nil];
return [NSURL fileURLWithPath:path];
}
- (IBAction)viewPdfButton:(id)sender {
NSString *filename= #"ObservationPDF.pdf";
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documnetDirectory = [path objectAtIndex:0];
NSString *pdfPathWithFileName = [documnetDirectory stringByAppendingPathComponent:filename];
[self generatePdf: pdfPathWithFileName];
QLPreviewController *previewController=[[QLPreviewController alloc]init];
previewController.delegate=self;
previewController.dataSource=self;
[self presentViewController:previewController animated:YES completion:nil];
}
If the PDF file is in the app documents folder then you shouldn't be thinking about passing it to another app, you should be looking to present the file inside the app. 2 general options:
Add a UIWebView and load the local file into it
Use QLPreviewController to show a new view containing the PDF
The web view is simple and requires no transition on the UI. The preview controller needs a transition but offers some sharing / printing support for free.
This line is confused (and invalid syntax by the looks of it):
NSString *path=[[NSBundle mainBundle] pathForResource:[pdfPathWithFileName] ofType:nil];
You only use NSBundle to get items out of the bundle, and that isn't what you have. You should just be creating the URL with the file path where you save the file:
[NSURL fileURLWithPath:pdfPathWithFileName];
(which you may store or you may need to recreate in the same way as when you save the file)

UIActivityViewController & UIDocumentInteractionController not showing options

I am new to UIActivityViewController and perhaps I am missing a basic understanding. What I am trying to do is attached a csv, xml and vcard file to activity controller and show dropbox, google drive etc options. I have downloaded and installed dropbox, google drive etc apps on my iPhone.
Now when I launch UIActivityViewController all I see are default message and email app in my acitivity controller. How can I have other apps show up on their too? Do I need to install each and every apps individual SDKs and somehow incorporate them in my app?
This is what I wold like to see
but this is what I see instead.
Here's the code that I have tried so far
-(IBAction) dropBoxAction
{
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask ,YES);
NSString* documentsPath = [paths objectAtIndex:0];
//CSV
NSMutableString *fileNameStr = [NSMutableString stringWithFormat:#"test_CSV_Backup.csv"];
NSString* csvDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr];
NSData *csvData = [NSData dataWithContentsOfFile:csvDataFileStr];
//EXCEL
NSMutableString *fileNameStr2 = [NSMutableString stringWithFormat:#"test_EXCEL_Backup.xml"];
NSString* excelDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr2];
NSData *excelData = [NSData dataWithContentsOfFile:excelDataFileStr];
//VCARD
NSMutableString *fileNameStr3 = [NSMutableString stringWithFormat:#"test_VCARD_Backup.vcf"];
NSString* vcardDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr3];
NSData *vcardData = [NSData dataWithContentsOfFile:vcardDataFileStr];
//adding them all together
NSMutableArray *sharingItems = [NSMutableArray new];
[sharingItems addObject:csvData];
[sharingItems addObject:excelData];
[sharingItems addObject:vcardData];
UIActivity *activity = [[UIActivity alloc] init];
NSArray *applicationActivities = #[activity];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:applicationActivities];
[self presentViewController:activityController animated:YES completion:nil];
}
As #rmaddy said, you should use UIDocumentInteractionController to replace UIActivityViewController, just like this:
UIDocumentInteractionController *dc = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileNameStr]];
[dc presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES];
For anyone interested in future, here's the code all in one place. Do rate it up if this helps.
In your *.h file add this
#interface v1BackupComplete : UIViewController <UIDocumentInteractionControllerDelegate>
{
UIDocumentInteractionController *docController;
}
In your *.m file add this
/************************
* Dropbox ACTION
************************/
-(IBAction) dropBoxAction2
{
NSLog(#"dropBoxAction2 ...");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask ,YES);
NSString* documentsPath = [paths objectAtIndex:0];
NSMutableString *fileNameStr3 = [NSMutableString stringWithFormat:#"test_VCARD_Backup.vcf"];
NSString* vcardDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr3];
NSURL *fileURL = [NSURL fileURLWithPath:vcardDataFileStr];
docController = [self setupControllerWithURL:fileURL
usingDelegate:self];
bool didShow = [docController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];
NSLog(#"didShow %d ...", didShow);
if (!didShow)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ERROR"
message:#"Sorry. The appropriate apps are not found on this device."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
}
#pragma mark - UIDocumentInteractionControllerDelegate
- (UIDocumentInteractionController *) setupControllerWithURL:(NSURL *)fileURL
usingDelegate:(id <UIDocumentInteractionControllerDelegate>) interactionDelegate {
UIDocumentInteractionController *interactionController =
[UIDocumentInteractionController interactionControllerWithURL:fileURL];
interactionController.delegate = interactionDelegate;
return interactionController;
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
UIActivityViewController only shows standard built-in activities plus any custom activities you pass as applicationActivities.
For what you are doing, you don't want UIActivityViewController. You want a UIDocumentInteractionController. If you just want to display existing apps that can open the file, use one of the presentOpenInMenuFrom... methods.
But note that is to be used for just a single file, not three.
Passing three files makes no sense in this context.
I have used your code here to open with dropbox and only after I have used presentPreview method (bellow) It was worked for me.
The pdf was shown as preview and then on the preview share button click (top right) the dropbox option ("open in dropbox") did the job. As it works in the mail app in the attachment preview.
[interactionController presentPreviewAnimated:YES];
When i tried to open with presentOpenInMenuFromRect it was crashed on selecting "open in dropbox".

Resources