Document lifecycle
Lifecycle
SmartOffice documents require a single instance of the SmartOffice SDK library (SODKLib) to be initialized with your required settings for a document session (ARDKDocSession) to commence. Once ready an instance of SODKDocumentViewController should be instantiated with the session and pushed to your navigation controller.
The SmartOffice SDK library (SODKLib)
An example of initializing the SODKLib is as follows:
@interface ViewController ()
@property (strong, nonatomic) SODKLib *sodkLib;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ARDKSettings *settings = [[ARDKSettings alloc] init];
settings.secureFs = [[SecureFS alloc] init];
self.sodkLib = [[SODKLib alloc] initWithSettings:settings];
}
@end
class ViewController: UIViewController {
var sodkLib:SODKLib?
override func viewDidLoad() {
super.viewDidLoad()
let settings:ARDKSettings = ARDKSettings()
settings.secureFs = SecureFS()
sodkLib = SODKLib(settings: settings)
}
}
Once instantiated the SODKLib should remain in memory as a singleton.
The code sample above uses a bespoke class SecureFS as an example. SecureFS would be a class following the ARDKSecureFS protocol. It is the application developer's responsibility to implement this as they see fit to handle an application's file operations.
The ARDKSecureFS protocol
ARDKSecureFS allows a developer to interface with encrypted storage and its protocol is defined as follows:
/// Retrieve file attributes
///
/// Returned dictionary should include the keys:
/// NSFileModificationDate
/// NSFileType
/// NSFileSize
- (NSDictionary<NSString *,id> *)ARDKSecureFS_attributesOfItemAtPath:(NSString *)path {
}
/// Performs a search of the specified directory and returns the paths of any
/// contained items
- (NSArray<NSString *> *)ARDKSecureFS_contentsOfDirAtPath:(NSString *)path {
}
/// Creates a directory at the specified path
- (BOOL)ARDKSecureFS_createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)withIntermediateDirectories {
}
/// Creates a file at the specified path
- (BOOL)ARDKSecureFS_createFileAtPath:(NSString *)path {
}
/// Copies a file or directory to a specified destination
- (BOOL)ARDKSecureFS_fileCopy:(NSString *)src to:(NSString *)dst {
}
/// Deletes a file or directory
- (BOOL)ARDKSecureFS_fileDelete:(NSString *)path {
}
/// Specifies whether a file or directory exists at a specified path
- (BOOL)ARDKSecureFS_fileExists:(NSString *)path {
}
- (id<ARDKSecureFS_Handle>)ARDKSecureFS_fileHandleForReadingAtPath:(NSString *)path {
}
- (id<ARDKSecureFS_Handle>)ARDKSecureFS_fileHandleForUpdatingAtPath:(NSString *)path {
}
- (id<ARDKSecureFS_Handle>)ARDKSecureFS_fileHandleForWritingAtPath:(NSString *)path {
}
/// Renames a file or directory and moves to a specified destination
- (BOOL)ARDKSecureFS_fileRename:(NSString *)src to:(NSString *)dst {
}
/// Returns whether a file or directory is secure at a specified path
- (BOOL)ARDKSecureFS_isSecure:(NSString *)path {
}
/// Denotes whether a file or directory is writable at a specified path
/// If a file or directory is locked this should return false
- (BOOL)ARDKSecureFS_isWritableFileAtPath:(NSString *)path {
}
/// Retrieve file attributes
///
/// Returned dictionary should include the keys:
/// NSFileModificationDate
/// NSFileType
/// NSFileSize
func ardkSecureFS_attributesOfItem(atPath path: String!) -> [String : Any]! {
}
/// Performs a search of the specified directory and returns the paths of any
/// contained items
func ardkSecureFS_contentsOfDir(atPath path: String!) -> [String]! {
}
/// Creates a directory at the specified path
func ardkSecureFS_createDirectory(atPath path: String!, withIntermediateDirectories: Bool) -> Bool {
}
/// Creates a file at the specified path
func ardkSecureFS_createFile(atPath path: String!) -> Bool {
}
/// Copies a file or directory to a specified destination
func ardkSecureFS_fileCopy(_ src: String!, to dst: String!) -> Bool {
}
/// Deletes a file or directory
func ardkSecureFS_fileDelete(_ path: String!) -> Bool {
}
/// Specifies whether a file or directory exists at a specified path
func ardkSecureFS_fileExists(_ path: String!) -> Bool {
}
func ardkSecureFS_fileHandleForReading(atPath path: String!) -> ARDKSecureFS_Handle! {
}
func ardkSecureFS_fileHandleForWriting(atPath path: String!) -> ARDKSecureFS_Handle! {
}
func ardkSecureFS_fileHandleForUpdating(atPath path: String!) -> ARDKSecureFS_Handle! {
}
/// Renames a file or directory and moves to a specified destination
func ardkSecureFS_fileRename(_ src: String!, to dst: String!) -> Bool {
}
/// Returns whether a file or directory is secure at a specified path
func ardkSecureFS_isSecure(_ path: String!) -> Bool {
}
/// Denotes whether a file or directory is writable at a specified path
/// If a file or directory is locked this should return false
func ardkSecureFS_isWritableFile(atPath path: String!) -> Bool {
}
For an example of an implementation of ARDKSecureFS please see the SecureFS class in the sample iOS project.
The document session
The document session requires three objects:
- A file state object ( an instance of an object adhering to the
ARDKFileStateprotocol ) - The
SODKLibinstance - An instance of
SODKDocumentSettingsfor document options in the SmartOffice SDK UI
@interface ViewController ()
@property (strong, nonatomic) SODKLib *sodkLib;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/// 1. create the file state instance with the document you want to load
FileState *fileState = [FileState fileStateForPath:@"my-document.docx"];
/// 2. create the SODKLib instance
ARDKSettings *settings = [[ARDKSettings alloc] init];
settings.secureFs = [[SecureFS alloc] init];
self.sodkLib = [[SODKLib alloc] initWithSettings:settings];
/// 3. create the document settings
SODKDocumentSettings *docSettings = [[SODKDocumentSettings alloc] init];
[docSettings enableAll:YES];
/// Ready - now create the document session
ARDKDocSession *docSession = [SODKDocSession
sessionForFileState:fileState
ardkLib:self.sodkLib
docSettings:docSettings];
}
@end
class ViewController: UIViewController {
var sodkLib:SODKLib?
override func viewDidLoad() {
super.viewDidLoad()
/// 1. create the file state instance with the document you want to load
let fileState:FileState = FileState(path:"my-document.docx")
/// 2. create the SODKLib instance
let settings:ARDKSettings = ARDKSettings()
settings.secureFs = SecureFS()
sodkLib = SODKLib(settings: settings)
/// 3. create the document settings
let docSettings:SODKDocumentSettings = SODKDocumentSettings()
docSettings.enableAll(true)
/// Ready - now create the document session
let docSession:ARDKDocSession = SODKDocSession(fileState:fileState,
ardkLib:sodkLib,
docSettings:docSettings)
}
}
The ARDKFileState protocol
ARDKFileState handles access to cloud storage, copying to local storage and any copying back to cloud storage that might be required.
A bespoke file state class which adheres to the ARDKFileState protocol should be instantiated by an application developer. The ARDKFileState protocol is defined as follows:
/// The path to the document to display and edit
@synthesize absoluteInternalPath;
/// The file type
@synthesize 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
@synthesize 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.
@synthesize 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.
@synthesize requiresCopyBack;
/// Information regarding the viewing state of the file (e.g.,
/// which page is being viewed). The document view will ensure
/// this is valid when sessionDidClose is called. A class
/// implementing the ARDKFileState interface can record this
/// value (using its NSCoding interface) against the file name
/// and then arrange to restore it should the same file be
/// reopened.
@synthesize viewingStateInfo;
/// Information method called when a session has loaded the
/// first page of the document
- (void)sessionDidLoadFirstPage:(ARDKDocSession *)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 *)session {
}
/// Information method called when a session saves document
/// edits back to the supplied file
- (void)sessionDidSaveDoc:(ARDKDocSession *)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 (^)(BOOL))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 {
}
/// The path to the document to display and edit
var absoluteInternalPath: String!
/// The file type
var docType: ARDKDocType = SODKDoc.docType(fromFileExtension: "")
/// 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
var displayPath: String!
/// Whether this file can be overwritten. If TRUE, saving
/// back of edits to the file are not permitted, and
/// the user will need to save to another location. An
/// app might return TRUE here for document templates.
var isReadonly: Bool = false
/// 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 TRUE.
var requiresCopyBack: Bool = false
/// Information regarding the viewing state of the file (e.g.,
/// which page is being viewed). The document view will ensure
/// this is valid when sessionDidClose is called. A class
/// implementing the ARDKFileState interface can record this
/// value (using its NSCoding interface) against the file name
/// and then arrange to restore it should the same file be
/// reopened.
var viewingStateInfo: (NSCoding & NSObjectProtocol)!
/// Information method called when a session has loaded the
/// first page of the document
func sessionDidLoadFirstPage(_ session: ARDKDocSession!) {
}
/// Information method called when the file is opened in the
/// main document view ready for viewing and editing by the user.
func sessionDidShowDoc(_ session: ARDKDocSession!) {
}
/// Information method called when a session saves document
/// edits back to the supplied file
func sessionDidSaveDoc(_ session: ARDKDocSession!) {
}
/// 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 TRUE from requiresCopyBack
/// this method need do nothing.
func sessionRequestedCopyBack(onCompletion block: ((Bool) -> Void)!) {
}
/// 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.
func sessionDidClose() {
}
For an example of an implementation of ARDKFileState please see the FileState class in the sample iOS project.
SmartOffice document settings (SODKDocumentSettings)
These document settings control what is available via the default UI in SmartOffice SDK. In the simplest case an application developer can simply enable all the features in the UI.
SODKDocumentSettings *documentUISettings = [[SODKDocumentSettings alloc] init];
[documentUISettings enableAll:YES];
let documentUISettings:SODKDocumentSettings = SODKDocumentSettings()
documentSettings.enableAll(true)
The full set of UI settings are defined as follows:
@property (nonatomic, weak) id<ARDKDocumentSettingsFeatureDelegate> _Nullable featureDelegate;
/// Whether the save button appears on the document File ribbon
@property (nonatomic) BOOL saveButtonEnabled;
/// Whether the 'save to' button appears on the document File ribbon
@property (nonatomic) BOOL saveToButtonEnabled;
/// Whether document editing is enabled
@property (nonatomic) BOOL editingEnabled;
/// Whether the user is allowed to print documents
@property (nonatomic) BOOL printingEnabled;
/// Whether the user is allowed to securely print documents
@property (nonatomic) BOOL securePrintingEnabled;
/// Whether the user is allowed to insert photos from the camera into documents
@property (nonatomic) BOOL insertFromCameraEnabled;
/// Whether the user is allowed to insert images from the gallery into documents
@property (nonatomic) BOOL insertFromPhotosEnabled;
/// Whether the user is allowed to edit PDF annotations
@property (nonatomic) BOOL pdfAnnotationsEnabled;
/// Whether the user is allowed to perform PDF redaction
@property (nonatomic) BOOL pdfRedactionEnabled;
/// Whether the user is allowed to fill PDF forms
@property (nonatomic) BOOL pdfFormFillingEnabled;
/// Whether the app should show PDF forms filling options
@property (nonatomic) BOOL pdfFormFillingAvailable;
/// Whether the app should show PDF redaction options
@property (nonatomic) BOOL pdfRedactionAvailable;
/// Whether the user is allowed to sign PDF forms
@property (nonatomic) BOOL pdfFormSigningEnabled;
/// Whether full-screen mode is supported
@property (nonatomic) BOOL fullScreenModeEnabled;
/// Whether dark-mode affects document content
@property (nonatomic) BOOL contentDarkModeEnabled;
/// The date and time after which the document may no longer be viewed or
/// edited, the document is closed as the default action when expires.
/// If expiresPromptBlock property is set then the block is called instead of
/// closing the document
@property (nonatomic) NSDate * _Nullable expiresDate;
/// A block to prompt the app to close the document.
/// If this is set, it is called instead of closing the document when the time
/// expires and if closeDocBlock is called then the document is closed
@property (nonatomic, copy, nullable)
void (^expiresPromptBlock)(UIViewController * _Nonnull presentingVc,
BOOL docHasBeenModified,
void (^ _Nullable closeDocBlock)(void));
/// Tells whether it has expired
/// - YES if expiresDate is set and expired
@property (nonatomic, readonly) BOOL expired;
/// Use this to enable or disable all settings
- (void)enableAll:(BOOL)enable;
Opening a document
SmartOffice SDK view controller
After adhering to the initial SDK protocols and creating any required bespoke classes you should be ready to create your SmartOffce document view controller with the initialized document session.
Create a SmartOffice document view controller with the document session and the page you want to view, and then push it to your navigation controller as follows:
ARDKDocumentViewController *vc = [SODKDocumentViewController
viewControllerForSession:docSession
openOnPage:0];
[self.navigationController pushViewController:vc animated:NO];
let vc:ARDKDocumentViewController = SODKDocumentViewController.viewController(for: docSession,
openOnPage: 0)
self.navigationController?.pushViewController(vc, animated: false)
