Advances in AirPrint

Session 711 WWDC 2013

AirPrint is the iOS and OS X printing system, a revolutionary printing architecture that makes printing easy for users and app developers. Learn all about AirPrint, how it has grown, and best practices for adding printing to iOS apps.

[ Silence ]

Howard Miller: Okay welcome to the WWDC 2013 AirPrint Session.

I'm Howard Miller.

I manage everything that's related to AirPrint.

How many people here are iOS developers?

Show of hands, alright.

How many of your apps already print?

A few of you, okay.

If they don't print, by the time you leave today, your app should be printing via what we tell you here or the lab that immediately follows this.

Today's agenda, I'm going to talk about AirPrint, the success that we've had in AirPrint and the market.

We're going to focus a little bit on AirPrint in the Enterprise.

We've got a lot of new printers that have come to market that I think will solve a lot of enterprise issues.

And then we're going to spend the majority of today's session helping you and your app be able to print.

So let's start with the printing architecture.

Apple has a long tradition.

We invented desktop publishing back in the 80's with the Introduction to PostScript, the original LaserWriter, partnership with Adobe.

With Mac OS X we brought in a full featured rich printing system, two sets of API's, high level API's for your applications, some low level cups API's.

We've built in the most robust printing system in the world, the common Unix Printing System.

And as you know there's a myriad of printer drivers that are available to talk to tens of thousands of printers.

We adapted this system to eliminate the need for drivers.

We built a new printing standard, which we call AirPrint, which well, you know marketing called it AirPrint.

It does work on wireless but it also works on Ethernet and starting next year it will work on USB as well.

This provided a very rich and complete printing system though because of its history may be a little bit complicated for application developers.

So what we have done is for iOS we've brought over the best of the printing system, we've put a thin layer of API's that get to the essence of what your app needs to do to print and to print well.

So with a minimum amount of code, maybe 10 lines of code if you already have predefined content such as PDF or JPEG, you can get desktop quality output from your application.

Okay if you want to do a little bit more we still have the full richness and powerful printing system underlying you and you can get desktop quality output and all the level of control that you would expect from your application using the AirPrint API's.

So let's talk a little bit about the technology.

When we came to iOS the goal was pretty straight forward, what is the best that we can do for the user?

Printing has been a pain, it's been a pain since the dawn of time when they were carving them on stone tablets and putting them in pyramids.

Printing is hard and it doesn't have to be hard.

So our goal is to have the best quality output with the least amount of friction for the end user.

And to that end we've completely eliminated drivers, no software to install, there's no setup, there's no settings, there's no tweaking, the right thing happens.

You get full quality output and now for you application developers we ask you to be a partner in this.

So for example, if your app is a photo app, when you print your photo, it's nice, that's sort of required, that you tell the printing system, yes it is my intent to be printing a color photo.

That will let us optimize the printing path and the settings in the printer so the user will get the full quality output, full bleed, edge to edge, correctly matched with color, pulled from the right tray without having to pick anything.

AirPrint was released in iOS 4.2 so iOS 4.2 and later will support that.

It's also on OS X starting in 10.7, became our default in 10.8 and continues in Mavericks.

If a customer comes across an AirPrint printer it will just appear in their print dialogue on either platform, they pick it and they print.

It's all standards based.

Of course we put some Apple secret sauce on top of that.

But yet everything that we've done is available under license at no cost to all printer manufactures and starting last year server manufacturers.

So we have a few printer manufacturers that have adopted AirPrint.

Just this week you saw announcements from Xerox and Kyocera, both bringing midsize business and enterprise class printers to market with AirPrint in them.

You'll notice all of your favorite vendors probably are on this slide.

We have a list of licensees, some of which I will talk about as we go through today's presentation.

This list of licensees that I show you have printers that have AirPrint and are currently with Apple under certification.

If you want to know is your printer an AirPrint printer, we have this AirPrint basics knowledge base article which turned out to become one of the 10 most popular knowledge base articles in Apple's history, this has the definitive list.

For a printer to be on this list, first the vendor has to have a license, second they have to have provided working functional prototypes to Apple when we run a complete certification sweep.

So this is a pretty good definitive source if you want to find out what's there.

So new printers for 2013 so we're going to start with a couple of my favorites.

Roll fed printers, there's a myriad of roll fed printers in the industry.

You see them everywhere.

We have, and we'll demonstrate it later, this is a Brother Label Roll fed printer.

It will come to market later this year.

Actually it's a firmware update for an existing printer.

Awesome printer and we're going to demo it live with some demo code.

I hold in my hand this which is an iPhone 5 panorama.

This was taken recently and this has been printed on a printer from ZINK.

For those who know ZINK, ZINK stands for zero ink.

Their patented technology lets the customer just buy paper and always have ink available.

This roll fed is 2 inches by 9 inches.

It's a beautiful California scene.

And for those in the back who can't see it, we have a slightly larger version.

This one is 160 some odd inches by 36 inches.

This has been printed using AirPrint off of shipping HP Designjet T520.

That roll fed printer came out earlier this year with AirPrint and HP's bringing AirPrint to many other Designjet printers.

Okay thank you guys.

I mentioned the enterprise class, laser printers, one of the preeminent printers in the enterprise space has been Lexmark.

Lexmark makes a wide array of laser printers.

Every printer sold by Lexmark is AirPrint certified, AirPrint enabled today.

They also have enterprise classes on some of their printers where you set your printer up in your shop, you connect it to your active directory server, that printer will then present itself to iOS users supporting users in groups, IPPS, using TLS for security so encrypted data channels.

You get all the functionality, all the capability and all the security that you would expect in an enterprise class printer.

So those are available from Lexmark.

Many of the other vendors, HP, the Ricoh and the Ricoh family, I mentioned Kyocera and Xerox, there's a lot of printers made for the Enterprise class.

Label printers, I mentioned Brother already, Dye Sub printers, again I don't have big ones of these so you won't be able to see them in the back, but these printers are off of a Cannon Selphy Dye-sub Printer, also in certification and will also be available later this year.

I think this will be the must have Christmas peripheral because straight from your iPhone with two clicks you get production quality, color photos, there's tabs on it so it comes out borderless, right from your iPhone.

And then we will see later this year our first round of certified servers.

Yes, these will be the first AirPrint certified servers in the world.

The first one we expect will probably be from Lexmark.

They're bringing their Enterprise class print and release capability and the full server capability for printing.

They're going to add AirPrint right on top of that and you'll be able to print to all of their printers plus other third party printers.

So let me drill down just a little bit into the Enterprise, I think I've talked about this.

AirPrint itself uses Bonjour for discovery which works great in the home.

We're a small network.

You see the printers there immediately available so you pick it and you print.

AirPrint from the beginning is also supported static DNS entries for printers.

So you can define all of your AirPrint printers and your DNS server and for whatever search domain your users using they will get a list of printers that are available and reachable so you can print across the internet with AirPrint today.

New in iOS 7 we've added iOS profile support so from the Apple Configuration Utility and it's all documented so hopefully third party utilities that create profiles, you'll be able to define AirPrint printers and your users will be able to print to them from any place in the world.

AirPrint natively supports IPPS which secure IPP with TLS and we support users in groups.

We've also added some higher end features to laser printers.

In Mavericks you will find that if an AirPrint printer is selected we support all the finishing options that one would expect, fold, staple, three hole punch, jog, output.

If you have a server, this Lexmark server I'm talking about, and servers from other manufacturers, print and release will become a standard feature.

You can print from your phone, go to your printer, type in your code or put your badge on the printer, see your print jobs and release them at the printer.

And there's also native support for quotas now built in.

So let's talk about OS X printing.

We have all these great features in AirPrint and if you're an OS X developer there's a few things that you need to know, well really you don't need to know anything.

All of these changes are immediately available to the user.

There's no new API's, there's no new code changes at all in OS X.

iOS, which hopefully is why most everybody is here, we have created what we think is a really simple way to print but to get really great quality out there.

So I've got just a couple things I want to mention.

On other platforms it's acceptable to just sort of screen scrape and drop that to the printer.

On our platform that's not what we are about.

We want full quality, desktop quality output.

We want you to use the space that you would have available on paper and bring the information to bear that a customer would want to see on an 8 1/2 by 11 piece of paper or even larger.

It's not about a little screen at that point.

It's about what the user is going to need when they get themselves to paper.

So you should be able to enhance your content.

You should be able to draw everything at print time in high quality and you should be able to use the real estate.

So the example that I always like to use is Maps.

And you've seen this on an iPhone 5.

It's gorgeous.

It's got a bunch of exciting features, turn right, turn navigation and they've even fixed a lot of it so it takes you to the right place.

On the iPad there's more real estate.

You get more maps.

There's more interesting things that they could bring.

But when you go to paper, you don't have the phone telling you to turn by turn and you have a lot more pixels to bring to bear.

So on paper they show you the same view so you can see where you're going but they also give you the turn by turn on the side.

There is example after example of this, web browsers where you see all kinds of stuff but when you print you get the article of interest, receipt point of sale programs where it's an entry for buying stuff on the iPad but when you hit print you actually get an itemized receipt with the address of the return procedures printed on the bottom.

So we expect your apps to look at print as a larger output form and a static output form, the thing that somebody's going to fold up and put in their pocket or put in their binder.

Take advantage of that space.

Okay so for printing we have two ways for you to print, I kind of mentioned this.

If you already have pre-formed content, a JPEG or any other image format supported on the platform or PDF, 10 lines of code, we'll take care of the rest.

You'll tell us what your intent is for the category of output of photo or general document or some others and we will make all the right settings and get the right output for the user.

If you don't already have a PDF it's a long way around the horn to go and create a PDF to hand it to the printing system.

So in those situations we'd like your app to do fine grain drawing at print time.

And we have a couple of different classes that are set up that will make this structured and simple for you.

And to show you all those details I'm going to bring up Todd Ritland.

And he is going to go through the API's and give us a demo showing you how to make your app print.

Thank you, Todd.

[ Applause ]

Todd Ritland: I'm Todd Ritland, AirPrint Engineer.

So let's talk about some iOS printing stuff here.

So first I'm going to talk about picking what to print.

We're going to go over the API.

We'll talk about your different UI options for ways to present the printing UI.

We'll talk about some new types of printers like Howard mentioned, roll fed and label printers, and we'll do a demo roll fed sample app.

So first it's important to keep in mind that iOS printing is easy.

It was designed to be really easy for users with a simple UI and it's actually really pretty simple for you as a developer to add printing to your app.

But first the most important part of printing is providing really good content, as Howard mentioned.

The best apps provide useful, attractive, high quality output.

It's best to think of this as like high end graphic design.

I recommend kind of designing your output first and then using the classes to actually make it happen instead of approaching it the other way around.

As Howard mentioned, what looks good on screen doesn't always look good on paper.

Make use of the dynamic printing system.

The paper size can actually be anything.

A lot of people don't realize but there are two major paper sizes in the world for documents, A4, which is taller and thinner then letter, and letter, what we use in the United States.

The iOS printing system will figure out the correct one to use and your app needs to be dynamic about the way it lays out its content to best fit.

If you're expecting US letter and you get A4 which is narrower you might get your content clipped off on the sides and you have a huge market of people that their output is not going to look right.

Printers also have paper size sensors.

A lot of new printers, all future AirPrint printers, will have paper size sensors so whatever the user actually has loaded in the printer, iOS will dynamically figure that out and pass it on to the app so the best apps are dynamic about the way that they load up their content.

Printer hardware margins also vary quite a bit.

A lot of Inkjets that do duplexing need a bunch of space at the bottom to hold on to the page so you might have a really big margin at the bottom or margins on the left and right and top can be any number of things so apps that are dynamic make sure that their content won't get clipped.

So for all these reasons it's best not to just produce a fixed sized PDF and hand it to the printing system.

We've built classes for you to be dynamic.

So a really good example of this is Bloomberg for iPad.

So here we're looking at an article about the new spaceship campus at Apple.

And if you print this out, this is the output you get.

We have a nice title at the top.

It has the Bloomberg logo.

There's you know the picture has a caption, we have footers at the bottom that tell us what page we're on and nice margins on the side.

And if the user actually has US legal, which is a taller paper loaded in the printer, the Bloomberg app will be dynamic about things and it will make the content larger.

In this case we can print the whole thing in just one page.

So we'll go over some of the API's here.

The basic steps are first your app will get the printer controller or the activity controller if you're using the share sheet.

You'll set up the attributes for the job like the type of job that it is, the job name.

You'll provide content and then you'll present the UI.

At this point iOS will present the user interface.

The user can select the printer.

iOS will communicate with the printer, figure out all the relevant information.

The daemon will take over managing the jobs.

The user can cancel it.

If it's a print release job we'll hold on to the job.

You know all these things you don't have to manage in your app.

So here's the basic classes that we'll be using.

I'll just briefly go over them now and then we'll go on to some of these in more detail.

First we have UIPrintInfo which is basically what you use to put those attributes for the job like orientation, the job name, the type of job.

UIPrintPaper, just basically represents the paper at the printer.

We have a print formatter which formats content to be put onto the page.

Print page renderer which lets you take full control over the drawing.

For the UI we have UIPrintInteractionController which is the main printing UI and UIActivityController which is the share sheet, essentially.

So first let's talk about UIPrintIinfo.

First you'll set the job name.

Now this is really important.

It's shown in the UI print center when the user's managing the job.

It also gets shown on the front panel of a lot of printers.

This is the way the user is going to identify your job.

Howard mentioned servers, for print and release situations and stuff, users will be identifying their job by the job name so it needs to be really specific and something that the user would actually be able to find.

Next a really important one is output type.

This is how you'll tell the printing system the type of content you're printing.

We'll change the default paper size.

We'll pick a correct print quality mode.

And we'll show the appropriate UI based on the content that you tell us.

So we have four of these.

The first one is just a general document.

Safari is an example of this.

It's just mixed text and graphics.

We'll choose a document size like A4 or letter, depending on the region.

Duplex control will be allowed and page range control, things you would expect from a document.

And we choose normal quality.

Next a very similar one is document Grayscale.

This is monochrome text and graphics.

Now you can choose this and we'll optimize things so that the data over the network is lower.

We'll tell the printer to print it using just its black ink so it can save the user some ink.

And just like the previous example, duplex and page range is allowed.

Next we have photo.

This is you know printing photos.

Users want high quality, borderless and when we show the UI, when you tell us that you're printing a photo, we won't show the duplex control or page range because these don't make sense for a photo.

And new in iOS 7 we have UIPrintInfoOutputPhotoGrayscale.

So similar to the last one where we have photo paper sizes we'll choose the photo tray, if the printer has one, borderless, but we'll actually tell the printer to print this in high quality Grayscale.

Some printers that are like high end Cannon printers have a bunch of gray inks and really excellent gray quality printing and we'll tell the printer to use that if you choose this output type.

Okay so that's UIPrintInfo.

Next we'll go over UIPrintPaper.

It's basically just the size of the page at the printer and then inside of that we have the printable area.

This is the size minus the hardware margins of the printer, the area where the printer can't print because you know it can't shoot its laser or the print head can't move towards it.

Next we'll talk about providing content.

As Howard mentioned, there's basically two types of printing, you either have items like PDF's and images that already exist or you're going to be creating your pages dynamically.

If you're creating pages dynamically you'll use these formatters and renderer classes that I've mentioned.

If you already have content like PDF and images, you don't use these things.

So the easy example is printing items.

It could be a single item or you can actually send an array of items like an array of photos for example that the user selects in a bunch of photos.

This could be JPEG's or any image type that iOS understands.

These can be in the form of NSURL's, file URL on disk or elsewhere, it could be in memory in the form of NSData or a UIImage or CI image or it could be something in the photo library in the form of an ALAsset or ALAssetURL.

If you provide an array of items, each one will be a separate job.

So here's all the code that you would need to print a PDF.

First we'll ask the UIPrintInteractionController if it can print the URL.

This is a method that gets the URL to a PDF file.

Examples when it wouldn't be able to print it are if the PDF had password protection or if it was malformed in some way and the UIPrinterActionController actually can tell you if it can be printed.

Next we'll grab the shared UIPrinterInteractionController.

It's a shared object so you don't initialize it.

You just grab the shared one.

We'll set the printing item property to be the URL of our PDF file.

We'll set up a UIPrintInfo.

Those are the attributes for the job so we'll initialize the UIPrintInfo.

We'll set the output type to be output general.

This makes sense for PDF because PDF typically have, you know, photos in them or other color content plus text.

We'll set the job name to be name of the file.

And then we'll set the controllers print info property to be the print info we just created.

We'll tell the controller to turn on the page range control.

By default it doesn't show the page range control.

But when our user's printing a PDF they're probably going to want to be able to choose a page range inside of the page, I mean inside of the PDF and then we'll just present.

So that's all that it takes to print a PDF.

At this point the iOS will take control of everything else.

If the printer has a bunch of trays and we actually notice that the PDF file matches exactly one of those trays like say it's an 11 by 17 PDF, we'll choose the right tray, everything will just happen magically.

[ laughter ]

Okay so formatters, if you're actually formatting content or rendering content dynamically, formatters are the first thing to get to know.

Now what exactly is a formatter?

Formatter basically takes some data in your app and some rectangle on a printed page and it figures out how to format that for printing.

That's just in the abstract sense here.

So an example of this would be string of text, we use a simple text formatter.

The simple text formatter will just take that string, it will figure out how best to put it into the rectangle and it will format it.

It will figure out the line breaks, line spacing, you can set font, color, things like that.

Now all of this text doesn't actually fit in this rectangle so a formatter knows that it needs to continue on to the next page.

So you can use a formatter directly if all you're doing is formatting the content.

You can use it with UIPrintInteractionController or you can add it to the array of activity items if you're using the share sheet.

You can also use formatters as a helper in a full renderer and we'll go over that later.

For plain text, as I mentioned you can use UISimpleTextFormatter, you can specify font, color, alignment like center, left, justified.

For HTML we have a really handy markup text formatter and that knows how to layout your HTML according to all the HTML rules on a page.

So by default a formatter uses the printable rect inside of the page which is the area that's printable but some printers have really small margins, some printers can print you know up to 1/10 of an inch to the edge of the page and so that's not probably ideal so that's why we have content insets.

You can specify area inside the printable rect, left, right and top.

Upper page renderer will just keep rendering the content until it uses up all the content so the bottom content inside is ignored.

So here's an easy example of using a formatter to print some HTML text.

Here we just create our UIMarkupTextFormatter.

We're initializing it with the HTML text that was provided into this method.

And then we set the URIPrinterAction ControllersPrintFormatter property to be our formatter.

So this is all that it takes to print some HTML text onto a page.

And we set up our UIPrintInfo, general, job name and so on and then we present.

Now all of viewers actually have print formatters so a lot of times you don't need to create a formatter yourself.

In this case we have a web view in our app.

Instead of initializing our own print formatter we can just grab the view print formatter from our web view.

Another view that this is really useful for is a map view, if you need to format map content to put onto a page, you can just grab the ViewPrintFormatter from the map view.

Okay so that's formatters.

Next, page renderers.

Now renderers you can use, they're completely control content.

This is total custom printing.

What is a renderer exactly though?

Here's our renderer class.

It needs to know the number of pages it's going to print.

And then the system basically asks it to draw each page.

It says you know draw first page and it goes and draws.

It can use any of the screen drawing methods, you know it can use cores.

If you want to have find viewing control over text you can use core text.

Basically anything you print to screen you can use.

So we have full drawing control.

It will calculate the page count and then draw the page contents.

The class also has capability to add space for headers and footers and for more information on that you can take a look at the developer documentation or come to our lab later and you can add formatters.

Now what does a renderer with a formatter look like?

Well here we have our render object.

It's told to draw a page.

In this case it's just drawing some accents at the top and bottom of the page.

Then the area in the middle we want to put some text.

So the render has a simple text formatter.

Once it's done drawing the outside part it will use the UI simple text formatter to draw our Gettysburg Address here.

So you can see how you can kind of combine these things together.

You can think of the renderer as kind of the captain that's controlling everything.

It can kind of draw using any method possible and a renderer is just one of those tools that it can use.

So you'll subclass UIPrintPageRenderer.

At a minimum you'll override number of pages and drop content for page and index.

You can also override draw header for content, draw header for page and index and draw footer for page and index and some other things.

So you'll set, if you're using with a print interaction controller, you'll set the print page renderer property to be the instantiated object that you just created of your custom print page renderer.

Or you can add that object to the array of items when you are creating a UIActivityViewController when you're doing the view share sheet.

To use formatters you'll actually create your formatter object and then you'll call add, print formatter, starting at page index.

Formatters can start at any page.

Now showing UI, we have a couple different options for showing UPrintUI.

As I've mentioned we have printing from the share sheet.

This is probably where most people I think expect printing.

This is where it appears in most of the built in iOS apps.

And you also get other things like AirDrop, a cool new feature.

So to add printing to a share sheet, if you're sharing something like in this case we're sharing our URL text and UI will figure out all the different sharing items that should be shown.

But if the user is sharing a web page and they're printing, they're probably going to want the actual web page printed out.

So here we're actually adding a renderer to our activity items and we can add our print info which has our job name and output type.

So we just create that array and we set, when we create our UIActivityViewController we just set the activity items to be those items and present using standard present methods.

Now if you're printing using a print button that goes right into the printing UI, that's when you'll be using UIPrintInteractionController.

On iPhone you just imply call presentAnimated: completionHandler on iPad.

It will be a pop over so you'll be calling presentFromRect or presentFromBarButtonItem.

Now if you're printing as a menu item, in this case pages, we have an embedded printing control inside of your control, you'll set your class as a delegate for the shared UIPrinterActionController.

Your class will implement printInteractionController ParentViewController.

The printer action controller will call this to figure out what its parent view controller is.

Then when the user taps print you'll call presentAnimated: CompletionHandler.

And if your parent view is the UINavigationController it will get a push, and that is what the case is I'm showing here, if it's a ViewControl it will get a modal presentation.

You'll have access to the object but just don't peek at it because everything inside of it is subject to change at any time.

If you need control over paper size like pages, for example, at the document center gap where the user is designing their layout with the page in mind, we also have capabilities to do that and so first you'll design your UI for the user to select the page.

And you'll use the delegate method, print interaction controller choose paper.

There'll be an array of papers that get passed into this and your delegate is responsible for picking the one to use.

This gets called after the user has selected the printer, iOS communicates with the printer to figure out what sizes are available and then some printers have paper size sensors, like I mentioned, that can tell the types of papers that are at the printer.

The array that gets passed to your app will actually be those papers that are available at the printer in that case.

So this array of papers that gets passed to you could be a lot of different things but you'll be responsible for selecting it.

So here's an example of that.

Here we're just creating a paper size, CGSize that's just basically 8 1/2 by 11.

We'll use UIPrintPaper's best paper for page size method so we provided this as a great way for matching because paper matching is actually pretty complicated if you want to find the closest match so we've provided this for you and we recommend that you use this.

Next we have roll paper, this is what Howard mentioned, and this is new in iOS 7.

Basically you'll use the delegate method, print interaction controller, cut length for paper.

So this works pretty similarly to the choose paper but in this case you're passed in a UIPrintPaper.

Once the user selected a printer that has a roll loaded, the UIPrintPaper will have the width, will be the roll width, and the height will be the maximum height that's possible on this roll printer.

So by default if your app doesn't implement this cut length for paper and the user chooses a roll printer, the default length will be proportional to the height.

So if you normally would be printing US letter, we'll choose a paper size proportional to US letter or if you have a photo, 4 by 6 or something, we'll choose a size that's proportional to that.

So here's an example of telling the printer system how long to cut.

In this case all we're doing is returning 2 times the width.

So next we'll go over the demo here.

This is what our UI's going to look like.

And I have bad news.

I did not win the Apple design award for this UI.

[ laughter ]

It's pretty simple.

It's just like a text field and a couple different ways for the user to select the font and the color.

And then when user selects a roll printer, we'll be printing a banner so it will come out as a banner printed across the roll.

So how are we going to do this?

We'll have our string of text, here's our roll of paper that we just found at the printer.

We'll tell the printing system that we're going to be doing a landscape job so that we print the text along the roll.

We're going to use a UI simple text formatter to format the text with the font the user selected.

We're going to figure out how big we can make it.

We'll calculate that total size and we'll return a cut length.

And I'll show that demo now.

Okay so here we have our print banner project.

So this is available in the prerelease section of the developer documentation so it's been available this week.

So basically everything that's going on in this app happens in the view controller.

We have some pretty boiler plate things that are just finding the font that the user selected and finding a color that the user selected in the UI.

Here's our print method.

First we're grabbing the shared UIPrintInteractionController.

We're setting the controller's delegate to be ourselves because we want to be called for cut length for paper.

We setup a completion handler which just basically logs an error if something goes wrong.

Here we're setting our printInfo output type to be general because the user can select any number of colors so it's not Grayscale.

Here we're setting the orientation to be landscape so we're printing along the roll.

Here we're setting the job name to be just whatever the user has entered into the text field and then we set the printInfo on the controller.

Next we create our simple text formatter.

We're initializing it with the text from the text field.

We set the text formatters color to be the users chosen color and the font to be the users chosen font.

We set the controller print formatter property to be our simple text formatter we created and then we just present the UI.

Now when the user selects the printer it has a roll.

This delegate will be called cut length for paper with the UIPrintPaper representing the roll.

Here we're just calculating the size of our text based on the default font.

We'll do a simple calculation to figure out how big that we can actually make it on the page.

And we'll create a new font based on that size that we just calculated.

Here we're finding how big our final text size is going to be with that font that we calculated using just a size with attributes.

And we set our simple text formatters font to be the font that we just calculated with the size we calculated.

Now next we actually have to figure out the margins.

So we figured out how wide our text is going to be but if we just returned that length we wouldn't be accounting for the margins.

Even roll printers can have margins on top, bottom, left and right so we need to add in our margins.

To figure out margins we just subtract our printable rect from our paper size so that gives us margins on both sides.

So we'll return the width of our text plus the length of these margins and plus some small padding factor to make sure things fit.

So we'll run this in the simulator here and here's our UI.

I'll choose script.

We'll enter some text in here.

[ Silence ]

San Francisco is full of hipsters.

[laughter] This is true.

So next, what are we going to print this on?

Well we ship a really great tool with Xcode that's a printer simulator so as you're developing your app you don't have to be wasting paper.

To get to this simulator, from the iOS simulator we can just go file, open printer simulator or we can, from Xcodes developer menu, we can choose open developer tool, that's available here too.

So the printer simulator has a bunch of simulated printers.

We have different types, color lasers, Inkjets, two sided printers.

New in the latest Xcode, Xcode 5, we have a 36 inch roll printer and we have a simulated label printer.

Now roll printers always detect the size of the roll that's loaded.

You always know the size.

So how do we set a size with our simulated printer?

Well we have this load paper button here in the UI.

We can tap that and here we get a view of all the different simulated printers and which size is loaded in each.

We'll go to the simulated label printer and actually load a 2 inch roll so we're going to print a 2 inch roll banner.

Click okay.

We'll choose the label printer.

And there we have our output so it's been formatted correctly and spans the roll.

Now we're dynamic here, we're dynamic here so we can choose a different font.

We can go in, load a 4 inch roll if we want, print that same content to the label printer and then fills the roll.

Now as Howard mentioned we have an actual real printer here.

We'll go ahead and choose that.

We'll print that out.

So Brother makes really great, very reliable printers and this one, like Howard mentioned, will actually be getting an AirPrint upgrade later this year.

It's shipping right now.

It takes a little bit of time for it to get warmed up here as it prints.

It's a thermal printer so the array needs to get warmed up.

We haven't printed to it in quite a while.

And here we go.

[ Noise ]

And so there we have it, so there's our printed roll.

So I hope we've shown you that printing in your app is really easy.

Printing items like PDF's and images can be really just like 10 lines of code.

We provide formatters and renderers to give you full control of printing so you can make beautiful output.

And like I mentioned the printer banner sample app is available on the developer website.

With that I'll hand it back over to Howard.

Howard Miller: Thanks for coming.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US