Deleting certain pages of pdf and coverting back to NSMutableData - ios

I have a NSMutableData which contains pdf data. I want to delete certain pages from the pdf and return the pdf. I have tried creating the CGPDFContext, CGPDFPageRef, etc, but nothing really worked out. I have the below code, Can someone help me to fill the 3 steps.
-(NSMutableData *)deletePagesofPDF:(NSMutableData *)data withStartPage:(int)startpage withEndPage:(int)endpage{
NSData *data1 = data;
CFDataRef myPDFData = (__bridge CFDataRef)data1;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
//step 1 delete pages from startpage to endpage.
//step 2 save pdf
//step 3 convert pdf back to NSMutabledata
return data;
}
Edit 1
I have decided to change my strategy. Instead of deleting the pages, i am now creating a new pdf with only the pages i require from another PDF. Please see the code below, somehow it crashes while creating the pdf context. error is : address doesn't contain a section that points to a section in a object file. I could not go past creating the context. Please correct me if there is something wrong after creating the context.
-(void)saveNSDataToPDFFile:(NSMutableData *)data{
NSData *data1 = data;
CFDataRef myPDFData = (__bridge CFDataRef)data1;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGPDFPageRef newPage = CGPDFDocumentGetPage(pdf, 2);
NSMutableData *pdfData = [[NSMutableData alloc] init];
CGRect mediaBox = CGRectMake(0, 0, 850, 1100);
CGContextRef pdfContext = CGPDFContextCreate((__bridge CGDataConsumerRef)(pdfData),&mediaBox,NULL);
CGPDFContextBeginPage (pdfContext,nil);
CGContextDrawPDFPage(pdfContext, newPage);
CGPDFContextClose(pdfContext);
[pdfData writeToFile:[self getDBPathPDf:#"Rajashekar.pdf"] atomically:YES];
}
EDIT 2
Sorry about my long post.
I can save the pdf file now without crashing but i cannot see the data inside the pdf. It just shows a medium sized box with "PDF" written inside it. Where am i going wrong?
-(void)saveNSDataToPDFFile:(NSMutableData *)data{
NSData *data1 = data;
CFDataRef myPDFData = (__bridge CFDataRef)data1;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGPDFPageRef newPage = CGPDFDocumentGetPage(pdf, 2);
NSMutableData *pdfData = [[NSMutableData alloc] init];
CGRect mediaBox = CGRectMake(0, 0, 850, 1100);
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((__bridge CFMutableDataRef)pdfData);
CGContextRef pdfContext = CGPDFContextCreate(consumer,&mediaBox,NULL);
if (pdfContext)
{
CGPDFContextBeginPage (pdfContext,nil);
CGContextDrawPDFPage(pdfContext, newPage);
CGPDFContextClose(pdfContext);
[pdfData writeToFile:[self getDBPathPDf:#"Rajashekar.pdf"] atomically:YES];
}
}
EDIT 3
Its working....:) i forgot to CGPDFContextEndPage(pdfContext); before i closed the context.

Related

PDF First Page doesn't show in iOS

I have to show PDF First Page in UITableViewCell's ImageView.
My PDF Documents are located in document directory of app.
Here is my code in CellForRowAtIndexPath
NSURL* url =[self.arrayOfBooks objectAtIndex:indexPath.row];
UIImage *cellImage = [self buildThumbnailImage:MyGetPDFDocumentRef(url.absoluteString)];
cell.imageView.image = cellImage;
And Here is buildThumbnailImage Method.
- (UIImage *)buildThumbnailImage:(CGPDFDocumentRef)pdfDocument
{
BOOL hasRetinaDisplay = FALSE; // by default
CGFloat pixelsPerPoint = 1.0; // by default (pixelsPerPoint is just the "scale" property of the screen)
if ([UIScreen instancesRespondToSelector:#selector(scale)]) // the "scale" property is only present in iOS 4.0 and later
{
// we are running iOS 4.0 or later, so we may be on a Retina display; we need to check further...
if ((pixelsPerPoint = [[UIScreen mainScreen] scale]) == 1.0)
hasRetinaDisplay = FALSE;
else
hasRetinaDisplay = TRUE;
}
else
{
// we are NOT running iOS 4.0 or later, so we can be sure that we are NOT on a Retina display
pixelsPerPoint = 1.0;
hasRetinaDisplay = FALSE;
}
size_t imageWidth = 320; // width of thumbnail in points
size_t imageHeight = 460; // height of thumbnail in points
if (hasRetinaDisplay)
{
imageWidth *= pixelsPerPoint;
imageHeight *= pixelsPerPoint;
}
size_t bytesPerPixel = 4; // RGBA
size_t bitsPerComponent = 8;
size_t bytesPerRow = bytesPerPixel * imageWidth;
void *bitmapData = malloc(imageWidth * imageHeight * bytesPerPixel);
// in the event that we were unable to mallocate the heap memory for the bitmap,
// we just abort and preemptively return nil:
if (bitmapData == NULL)
return nil;
// remember to zero the buffer before handing it off to the bitmap context:
bzero(bitmapData, imageWidth * imageHeight * bytesPerPixel);
CGContextRef theContext = CGBitmapContextCreate(bitmapData, imageWidth, imageHeight, bitsPerComponent, bytesPerRow,
CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
//CGPDFDocumentRef pdfDocument = MyGetPDFDocumentRef(); // NOTE: you will need to modify this line to supply the CGPDFDocumentRef for your file here...
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument, 1); // get the first page for your thumbnail
CGAffineTransform shrinkingTransform =
CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, CGRectMake(0, 0, imageWidth, imageHeight), 0, YES);
CGContextConcatCTM(theContext, shrinkingTransform);
CGContextDrawPDFPage(theContext, pdfPage); // draw the pdfPage into the bitmap context
CGPDFDocumentRelease(pdfDocument);
//
// create the CGImageRef (and thence the UIImage) from the context (with its bitmap of the pdf page):
//
CGImageRef theCGImageRef = CGBitmapContextCreateImage(theContext);
free(CGBitmapContextGetData(theContext)); // this frees the bitmapData we malloc'ed earlier
CGContextRelease(theContext);
UIImage *theUIImage;
// CAUTION: the method imageWithCGImage:scale:orientation: only exists on iOS 4.0 or later!!!
if ([UIImage respondsToSelector:#selector(imageWithCGImage:scale:orientation:)])
{
theUIImage = [UIImage imageWithCGImage:theCGImageRef scale:pixelsPerPoint orientation:UIImageOrientationUp];
}
else
{
theUIImage = [UIImage imageWithCGImage:theCGImageRef];
}
CFRelease(theCGImageRef);
return theUIImage;
}
CGPDFDocumentRef MyGetPDFDocumentRef(NSString *inputPDFFile)
{
//NSString *inputPDFFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"test.pdf"];
const char *inputPDFFileAsCString = [inputPDFFile cStringUsingEncoding:NSASCIIStringEncoding];
//NSLog(#"expecting pdf file to exist at this pathname: \"%s\"", inputPDFFileAsCString);
CFStringRef path = CFStringCreateWithCString(NULL, inputPDFFileAsCString, kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease (path);
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);
CFRelease(url);
if (CGPDFDocumentGetNumberOfPages(document) == 0)
{
printf("Warning: No pages in pdf file \"%s\" or pdf file does not exist at this path\n", inputPDFFileAsCString);
return NULL;
}
return document;
}
And Here is how i load pdf file list from document directory.
- (NSMutableArray *)loadBookFromDocumentDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [NSString stringWithFormat:#"%#",[paths objectAtIndex:0]];
NSFileManager *manager = [NSFileManager defaultManager];
NSError *error;
NSArray *files = [manager contentsOfDirectoryAtURL:[NSURL fileURLWithPath:documentsDirectory]
includingPropertiesForKeys:[NSArray arrayWithObject:NSURLContentModificationDateKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:&error];
NSArray* sortArray = [files sortedArrayUsingComparator:
^(NSURL *file1, NSURL *file2)
{
NSDate *file1Date;
[file1 getResourceValue:&file1Date forKey:NSURLContentModificationDateKey error:nil];
NSDate *file2Date;
[file2 getResourceValue:&file2Date forKey:NSURLContentModificationDateKey error:nil];
// Ascending:
//return [file1Date compare: file2Date];
// Descending:
return [file2Date compare: file1Date];
}];
NSMutableArray *sortedContents = [[NSMutableArray alloc] initWithArray:sortArray];
return sortedContents;
}
When i run my app , it doesn't show anything at Cell ImageView and showing this message.
file:///Users/MacUser/Library/Application%20Support/iPhone%20Simulator/7.1-64/Applications/08BE9071-6251-44ED-A8E0-55CD478380FC/Documents/CGPDFDocument.pdf" or pdf file does not exist at this path
I am sure i have that pdf and even showing PDF Name in TableView.
Where am i wroning?
Okay. I think I understand what's going on here.
You've "added your PDF files via iTunes". I have NO idea how that is supposed to actually work.
But it's clear to me that the PDF files in your simulator folder are zero bytes in size.
The code you have right now should work, you just need to get valid PDF files into there to start with.
In Terminal, you can open that folder using the command
open ~/Library/Application\ Support/iPhone\ Simulator/7.1-64/Applications/08BE9071-6251-44ED-A8E0-55CD478380FC/Documents
And when it opens in the Macintosh Finder, you'll see that all the PDF files in there are zero bytes in size. Manually copy in your correct PDF files and your app should begin to magically work in the simulator.
Now, for production code, you need to write code to REALLY copy the PDF files into the documents folder. Where do the PDF files come from originally? Do you download them or are they built into the app somewhere?

Add a signature image to a pdf without showing the pdf data to user in iOS

I want to add the signature on existing pdf. I have done this in following way:
1) Load existing pdf on UIView say mainView.
2) Add a signature image on mainView.
3) Call a following function
-(NSMutableData *)getPDFDatafromUIView
{
DebugLog(#"");
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [NSMutableData data];
// Points the pdf converter to the mutable data object and to the UIView to be converted
UIGraphicsBeginPDFContextToData(pdfData, mainView.bounds, nil);
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
mainView.layer renderInContext:pdfContext];
// remove PDF rendering context
UIGraphicsEndPDFContext();
return pdfData;
}
4) This function block your UI for a while, so call it on new thread
[NSThread detachNewThreadSelector:#selector(launchExportViewForExportDrawing) toTarget:self withObject:nil];
Using above method I get a pdf data with signature which contain the old pdf data too.
But for above method I must need to show the pdf in UIView. If I want do the above thing without loading on UIView, without showing pdf to user, How do I do that?
I am able to add a Image on pdf with creating the new pdf page. How do I add a image on existing pdf?
I have solved by creating the new PDF and drawing the pdf data and signature on it. Please refer following code:
// For adding the Siganture we need to wite the content on new PDF
-(void) addSignature:(UIImage *) imgSignature onPDFData:(NSData *)pdfData {
NSMutableData* outputPDFData = [[NSMutableData alloc] init];
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputPDFData);
CFMutableDictionaryRef attrDictionary = NULL;
attrDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, CFSTR("My Doc"));
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary);
CFRelease(dataConsumer);
CFRelease(attrDictionary);
CGRect pageRect;
// Draw the old "pdfData" on pdfContext
CFDataRef myPDFData = (__bridge CFDataRef) pdfData;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextBeginPage(pdfContext, &pageRect);
CGContextDrawPDFPage(pdfContext, page);
// Draw the signature on pdfContext
pageRect = CGRectMake(0, 0,imgSignature.size.width , imgSignature.size.height);
CGImageRef pageImage = [imgSignature CGImage];
CGContextDrawImage(pdfContext, pageRect, pageImage);
// release the allocated memory
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
CGContextRelease(pdfContext);
// write new PDFData in "outPutPDF.pdf" file in document directory
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pdfFilePath =[NSString stringWithFormat:#"%#/outPutPDF.pdf",docsDirectory];
[outputPDFData writeToFile:pdfFilePath atomically:YES];
}
Rohit Answer is working perfectly,But it works only single page so i just Added some code for all pages displaying with image(image shown in single page reaming pages are looks same).Thanks #Rohit
NSString *path = [[NSBundle mainBundle] pathForResource:#"PartB" ofType:#"pdf"];
NSURL *docURL = [NSURL fileURLWithPath:path];
NSString *pdfName = [NSString stringWithFormat:#"%#",docURL];
NSLog(#"pdfName: %#", pdfName);
NSData *pdfData = [NSData dataWithContentsOfFile:path];
NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:#"PartB.pdf" withExtension:nil];
CGPDFDocumentRef pdf1 = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
long pageCount = CGPDFDocumentGetNumberOfPages(pdf1);
NSLog(#"the page count %ld",pageCount);
NSMutableData* outputPDFData = [[NSMutableData alloc] init];
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputPDFData);
CFMutableDictionaryRef attrDictionary = NULL;
attrDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, CFSTR("My Doc"));
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary);
CFRelease(dataConsumer);
CFRelease(attrDictionary);
CGRect pageRect;
// Draw the old "pdfData" on pdfContext
CFDataRef myPDFData = (__bridge CFDataRef) pdfData;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
for (int k=1; k<=pageCount; k++) {
CGPDFPageRef page3 = CGPDFDocumentGetPage(pdf, k);
pageRect = CGPDFPageGetBoxRect(page3, kCGPDFMediaBox);
CGContextBeginPage(pdfContext, &pageRect);
CGContextDrawPDFPage(pdfContext, page3);
if (k==pageSelect) {
pageRect = CGRectMake(0, 0,100 , 100);
CGImageRef pageImage = [mainImage.image CGImage];
CGContextDrawImage(pdfContext, pageRect, pageImage);
}
CGPDFContextEndPage(pdfContext);
}
CGPDFContextClose(pdfContext);
CGContextRelease(pdfContext);
// write new PDFData in "outPutPDF.pdf" file in document directory
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pdfFilePath =[NSString stringWithFormat:#"%#/outPutPDF.pdf",docsDirectory];
[outputPDFData writeToFile:pdfFilePath atomically:YES];
NSLog(#"save the pdf %#",pdfFilePath);
I'm not sure I understand your problem completely. From what I can tell you have a UIView that you're rendering onto a PDF document, and you want to add a signature image and not show it to the user.
If you're trying to add a "signature image" to your pdf, you can add a UIImageView to the UIView that you're rendering to the pdf.
If you don't want the user to see the UIView in the mean time, you could change it's origin to somewhere off bounds, for example:
CGRect originalFrame = mainView.frame;
CGRect newFrame = mainView.frame;
newFrame.origin.x = -newFrame.size.width;
newFrame.origin.y = -newFrame.size.height;
mainView.frame = newFrame;
//do all your PDF stuff here
mainView.frame = originalFrame;
I hope that helps. If it doesn't, please clarify the problem :)

how to create multiple pages pdf programmatically in iPhone

I have one image array and I am trying to create pdf with that images.how can i create multiple pages pdf file.
I checked one tutorial but its not working for me.
How to create a multiple page PDF in ios6?
Please help me
This works for me:
NSArray *pageArray = yourImageArray;
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData(pdfData, CGRectMake(0, 0, 595, 842), nil);
for (UIImage *theImage in pageArray) {
UIGraphicsBeginPDFPage();
NSData *jpegData = UIImageJPEGRepresentation(theImage, 0.5);
CGDataProviderRef dp = CGDataProviderCreateWithCFData((__bridge CFDataRef)jpegData);
CGImageRef cgImage = CGImageCreateWithJPEGDataProvider(dp, NULL, true, kCGRenderingIntentDefault);
[[UIImage imageWithCGImage:cgImage] drawInRect:CGRectMake(0, 0, theImage.size.width, theImage.size.height)];
}
UIGraphicsEndPDFContext();
return pdfData;
For starting each new page in the pdf, use
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageWidth, pageHeight), nil);

e-sign in pdf file, makes multiple paged pdf to single page with same content

Am trying to sign my pdf file which is multiple paged, by fetching the signature drawn in UIView to my pdf file, but the problem I face is, after signing the pdf, signature is integrated with the pdf file where all the pages in the pdf file is displayed in a single page as a pdf file.(ex if 8 pages are there in a pdf file, then all 8 pages are displaying as a single page along with the signature). The output of the pdf file with signature integrated, is as below
Codes used for fetching the image from document directory and integrating with the pdf file is,
- (void)viewWillAppear:(BOOL)animated
{
[webView reload];
UIWebView *webView;
webView= [[UIWebView alloc] initWithFrame:CGRectMake(0,44, 320, 460)];
NSString *path1;
path1 = [[NSBundle mainBundle] pathForResource:#"typo_tips" ofType:#"pdf"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDirectoryPath;
NSURL *targetURL;
documentDirectoryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"typo_tips.pdf"];
[fileManager copyItemAtPath:path1 toPath:documentDirectoryPath error:&error];
NSLog(#"path1 value is %# \n",path1);
NSLog(#"docu dir path is %# \n",documentDirectoryPath);
if (entered==1)//"entered==1", after save button clicked in signviewcontroller
{
targetURL = [NSURL fileURLWithPath:documentDirectoryPath];
}
else targetURL = [NSURL fileURLWithPath:path1];
if (entered==1)
{
CFURLRef url;
url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:documentDirectoryPath]);
CGPDFDocumentRef myDocument;
myDocument = CGPDFDocumentCreateWithURL(url);
// Create PDF context
CGContextRef pdfContext = CGPDFContextCreateWithURL(url, NULL, NULL); //(CFURLRef)outputURL
CGPDFContextBeginPage(pdfContext, NULL);
UIGraphicsPushContext(pdfContext);
int totalPages = (int)CGPDFDocumentGetNumberOfPages(myDocument);
NSLog(#"no. of pages in pdf is %d \n",totalPages);
for (int currentPage = 0; currentPage < totalPages; currentPage++)
{
CGContextDrawPDFPage(UIGraphicsGetCurrentContext(), CGPDFDocumentGetPage(myDocument, page));
//"page" is current pdf page to be signed
if (page == currentPage)
{
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"Image.png"];// "image.png" is the saved user's signature in document directory
image = [[UIImage alloc] initWithContentsOfFile:filePath];
CGRect imageRect = CGRectMake(50, 50, image.size.width, image.size.height);
CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image.CGImage);
}
}
// Clean up
UIGraphicsPopContext();
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
}
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[webView loadRequest:request];
[self.view addSubview:webView];
}
Can any one help me, how to display the pdf page separately along with the e-signature integrated.
Try this:
// Create PDF context
CGContextRef pdfContext = CGPDFContextCreateWithURL(url, NULL, NULL); //(CFURLRef)outputURL
int totalPages = (int)CGPDFDocumentGetNumberOfPages(myDocument);
NSLog(#"no. of pages in pdf is %d \n",totalPages);
for (int currentPage = 0; currentPage < totalPages; currentPage++)
{
CGPDFContextBeginPage(pdfContext, NULL);
UIGraphicsPushContext(pdfContext);
CGContextDrawPDFPage(UIGraphicsGetCurrentContext(),
CGPDFDocumentGetPage(myDocument, page));
//"page" is current pdf page to be signed
if (page == currentPage)
{
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"Image.png"];
image = [[UIImage alloc] initWithContentsOfFile:filePath];
CGRect imageRect = CGRectMake(50, 50, image.size.width, image.size.height);
CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image.CGImage);
}
// Clean up
UIGraphicsPopContext();
CGPDFContextEndPage(pdfContext);
}
CGPDFContextClose(pdfContext);
In your for loop you have to create a new PDF page for each page in the source file. I moved these lines inside the for loop:
CGPDFContextBeginPage(pdfContext, NULL);
UIGraphicsPushContext(pdfContext);
and also the corresponding cleanup code.
You are using a webview to display it Reader which uses iOS built in PDF reading classes.
https://github.com/vfr/Reader
Failing that, try adjusting the zoom levels on your UIWebview. Unfortunately UIWebview has limited options because its just a web container.

How to attach CGPDFDocument/CGPDFPage to MFMailComposeViewController

I have a muti page pdf document stored on local storage. I want to extract any page out of that pdf doc and convert it into NSData to attach it with 'MFMailComposeViewController'. With the following lines of code, I can easily retrive the required page...
CGPDFDocumentRef pdfDoc=CGPDFDocumentCreateWithURL(pdfURL);
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDoc, pageNumber);
But I am unable to find a way to convert pdfPage into NSData so that I can attach it with mail.
NOTE: The requirement is to attach page in PDF format, so please DON'T suggest converting PDF into PNG or JPEG.
CGPDF is primarily for drawing from and to PDF, not for converting PDF data. Therefore, if you want to extract a page, you'll have to draw it. Use for example:
// input
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)inputData);
CGPDFDocumentRef document = CGPDFDocumentCreateWithProvider(provider);
CGPDFPageRef page = CGPDFDocumentGetPage(document, pageIndex);
CGRect mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
// output
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((__bridge CFMutableDataRef)outputData);
CGContextRef context = CGPDFContextCreate(consumer, &mediaBox, NULL);
// draw
CGContextBeginPage(context, &mediaBox);
CGContextDrawPDFPage(context, page);
CGContextEndPage(context);
// cleanup
CGDataProviderRelease(provider);
CGPDFDocumentRelease(document);
CGDataConsumerRelease(consumer);
CGContextRelease(context);
Here is what you do :
NSMutableData *pdfData = [[NSMutableData alloc] init];
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)pdfData);
const CGRect mediaBox = CGRectMake(0.0f, 0.0f, drawingWidth, drawingHeight);
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, &mediaBox, NULL);
UIGraphicsPushContext(pdfContext);
CGContextBeginPage(pdfContext, &mediaBox);
CGContextDrawPDFPage(pdfcontext, pdfPage);
CGContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
UIGraphicsPopContext();
CGContextRelease(pdfContext);
CGDataConsumerRelease(dataConsumer);
// Mail part
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
NSString *mime=#"application/pdf";
[mailViewController setSubject:#"Subject"];
[mailViewController setMessageBody:#"Message Body" isHTML:NO];
[mailViewController addAttachmentData:[pdfData copy] mimeType:mime fileName:#"page.pdf"];
[self presentModalViewController:mailViewController animated:YES];

Resources