Knowledge Base - How to build your first PDF reader for iOS - v4.x

Download the PDF version of this guide.

How to include RadaeePDF SDK in your project

Create folder in your project called “PDFViewer”.

Copy these folders and files from demo’s PDFViewer folder into your new PDFViewer folder with:

  • PDFLayout
  • PDFLib (without ios(sign) folder if present) 
  • PDFPages
  • PDFReader
  • PDFRes
  • PDFView 
  • RDMenu.h
  • RDMenu.m
  • RDPlugin
  • RDSignature
  • RDToolbar.h
  • RDToolbar.m
  • RDTreeTableViewController
  • UILElement.h
  • UILElement.m
  • UILShadowView.h
  • UILShadowView.m
  • UINavigationController+autoRotate.h
  • UINavigationController+autoRotate.m

Drag your PDFViewer folder with “Create groups” option selected except PDFRes folder.

Drag PDFRes folder into your project with “Create folder references” option.

Delete if present in PDFViewer/PDFLib:

  • PDFObjc.1.h 
  • PDFObjc.1.m 

Delete if present in PDFViewer

  • main.m 

Add these lines in your prefix.pch file:

#ifdef __OBJC__

    #import <UIKit/UIKit.h>

    #import <Foundation/Foundation.h>

    #import "UINavigationController+autoRotate.h"

#endif

#import "RDUtils.h"

If you don’t have any prefix.pch file in your project you could copy PDFViewer-Prefix.pch from Radaee demo project in your project folder and set its path as prefix header in Build Setting/Prefix Header.

In Build Phases/Link Binary With Libraries:

  • Add QuartzCore framework 
  • Add CoreGraphics framework 
  • Add libc++ lib 
  • Add libRDPDFLib.a (if it isn’t already added)

Add -lz and -lstdc++ in Other Linker Flags of Build Settings tab 

The building process may throw an error while building the project for iOS Simulator and linking in object file built for ARM64 architecture iOS, for architecture arm64:

  • Add arm64 in Build Settings/excluded Architectures debug. 

How to open your first PDF file

Import RDVGlobal.h in your AppDelegate.h 

Add :

- [RDVGlobal Init];

in - (BOOL)application:(UIApplication  *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Add a Navigation controller in Main.storyboard, delete the Root View Controller, put a root view controller segue from your Navigation Controller to your View Controller and apply “Is Initial View Controller” to the Navigation Controller.

Import PDFReaderCtrl.h and RDUtils.h in your ViewController.h and create NSMutableArray *m_files and PDFReaderCtrl *m_pdf:

#import <UIKit/UIKit.h>

#import "PDFReaderCtrl.h"

#import "RDUtils.h"

@interface ViewController : UIViewController

{

NSMutableArray *m_files;

PDFReaderCtrl *m_pdf;

}

Add these functions to your ViewController.m:

- (void)refreshDocuments

{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *dpath = [paths objectAtIndex:0];
    NSFileManager *fm = [NSFileManager defaultManager];
    m_files = [[NSMutableArray alloc] init];
    [self addPDFs:dpath :@"" :fm :0];
    [self copyDocumentsFromAssets:dpath];
}

- (void)addPDFs:(NSString *)dpath :(NSString *)subdir :(NSFileManager *)fm :(int)level
{
    NSString *path = [dpath stringByAppendingFormat:@"/%@", subdir];
    NSDirectoryEnumerator *fenum = [fm enumeratorAtPath:path];
    NSString *fName;
    while(fName = [fenum nextObject])
    {
        BOOL dir;
        NSString *dst = [path stringByAppendingFormat:@"%@",fName];
        if( [fm fileExistsAtPath:dst isDirectory:&dir] )
        {
            if( dir )
            {
                [self addPDFs:dpath :dst :fm :level+1];
            }
            else if( [dst hasSuffix:@".pdf"] )
            {
                NSString *dis = [subdir stringByAppendingFormat:@"%@",fName];//display name
                RDFileItem *item = [[RDFileItem alloc] init:dis :dst :level];
                [m_files addObject:item];
            }
        }
    }
}

- (void)copyDocumentsFromAssets :(NSString *)dpath
{
    NSString *hf = [[NSBundle mainBundle] pathForResource:@"PDFRes" ofType:nil];
    for (NSString *fpath in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:hf error:nil]) {
        if([fpath.pathExtension isEqualToString:@"pdf"] || [fpath.pathExtension isEqualToString:@"PDF"]) {
            NSString *documentPath = [hf stringByAppendingPathComponent:fpath];
            NSString *destPath = [dpath stringByAppendingPathComponent:fpath];           
if(![[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
                [[NSFileManager defaultManager] copyItemAtPath:documentPath toPath:destPath error:nil];
                RDFileItem *item = [[RDFileItem alloc] init:[fpath stringByDeletingPathExtension] :destPath :0];
                [m_files addObject:item];
            }
        }
    }
}

- (void)pdf_open_path:(RDFileItem *)item :(NSString *)pswd
{
    //Open PDF file
    PDFDoc *doc = [[PDFDoc alloc] init];
    [item.locker lock];
    int result = [doc open:item.path :pswd];
    [item.locker unlock];
    if(result == 0)//succeeded
    {
        m_pdf = [[UIStoryboard storyboardWithName:@"PDFReaderCtrl" bundle:nil] instantiateViewControllerWithIdentifier:@"rdpdfreader"];
        [m_pdf setDoc:doc];
        m_pdf.hidesBottomBarWhenPushed = YES;
        GLOBAL.g_pdf_name = [NSMutableString stringWithString:[item.path lastPathComponent]];
        [self.navigationController pushViewController:m_pdf animated:YES];
    }
    else if(result == 2)//require password
    {
        [self pdf_show_pwd_error:^(NSString *pwd) {
            [self pdf_open_path:item :pwd];
        }];
    }
    else//error
    {
        [self showOpenErrorAlertController];
    }
}

- (void)pdf_show_pwd_error:(void (^)(NSString *pwd))success
{
    NSString *title = NSLocalizedString(@"Please Enter PassWord", @"Localizable");
    UIAlertController *pwdAlert = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
    [pwdAlert addTextFieldWithConfigurationHandler:^(UITextField *textField)
     {
         textField.placeholder = NSLocalizedString(@"PassWord", @"Localizable");
         textField.secureTextEntry = YES;
     }];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"Localizable") style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        UITextField *password = pwdAlert.textFields.firstObject;
        success(password.text);
    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Localizable"style:UIAlertActionStyleCancel handler:nil];
    [pwdAlert addAction:okAction];
    [pwdAlert addAction:cancel];
    [self presentViewController:pwdAlert animated:YES completion:nil];
}

- (void)showOpenErrorAlertController
{
    NSString *str1 = NSLocalizedString(@"Alert", @"Localizable");
    NSString *str2 = NSLocalizedString(@"Error Document,Can't open", @"Localizable");
    NSString *str3 = NSLocalizedString(@"OK", @"Localizable");
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:str1 message:str2 preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:str3 style:UIAlertActionStyleDefault handler:nil];
    [alert addAction:okAction];
    [self presentViewController:alert animated:YES completion:nil];
}

add : 

[self refreshDocuments];

in  - (void)viewDidLoad

Create a method to open a pdf:

-(void)openPDF
{
    for(int i = 0; i <[m_files count]; i++)
    {
        RDFileItem *item = [m_files objectAtIndex:i];
        NSString *fName = item.help;
        if([fName isEqualToString:@"test.pdf"])
        {
            [self pdf_open_path:item :nil];
        }
    }
}

 

Applies To

RadaeePDF SDK for iOS

Related Articles

How to create your own APP with Swift and RadaeePDF SDK

Details

Created : 2021-04-13 17:30:06, Last Modified : 2021-04-13 18:19:53