File Operations#
There are a number of file operations available against a document, an application developer should only be required to implement these if using the Custom UI.
Save#
Saving a document only needs to be invoked if there are changes made to a document. As such an application developer can verify if changes have been made or not and act accordingly. The MuPDFDKBasicDocumentViewController
session can be used to save the document with a callback method for the completion.
self.session.saveDocumentAnd(onCompletion: { (result:ARDKSaveResult,
error:ARError) in
self.updateUI() // refresh the UI on completion
switch result {
case ARDKSave_Succeeded:
break
case ARDKSave_Cancelled:
break
case ARDKSave_Error:
break
default:
break
}
})
[self.session saveDocumentAndOnCompletion:^(ARDKSaveResult result,
ARError err) {
[self updateUI]; // refresh the UI on completion
switch (result)
{
case ARDKSave_Succeeded:
break;
case ARDKSave_Cancelled:
break;
case ARDKSave_Error:
break;
default:
break;
}
}];
Save As#
An application developer should provide the new filename and use the saveTo method of the MuPDFDKBasicDocumentViewController
session to save documents with a new name.
let fileName:String = "new-filename.pdf"
let existingPath:NSString = session.fileState.absoluteInternalPath as NSString
let newPath:String = "\(existingPath.deletingLastPathComponent)/\(fileName)"
session.save(to: newPath, completion: { (result:ARDKSaveResult,
error:ARError) in
self.updateUI() // refresh the UI on completion
switch result {
case ARDKSave_Succeeded:
break
case ARDKSave_Cancelled:
break
case ARDKSave_Error:
break
default:
break
}
})
NSString *fileName = @"new-filename.pdf";
NSString *newPath = [[self.session.fileState.absoluteInternalPath
stringByDeletingLastPathComponent] stringByAppendingPathComponent:fileName];
[self.session saveTo:newPath completion:^(ARDKSaveResult result, ARError err) {
switch (result)
{
case ARDKSave_Succeeded:
break;
case ARDKSave_Cancelled:
case ARDKSave_Error:
NSLog(@"Save failed with error: %d", err);
break;
}
}];
Export#
It is possible to export the content of a PDF into an external text file for simple text extraction. To do so an application developer should define a valid file path to use with the exportToAPI
against the instance of MuPDFDKDoc
within the session.
let doc:MuPDFDKDoc = docVc.session.doc as! MuPDFDKDoc
doc.export(to: "docPath",
format: "txt",
completion: { (result:ARDKSaveResult) in
switch result {
case ARDKSave_Succeeded:
break
case ARDKSave_Cancelled:
break
case ARDKSave_Error:
break
default:
break
}
})
MuPDFDKDoc *doc = (MuPDFDKDoc*)docVc.session.doc;
[doc exportTo:@"docPath" format:@"txt" completion:^(ARDKSaveResult result) {
switch (result)
{
case ARDKSave_Succeeded:
break;
case ARDKSave_Cancelled:
case ARDKSave_Error:
break;
}
}];
Note
At present the only valid format to export to is a text file, so the format parameter should always be set to “txt”.
Further formats will become available later.
Print#
Application developers should firstly instantiate a native UIPrintInteractionController
and pass through a page renderer with ARDKPrintPageRenderer
which has been initialized with the current document.
let printController:UIPrintInteractionController =
UIPrintInteractionController.shared
let pageRenderer:ARDKPrintPageRenderer =
ARDKPrintPageRenderer(document:self.doc)
printController.printPageRenderer = pageRenderer
printController.present(animated: true,
completionHandler: { (printInteractionController:UIPrintInteractionController,
completed:Bool,
error:Error?) in
if error != nil {
print("Print failed due to error:\(error!)")
}
})
UIPrintInteractionController *printController =
[UIPrintInteractionController sharedPrintController];
ARDKPrintPageRenderer *pageRenderer =
[[ARDKPrintPageRenderer alloc] initWithDocument:self.doc];
printController.printPageRenderer = pageRenderer;
[printController presentAnimated:YES
completionHandler:^(
UIPrintInteractionController * _Nonnull printInteractionController,
BOOL completed,
NSError * _Nullable error) {
if (error) {
NSLog(@"Print failed due to error %@", error);
}
}];
Search#
Searching can be made forward or backward from a defined point in the document. Successful searching automatically highlights the next instance of a found string and moves the document selection to that point.
Note
Search is case-insensitive.
let doc:MuPDFDKDoc = self.docViewController.session.doc as! MuPDFDKDoc
// Starts searching the document from the first page
doc.setSearchStartPage(0, offset: .zero)
// search forward from this point for the word "hello" and
// highlight the found occurrence
doc.search(for: "hello",
in:MuPDFDKSearch_Forwards,
onEvent:{event, page, area in
switch event {
case MuPDFDKSearch_Progress:
// If we had a progress indicator, we could set it here according
// to where page is between 0 and self.doc.pageCount
break
case MuPDFDKSearch_Found:
self.updateUI()
// Pan to show the found occurrence
self.docViewController.showArea(area, onPage: page)
break
case MuPDFDKSearch_NotFound:
self.updateUI()
// Could ask the user here whether to restart the search from
// the start of the document
break
case MuPDFDKSearch_Cancelled:
self.updateUI()
break
case MuPDFDKSearch_Error:
self.updateUI()
break
default:
self.updateUI()
break
}
})
MuPDFDKDoc *doc = (MuPDFDKDoc*)docVc.session.doc;
// Starts searching the document from the first page
[doc setSearchStartPage:0 offset:CGPointZero];
// search forward from this point for the word "hello" and
// highlight the found occurrence
[doc searchFor:@"hello"
inDirection:MuPDFDKSearch_Forwards
onEvent:^(MuPDFDKSearchEvent event, NSInteger page, CGRect area) {
switch (event)
{
case MuPDFDKSearch_Progress:
// If we had a progress indicator, we could set it here according
// to where page is between 0 and self.doc.pageCount
break;
case MuPDFDKSearch_Found:
[self updateUI];
// Pan to show the found occurrence
[self.docViewController showArea:area onPage:page];
break;
case MuPDFDKSearch_NotFound:
[self updateUI];
// Could ask the user here whether to restart the search from
// the start of the
break;
case MuPDFDKSearch_Cancelled:
[self updateUI];
break;
case MuPDFDKSearch_Error:
[self updateUI];
break;
}
}];
FileState#
The FileState protocol should be adhered to if an application developer requires to create their own class to handle file operations and open documents using the session method.
This protocol is detailed as follows:
@class ARDKDocSession;
/// Information about a file being opened by the SDK
///
/// The SDK user should provide an implementation of this interface.
/// An example minimal implementation is provided in the sample app.
@protocol ARDKFileState <NSObject>
/// The path to the document to display and edit
///
/// If ARDKSecureFS is in use (i.e. documents are not being stored directly to the device
/// filesystem unencrypted, this would normally be a path that for which ARDKSecureFS_isSecure
/// will return 'true'.
///
/// If ARDKSecureFS is not in use, this should be a path to a file on the device filesystem.
@property(readonly) NSString * _Nonnull absoluteInternalPath;
/// The file type
@property(readonly) ARDKDocType docType;
/// The path which will be displayed within the UI to
/// denote the file being edited. This may be different
/// to absoluteInternalPath for two reasons.
/// The app may be supplying the path to a copy of the
/// file in absoluteInternalPath, and wish to give a
/// displayPath that better represents the location of
/// the original file. Secondly, displayPath may use
/// a more readable start of path (e.g., "Storage/")
/// in place of the true location of the file
@property(readonly) NSString * _Nonnull displayPath;
/// Whether this file can be overwritten. If YES, saving
/// back of edits to the file are not permitted, and
/// the user will need to save to another location. An
/// app might return YES here for document templates.
@property(readonly) BOOL isReadonly;
/// In some use cases, an app may supply a copy of the file
/// to be edited, which will require copying back after any
/// edits have been saved. This property keeps track of
/// whether the original file is out of date with the
/// supplied one, and hence whether copying back may be needed.
/// For apps that supply the original file directly, this
/// property can simply return NO.
@property(readonly) BOOL requiresCopyBack;
/// Information regarding the viewing state of the file (e.g.,
/// which page is being viewed).
///
/// If a FileState with a non-null viewStateInfo is passed to
/// viewControllerForSessionRestoreLastViewingState then the
/// SDK will attempt to restore the file to show the same part
/// of the document that the user was viewing when they
/// previously opened the file.
///
/// The document view will write to this before sessionDidClose is called. A class
/// implementing the ARDKFileState interface can store this
/// value (using its NSCoding interface) against the file name
/// and then arrange to restore it should the same file be
/// reopened.
@property(nullable, retain) NSObject<NSCoding> *viewingStateInfo;
/// Information method called when a session has loaded the
/// first page of the document
- (void)sessionDidLoadFirstPage:(ARDKDocSession *_Nonnull)session;
/// Information method called when the file is opened in the
/// main document view ready for viewing and editing by the user.
- (void)sessionDidShowDoc:(ARDKDocSession *_Nonnull)session;
/// Information method called when a session saves document
/// edits back to the supplied file
- (void)sessionDidSaveDoc:(ARDKDocSession *_Nonnull)session;
/// In some use cases, an app may supply a copy of the file
/// to be edited, which will require copying back after any
/// edits have been saved. This method will be called when
/// copying back may be necessary. For apps that supply the
/// original file directly, and return NO from requiresCopyBack
/// this method need do nothing.
- (void)sessionRequestedCopyBackOnCompletion:(void (^_Nonnull)(BOOL succeeded))block;
/// Information method called when a session ends. In the case
/// that an app supplies a copy of a file to be edited. This
/// method might delete the copy, since the session is no
/// longer using it. The file should NOT be copied back before
/// removal.
- (void)sessionDidClose;
@end
This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at artifex.com or contact Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, CA 94129, USA, for further information.