Sample Obj-C code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API. Learn more about our iOS SDK and PDF Editing & Manipulation Library.
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#import <OBJC/PDFNetOBJC.h>
7#import <Foundation/Foundation.h>
8#include <stdio.h>
9
10//-----------------------------------------------------------------------------------------
11// The sample code illustrates how to read and edit existing outline items and create
12// new bookmarks using the high-level API.
13//-----------------------------------------------------------------------------------------
14
15void PrintIndent(PTBookmark *item)
16{
17 int ident = [item GetIndent] - 1;
18 int i=0;
19 for (int i=0; i<ident; ++i) printf(" ");
20}
21
22// Prints out the outline tree to the standard output
23void PrintOutlineTree(PTBookmark *item)
24{
25 for (; [item IsValid]; item=[item GetNext])
26 {
27 PrintIndent(item);
28 if ([item IsOpen]) {
29 printf("- %s ACTION -> ", [[item GetTitle] UTF8String]);
30 }
31 else {
32 printf("+ %s ACTION -> ", [[item GetTitle] UTF8String]);
33 }
34
35 // Print Action
36 PTAction *action = [item GetAction];
37 if ([action IsValid]) {
38 if ([action GetType] == e_ptGoTo) {
39 PTDestination *dest = [action GetDest];
40 if ([dest IsValid]) {
41 PTPage *page = [dest GetPage];
42 printf("GoTo Page #%d\n", [page GetIndex]);
43 }
44 }
45 else {
46 puts("Not a 'GoTo' action");
47 }
48 } else {
49 puts("NULL");
50 }
51
52 if ([item HasChildren]) // Recursively print children sub-trees
53 {
54 PrintOutlineTree([item GetFirstChild]);
55 }
56 }
57}
58
59int main(int argc, char *argv[])
60{
61 @autoreleasepool {
62 int ret = 0;
63 [PTPDFNet Initialize: 0];
64
65 // The following example illustrates how to create and edit the outline tree
66 // using high-level Bookmark methods.
67 @try
68 {
69 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/numbered.pdf"];
70 [doc InitSecurityHandler];
71
72 // Lets first create the root bookmark items.
73 PTBookmark *red = [PTBookmark Create: doc in_title: @"Red"];
74 PTBookmark *green = [PTBookmark Create: doc in_title: @"Green"];
75 PTBookmark *blue = [PTBookmark Create: doc in_title: @"Blue"];
76
77 [doc AddRootBookmark: red];
78 [doc AddRootBookmark: green];
79 [doc AddRootBookmark: blue];
80
81 // You can also add new root bookmarks using Bookmark.AddNext("...")
82 [blue AddNextWithTitle: @"foo"];
83 [blue AddNextWithTitle: @"bar"];
84
85 // We can now associate new bookmarks with page destinations:
86
87 // The following example creates an 'explicit' destination (see
88 // section '8.2.1 Destinations' in PDF Reference for more details)
89 PTDestination *red_dest = [PTDestination CreateFit: [doc GetPage: 1]];
90 [red SetAction: [PTAction CreateGoto: red_dest]];
91
92 // Create an explicit destination to the first green page in the document
93 [green SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 10]]]];
94
95 // The following example creates a 'named' destination (see
96 // section '8.2.1 Destinations' in PDF Reference for more details)
97 // Named destinations have certain advantages over explicit destinations.
98 char* buf = "blue1";
99 NSData* key = [NSData dataWithBytes: (const void*)buf length: 5];
100 PTAction *blue_action = [PTAction CreateGotoWithNamedDestination: key key_sz: 5 dest: [PTDestination CreateFit: [doc GetPage: 19]]];
101
102 [blue SetAction: blue_action];
103
104 // We can now add children Bookmarks
105 PTBookmark *sub_red1 = [red AddChildWithTitle: @"Red - Page 1"];
106 [sub_red1 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 1]]]];
107 PTBookmark *sub_red2 = [red AddChildWithTitle: @"Red - Page 2"];
108 [sub_red2 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 2]]]];
109 PTBookmark *sub_red3 = [red AddChildWithTitle: @"Red - Page 3"];
110 [sub_red3 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 3]]]];
111 PTBookmark *sub_red4 = [sub_red3 AddChildWithTitle: @"Red - Page 4"];
112 [sub_red4 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 4]]]];
113 PTBookmark *sub_red5 = [sub_red3 AddChildWithTitle: @"Red - Page 5"];
114 [sub_red5 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 5]]]];
115 PTBookmark *sub_red6 = [sub_red3 AddChildWithTitle: @"Red - Page 6"];
116 [sub_red6 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 6]]]];
117
118 // Example of how to find and delete a bookmark by title text.
119 PTBookmark *foo = [[doc GetFirstBookmark] Find: @"foo"];
120 if ([foo IsValid])
121 {
122 [foo Delete];
123 }
124 else
125 {
126 assert(FALSE);
127 }
128
129 PTBookmark *bar = [[doc GetFirstBookmark] Find: @"bar"];
130 if ([bar IsValid])
131 {
132 [bar Delete];
133 }
134 else
135 {
136 assert(FALSE);
137 }
138
139 // Adding color to Bookmarks. Color and other formatting can help readers
140 // get around more easily in large PDF documents.
141 [red SetColor: 1 in_g: 0 in_b: 0];
142 [green SetColor: 0 in_g: 1 in_b: 0];
143 [green SetFlags: 2]; // set bold font
144 [blue SetColor: 0 in_g: 0 in_b: 1];
145 [blue SetFlags: 3]; // set bold and italic
146
147 [doc SaveToFile: @"../../TestFiles/Output/bookmark.pdf" flags: 0];
148 puts("Done. Result saved in bookmark.pdf");
149 }
150 @catch(NSException *e)
151 {
152 printf("%s\n", [e.reason UTF8String]);
153 ret = 1;
154 }
155
156
157 // The following example illustrates how to traverse the outline tree using
158 // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(),
159 // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
160 @try
161 {
162 // Open the document that was saved in the previous code sample
163 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/bookmark.pdf"];
164 [doc InitSecurityHandler];
165
166 PTBookmark *root = [doc GetFirstBookmark];
167 PrintOutlineTree(root);
168
169 puts("Done.");
170 }
171 @catch(NSException *e)
172 {
173 printf("%s\n", [e.reason UTF8String]);
174 ret = 1;
175 }
176
177 // The following example illustrates how to create a Bookmark to a page
178 // in a remote document. A remote go-to action is similar to an ordinary
179 // go-to action, but jumps to a destination in another PDF file instead
180 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
181 // Reference Manual for details.
182 @try
183 {
184 // Open the document that was saved in the previous code sample
185 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/bookmark.pdf"];
186 [doc InitSecurityHandler];
187
188 // Create file specification (the file referred to by the remote bookmark)
189 PTObj * file_spec = [doc CreateIndirectDict];
190 [file_spec PutName: @"Type" name: @"Filespec"];
191 [file_spec PutString: @"F" value: @"bookmark.pdf"];
192 PTFileSpec *spec = [[PTFileSpec alloc] initWithF: file_spec];
193 PTAction *goto_remote = [PTAction CreateGotoRemoteWithNewWindow: spec page_num: 5 new_window: TRUE];
194
195 PTBookmark *remoteBookmark1 = [PTBookmark Create: doc in_title: @"REMOTE BOOKMARK 1"];
196 [remoteBookmark1 SetAction: goto_remote];
197 [doc AddRootBookmark: remoteBookmark1];
198
199 // Create another remote bookmark, but this time using the low-level SDF/Cos API.
200 // Create a remote action
201 PTBookmark *remoteBookmark2 = [PTBookmark Create: doc in_title: @"REMOTE BOOKMARK 2"];
202 [doc AddRootBookmark: remoteBookmark2];
203
204 PTObj * gotoR = [[remoteBookmark2 GetSDFObj] PutDict: @"A"];
205 {
206 [gotoR PutName: @"S" name: @"GoToR"]; // Set action type
207 [gotoR PutBool: @"NewWindow" value: TRUE];
208
209 // Set the file specification
210 [gotoR Put: @"F" obj: file_spec];
211
212 // jump to the first page. Note that pages are indexed from 0.
213 PTObj * dest = [gotoR PutArray: @"D"]; // Set the destination
214 [dest PushBackNumber: 9];
215 [dest PushBackName: @"Fit"];
216 }
217
218 [doc SaveToFile: @"../../TestFiles/Output/bookmark_remote.pdf" flags: e_ptlinearized];
219
220 puts("Done. Result saved in bookmark_remote.pdf");
221 }
222 @catch(NSException *e)
223 {
224 printf("%s\n", [e.reason UTF8String]);
225 ret = 1;
226 }
227 [PTPDFNet Terminate: 0];
228 return ret;
229 }
230}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import PDFNet
7import Foundation
8
9//-----------------------------------------------------------------------------------------
10// The sample code illustrates how to read and edit existing outline items and create
11// new bookmarks using the high-level API.
12//-----------------------------------------------------------------------------------------
13
14func PrintIndent(item: PTBookmark) -> String {
15 let indent = item.getIndent() - 1
16 var i = 0
17 var str = ""
18
19 while i < indent {
20 str = str + (" ")
21 i += 1
22 }
23 return str
24}
25
26// Prints out the outline tree to the standard output
27func PrintOutlineTree(item: PTBookmark) {
28 var currentItem = item
29 while currentItem.isValid() {
30 let indent: String = PrintIndent(item: currentItem)
31 if currentItem.isOpen() {
32 print("\(indent)- \(currentItem.getTitle()!) ACTION -> ")
33 }
34 else {
35 print("\(indent)+ \(currentItem.getTitle()!) ACTION -> ")
36 }
37
38 // Print Action
39 let action: PTAction = currentItem.getAction()
40 if action.isValid() {
41 if action.getType() == e_ptGoTo {
42 let dest: PTDestination = action.getDest()
43 if dest.isValid() {
44 let page: PTPage = dest.getPage()
45 print("GoTo Page #\(page.getIndex())")
46 }
47 }
48 else {
49 print("Not a 'GoTo' action")
50 }
51 }
52 else {
53 print("NULL")
54 }
55
56 if currentItem.hasChildren() {
57 PrintOutlineTree(item: currentItem.getFirstChild())
58 }
59 currentItem = currentItem.getNext()
60 }
61}
62
63func runBookmarkTest() -> Int {
64 return autoreleasepool {
65 var ret: Int = 0
66
67
68 // The following example illustrates how to create and edit the outline tree
69 // using high-level Bookmark methods.
70 do {
71 try PTPDFNet.catchException {
72 let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "numbered", ofType: "pdf"))
73 doc.initSecurityHandler()
74
75 // Lets first create the root bookmark items.
76 let red: PTBookmark = PTBookmark.create(doc, in_title: "Red")
77 let green: PTBookmark = PTBookmark.create(doc, in_title: "Green")
78 let blue: PTBookmark = PTBookmark.create(doc, in_title: "Blue")
79
80 doc.addRootBookmark(red)
81 doc.addRootBookmark(green)
82 doc.addRootBookmark(blue)
83
84 // You can also add new root bookmarks using Bookmark.AddNext("...")
85 blue.addNext(withTitle: "foo")
86 blue.addNext(withTitle: "bar")
87
88 // We can now associate new bookmarks with page destinations:
89
90 // The following example creates an 'explicit' destination (see
91 // section '8.2.1 Destinations' in PDF Reference for more details)
92 let red_dest = PTDestination.createFit(doc.getPageIterator(1).current())
93 red.setAction(PTAction.createGoto(red_dest))
94
95 // Create an explicit destination to the first green page in the document
96 green.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(10))))
97
98 // The following example creates a 'named' destination (see
99 // section '8.2.1 Destinations' in PDF Reference for more details)
100 // Named destinations have certain advantages over explicit destinations.
101 let buf = "blue1"
102 let key = buf.data(using: .utf8)
103 let blue_action = PTAction.createGoto(withNamedDestination: key, key_sz: 5, dest: PTDestination.createFit(doc.getPage(19)))
104
105 blue.setAction(blue_action)
106
107 // We can now add children Bookmarks
108 let sub_red1: PTBookmark = red.addChild(withTitle: "Red - Page 1")
109 sub_red1.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(1))))
110 let sub_red2: PTBookmark = red.addChild(withTitle: "Red - Page 2")
111 sub_red2.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(2))))
112 let sub_red3: PTBookmark = red.addChild(withTitle: "Red - Page 3")
113 sub_red3.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(3))))
114 let sub_red4: PTBookmark = sub_red3.addChild(withTitle: "Red - Page 4")
115 sub_red4.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(4))))
116 let sub_red5: PTBookmark = sub_red3.addChild(withTitle: "Red - Page 5")
117 sub_red5.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(5))))
118 let sub_red6: PTBookmark = sub_red3.addChild(withTitle: "Red - Page 6")
119 sub_red6.setAction(PTAction.createGoto(PTDestination.createFit(doc.getPage(6))))
120
121 // Example of how to find and delete a bookmark by title text.
122 let foo: PTBookmark = doc.getFirstBookmark().find("foo")
123 if foo.isValid() {
124 foo.delete()
125 }
126 else {
127 assert(false)
128 }
129
130 let bar: PTBookmark = doc.getFirstBookmark().find("bar")
131 if bar.isValid() {
132 bar.delete()
133 }
134 else {
135 assert(false)
136 }
137
138 // Adding color to Bookmarks. Color and other formatting can help readers
139 // get around more easily in large PDF documents.
140 red.setColor(1, in_g: 0, in_b: 0)
141 green.setColor(0, in_g: 1, in_b: 0)
142 green.setFlags(2) // set bold font
143 blue.setColor(0, in_g: 0, in_b: 1)
144 blue.setFlags(3) // set bold and italic
145
146 doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("bookmark.pdf").path, flags: 0)
147 }
148 } catch let e as NSError {
149 print("\(e)")
150 ret = 1
151 }
152
153 // The following example illustrates how to traverse the outline tree using
154 // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(),
155 // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
156 do {
157 try PTPDFNet.catchException {
158 // Open the document that was saved in the previous code sample
159 let doc: PTPDFDoc = PTPDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("bookmark.pdf").path)
160 doc.initSecurityHandler()
161
162 let root: PTBookmark = doc.getFirstBookmark()
163 PrintOutlineTree(item: root)
164
165 print("Done.")
166 }
167 } catch let e as NSError {
168 print("\(e)")
169 ret = 1
170 }
171
172 // The following example illustrates how to create a Bookmark to a page
173 // in a remote document. A remote go-to action is similar to an ordinary
174 // go-to action, but jumps to a destination in another PDF file instead
175 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
176 // Reference Manual for details.
177 do {
178 try PTPDFNet.catchException {
179 // Open the document that was saved in the previous code sample
180 let doc: PTPDFDoc = PTPDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("bookmark.pdf").path)
181 doc.initSecurityHandler()
182
183 // Create file specification (the file referred to by the remote bookmark)
184 let file_spec: PTObj = doc.createIndirectDict()
185 file_spec.putName("Type", name: "Filespec")
186 file_spec.put("F", value: "bookmark.pdf")
187 let spec = PTFileSpec(f: file_spec)
188 let goto_remote = PTAction.createGotoRemote(withNewWindow: spec, page_num: 5, new_window: true)
189
190 let remoteBookmark1: PTBookmark = PTBookmark.create(doc, in_title: "REMOTE BOOKMARK 1")
191 remoteBookmark1.setAction(goto_remote)
192 doc.addRootBookmark(remoteBookmark1)
193
194 // Create another remote bookmark, but this time using the low-level SDF/Cos API.
195 // Create a remote action
196 let remoteBookmark2: PTBookmark = PTBookmark.create(doc, in_title: "REMOTE BOOKMARK 2")
197 doc.addRootBookmark(remoteBookmark2)
198
199 let gotoR: PTObj = remoteBookmark2.getSDFObj().putDict("A")
200 do {
201 gotoR.putName("S", name: "GoToR") // Set action type
202 gotoR.putBool("NewWindow", value: true)
203
204 // Set the file specification
205 gotoR.put("F", obj: file_spec)
206
207 // jump to the first page. Note that pages are indexed from 0.
208 let dest: PTObj = gotoR.putArray("D") // Set the destination
209 dest.pushBackNumber(9)
210 dest.pushBackName("Fit")
211 }
212 doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("bookmark_remote.pdf").path, flags: e_ptlinearized.rawValue)
213 }
214 } catch let e as NSError {
215 print("\(e)")
216 ret = 1
217 }
218
219 return ret
220 }
221}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales