Open pdf with other apps - iphone

I am displaying a pdf file in an app. I want to show "open with" option on nag bar showing apps installed on iPhone that can open same pdf and if user selects any of the app (for e.g. pdf viewer) then the pdf should get open with pdf viewer app.
How do I do this?
Please help
Thanks in advance.

To open a file in an available application on the device, use the UIDocumentInteractionController class.
A document interaction controller, along with a delegate object, provides in-app support for managing user interactions with files in the local system. For example, an email program might use this class to allow the user to preview attachments and open them in other apps. Use this class to present an appropriate user interface for previewing, opening, copying, or printing a specified file.
There are a lot of questions around it on SO if you get stuck. search results for UIDocumentInteractionController

This code will present the OpenIn interaction you're looking for. It works for iPhone and iPad. On iPad its in a popover. I'm generating the PDF but if you're just using one you have you don't need to writeToFile, just hand in the filePath.
// In your header. MyViewController.h
#interface MyViewController : UIViewController <UIDocumentInteractionControllerDelegate>
{
UIDocumentInteractionController *docController;
}
// In your implementation. MyViewController.m Open Results is hooked up to a button.
- (void)openResults
{
// Generate PDF Data.
NSData *pdfData = [self makePDF];
// Create a filePath for the pdf.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Report.pdf"];
// Save the PDF. UIDocumentInteractionController has to use a physical PDF, not just the data.
[pdfData writeToFile:filePath atomically:YES];
// Open the controller.
docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
docController.delegate = self;
docController.UTI = #"com.adobe.pdf";
[docController presentOpenInMenuFromBarButtonItem:shareButton animated:YES];
}

You can check with Apple Default api of "UIDocumentInteractionController".
Below is url:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIDocumentInteractionController_class/Reference/Reference.html
Hope, it will resolve your issue.
Cheers.

Related

Xcode UIWEBVIEW download , save HTML file and show

I want to download a page and show this in WEBVIEW local, but the images are missing. The images are only shown, when I'm online, in offline mode they are missing. How can I solve this? This is the code I used up until now:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"http://livedemo00.template-help.com/wt_37587/index.html"];
//[WEBVIEW loadRequest:reqURL];
// Determile cache file path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [NSString stringWithFormat:#"%#/%#", [paths objectAtIndex:0],#"index.html"];
// Download and write to file
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
// Load file in UIWebView
[WEBVIEW loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
[super viewDidLoad];
}
I've been meaning to write this up for a few weeks now, and this question finally got me to do it. See Drop-in offline caching for UIWebView (and NSURLProtocol).
The short answer, in my experience, is that the easiest solution is to use an NSURLProtocol to intercept NSURLConnection requests (including the ones made by UIWebView) and write the results to disk. If the request is made when you're offline, just read the response from disk and replay it. This is extremely transparent to the rest of the application, and avoids all kinds of edge-cases related to subclassing NSURLCache. (For more information on how to subclass NSURLCache see Substituting local data for remote UIWebView requests on Cocoa With Love, and AFCache.)
My NSURLProtocol approach is very simple, and is not a general-purpose caching solution. It's just intended to assist a UIWebView when you're offline. But for that, I think it solves the problem well.

How do I format and put images in an email from my app?

There have been some older posts about this with very complicated answers. I was wonder if there is a simple way to take an image that is in your project and put it in an email, composed your app but sent through the mail program.
I also don't know how to format it. If I put \n the mail program is never opened.
Here is what does work:
NSString *url = [NSString stringWithString: #"mailto:?&subject=Hello%20There!&body=Really%20Cool.%20Check%20this%20out!"];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
And I would like to add an image and make it look nice, with newlines. Could someone help me out here?
Thanks!
R
You have two options, image as attachment with a mail compose view, or inline as HTML, which means you'd have to upload the app's images somewhere accessible with a permalink or fixed URL. Even if you can form a URL with a local path, the email recipient doesn't receive mail using your app, so it's sandboxed away from the world.
If you generate the pictures in the app it's not easier than a mail compose view, but if uploading them is okay it's dead easy.
I solved it today by uploading optimized and smaller jpg versions of the png images with FTP and linking to it with <b><img src="http://blah.etc.org/myfolder/mypic.jpg" /></b>. The <b> tags were needed to "trick" openURL into not stripping the image back in SDK 3.0, they might not be needed now.
You will want to use MFMailComposeViewController to send an attachment.
Attach an image that is part of your app (in the same directory) to an email like this:
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"My Image Is Attached"];
//other mail settings here
//now add your attachment
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *whereToFindFile = [NSString stringWithFormat:#"myImage.png"];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:whereToFindFile];
NSData *imageData1 = [[[NSData alloc] initWithContentsOfFile:appFile] autorelease];
[picker addAttachmentData:imageData1 mimeType:#"image/png" fileName:#"myImage"];

PDF in webview performance

I am using the following (simple) code to load a PDF from the documents folder in my app into a UIWebView. The performance is very poor. I tried loading the same PDF from the web via Safari and the performance was great. Does anyone have any ideas? (this viewController is being presented as a modalViewController).
- firstView.m
InfoViewController *mcontroller = [[InfoViewController alloc] init];
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *pathToPDF = [NSString stringWithFormat:#"%#/myPDF.PDF",docsPath];
NSURL *targetURL = [NSURL fileURLWithPath:pathToPDF];
mcontroller.urlToFile = targetURL;
[self presentModalViewController:mcontroller animated:YES];
modalViewController.m -
- (void)viewDidLoad {
[super viewDidLoad];
NSURLRequest *request = [NSURLRequest requestWithURL:urlToFile];
[webView loadRequest:request];
}
I ended up using the documentInteractionController for this to display the PDF in Quick Look. There is a great tutorial for this in the 2010 WWDC vids.
No idea why it wasn't working well in webView, but it's smooth as silk in Quick Look.
The first thing I would look at is the PDF its self. Often people try loading huge PDF files and expect them to perform wonderfully. Can you post the PDF for us to see? How large is the file? Remember that the PDF file size is the compressed size, to display images in the PDF they will be uncompressed when stored in RAM. Its not uncommon for a 500KB image on disk to use 20 MB in memory (This applies for all raster graphics, not just PDFs). This is usually the case when PDF performance is poor from what I've seen around here.
I know you said it works great in Safari, however we don't know what all Apple does in Safari's internals vs a UIWebView. Also Safari is usually running in the background, so it is using memory even when your app is running. This reduces mem that you app can use, but when you are running safari as the foremost app, 3rd party apps aren't using much memory, so safari could potentially cache more of the PDF at a time.

Where should I store an image selected on the iPhone?

I want to take a picture or select an existing picture from the users existing photos. What is the best way to do this?
Specifically I am concerned where I should to store the image. The storage location should be private to the application. I need to be able to reuse the image as a background every time the application opens. Thanks!
You should use the UIImagePickerController to retrieve images from the library or the camera. You can persist the picture in the App's Documents folder. This folder is private to your app and is writeable.
You can get the path to the documents folder like so
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *docDirectory = [sysPaths objectAtIndex:0];
And to save a file there.
NSString *filePath = [NSString stringWithFormat:#"%#whatever.jpg",docDirectory];
NSData *toSave = UIImageJPEGRepresentation(image,1.0); //image is a UIImage
[toSave writeToFile:filePath atomically:YES];

Emailing full screen of iPhone app

I am developing an iPhone app for creating images using built in graphics and user defined text.
I want to be able to have my app, with built in graphics and user defined text, which can then be sent as a single image (much like a screenshot) to the email app to be emailed.
Is there a way to do this without taking a screenshot, leaving the app, going into the Photos app, selecting the screenshot, and emailing it from there?
Ultimately I would like to be able to have a button in my app that the user could tap, and the whole screen would be captured and sent directly to the mail app.
Any pointers gratefully accepted!
To expand upon Brent's answer, the following code will grab a screenshot and save it out to the Documents directory as a PNG called screenshot.png:
UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow];
UIGraphicsBeginImageContext(screenWindow.frame.size);
[screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *screenshotPNG = UIImagePNGRepresentation(screenshot);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error = nil;
[screenshotPNG writeToFile:[documentsDirectory stringByAppendingPathComponent:#"screenshot.png"] options:NSAtomicWrite error:&error];
This is a little crude, as it will leave a blank spot near the top of the screen for the title bar, and doesn't appear to grab the content from CAEAGLLayers.
Also, I don't believe you can use the standard mailto:// URL construction, followed by openURL, to send MIME-encoded attachments. Maybe the 3.0 SDK fixes this, but I've yet to play with it. You may need to use something like sksmtpmessage to send the message directly from within your application.
There's also the private API UIGetScreenImage. It is used like so:
CGImageRef UIGetScreenImage();
#interface UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents;
#end
#implementation UIImage (ScreenImage)
+ (UIImage *)imageWithScreenContents
{
CGImageRef cgScreen = UIGetScreenImage();
if (cgScreen) {
UIImage *result = [UIImage imageWithCGImage:cgScreen];
CGImageRelease(cgScreen);
return result;
}
return nil;
}
#end
This function may be combined with UIImagePNGRepresentation to produce a PNG.
Apple is now allowing applications to use the;
CGImageRef UIGetScreenImage(void);
function. Although you must remember that it returns a retained CGImageRef and you'll have to manage your memory accordingly.
They also say that, "...a future release of iPhone OS may provide a public API equivalent of this functionality. At such time, all applications using UIGetScreenImage() will be required to adopt the public API."
skpsmtpmessage is great. If fact, it's so good, I went and cloned it and added sample project on github. The sample GUI below adds a few bells and whistles, like a progress bar and some other goodies, but it basically maintains the core skpsmtpmessage code.
http://github.com/kailoa/iphone-smtp/tree/master
I have no idea if this will work, but you can try creating a bitmap-backed graphics context, then getting your root view's Core Animation layer and calling its -renderInContext: method. That might do it, but I've never tried it.
Perhaps, though, you should consider a different approach. Is it just that you've written a bunch of custom drawing code that's visible on screen and you want to be able to draw into a file or memory buffer too? If so, perhaps you should factor that drawing code out of your view and into a separate object that your view simply uses. That would allow you to very easily draw it both ways.
In OS 3.0, you can use MFMailComposeViewController:
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker addAttachmentData:screenshotPNG mimeType:#"image/png" fileName:#"PNGfromMyApp"];