Why this app?
While developing the Remote Control Flight Log app I reached a point where I had a reasonable amount of data saved but no way to let the user output it. One of the requirements of the app was to be able to get the data in report format and that wasn't possible.
I had a dig around the net, looking for reporting libraries for iOS but failed miserably to find anything. Not just anything usable but anything at all. Maybe I was looking for the wrong thing, but it seems that producing hardcopy from an app isn't catered for.
That's where PDFTools was created. I first looked into using MarkDown, but I wanted images and I wanted pagination that was under my control. MarkDown provided almost all of my needs, but not the pagination and the support for embedded images seemed inconsistent.
I made the decision to create PDFTools to give me a set of helper functions to directly create PDF files. This is the resulting framework.
Key Learning Points
What did I want to achieve?
There were a few tutorials on using the Apple supplied PDFKit framework, but they largely concentrated on very simple documents and didn't deal with pagination at all. They also didn't delve in to how to componentize the code into a format suitable for a framework. So, my key aims were:
- Creating a public interface to PDFKit that could be used in a consistent way from many apps.
- Building an API that allowed PDF documents to be created declaratively.
- Creating a PDF Viewer to print or export my PDFs.
The framework is still evolving, but I have managed to create sufficient functionality to satisfy the needs of the Remote Control Flight Log. As I extend the needs of the flight log, I will continue to evolve the framework.
What is in it
And the end result is...
And this is what I ended up with. There are many sharable views and it does not seem sensible to document everything here in great detail. So, here's an overview of what we have.
It's kind of hard to show the library, so I've uploaded a couple of the reports I have created for the flight log.
The declarative language is pretty simple. To create a document, you declare the objects that are going on the page and add them to the document. If the objects you are adding won't fit on the page, the code throws a new page.
At the time of writing, the elements you can declare are:
- Throws a new page. You can optionally specify a parameter that will only throw the new page if there is less than a specified amount of space left on the page.
- Horizontal position on the page is controlled by setting the margins. The vertical position is set by changing the cursor position. Creating a PDFSetCursor element allows you to set the vertical position on the page. It's useful, for example, to skip space at the start of the document.
- Adds vertical space to the cursor. You might, for example, want to add spacing between sections. This can be done by adding a PDFSpacer element.
- Draws a line between two points on the report. You can specify the thickness of the line as well as it's location. By default, if you do not provide a location, it will be drawn horizontally across the page at the current cursor position.
- Draws a filled box on the page. As with PDFLine, you can specify location and size. You can also specify the fill colour.
- Outputs a paragraph of text. Formatting is controlled using pre-defined styles, so you can output a "Heading1" or a "Title" or just normal text. For pagination purposes, the paragraph is split at newline characters allowing a 'paragraph' to span over page boundaries.
- Similar to PDFParagraph except that the output is in two columns. You are allowed to specify the width of the first column and the second takes up the rest of the page width.
- Renders an image on the page. You can specify the location and the size of the image you want rendered and the image is passed as a standard UIImage.
Am I really any good?
Don't take my word for my abilities, take a look at other peoples opinions about me.
One very quickly runs out of superlatives with Steve. He is the cleverest person I know. He is highly innovative, passionate regarding the proper maintenance of agreed standards and protocols and establishes excellent relationships with our clients.
Steve is a rare developer resource who is able to provide a good breakdown of technical solutions for all audiences to understand... Steve understands the importance of project deliverable's both from a client and business perspective and shows a personal pride in ensuring the delivery schedules are met.
I have worked closely with Steve for his time with us and long before we formed our company. His technical ability far out-performs anyone I have known or met in companies we have worked with like IBM/EDS/Cap Gemini
Steven showed a great deal of commitment and skill when he worked with me. His attention to detail, comprehensive documentation and well thought out code, using very impressive technical standards meant that it was always possible to rely on the solutions provided being top notch. Steven is an asset to any company, at any level - if I were able to, I'd love to work with him again.
I have had the pleasure of working with Steven for several years in my role as CTO. He his one to the most multi-disciplined technically skilled developers I have known but what sets him apart is his eye for, and attention to detail, particularly when considering the user experience. I would absolutely not hesitate in recommending Steven.