WWDC2013 Session 711

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ 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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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 ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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 ]