WWDC2013 Session 203

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Thank you, thank you.
Welcome to this morning's
session
for what's new in Cocoa Touch.
If you were here for the
Building User Interfaces
for iOS 7 talk with Jason
Beaver and Andy Matuschak,
they had a lot of
really pretty pictures.
They went into some
fantastic detail
about the design
aspects of iOS 7.
And I'm going to spend a lot
of time on the actual API
that you're going to be using
in order to implement a lot
of the stuff that
they talked about.
So if you weren't able
to get into the room,
if you're listening to this
on the tape, you probably want
to go back and watch
that talk on video first
and then start in here.
So, let's get started.
One of the things that
you'll notice, of course,
is that stuff used
to look like this.
This wouldn't be a
presentation of mine
without a picture of my dog.
But now, it has a little
bit different look.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And again, they spent a lot of
time talking about how this--
you know, the reasons behind
this and how this works
in the previous talk, so please
make sure you go see that.
I'm going to spend,
again, a lot more time
on the really low
level details here.
So first, we'd like to talk
about adaptive multitasking.
So in iOS 6, if you
were a multitasking app,
you fell into one of
the void categories
or the audio categories
and things like that.
So we're adding new
mechanisms for you to be able
to keep your content fresh and
to be able to keep the illusion
as if your application is
running all the time in iOS 7.
And that involves three new
things, background fetching,
remote notifications,
and background transfers.
So for background fetching,
what you'll do is you'll
add this new fetch category
to your background mode in
your application's Info.plist.
At that point, your
application will be
launched opportunistically.
So what we're doing here is
watching the user's patterns
for how they use
your application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And if we notice that, for
instance, they're firing
that application up every day
at 7:55, we might fire you up at
about 7:50 and say, "OK, go
ahead and do this fetch,"
you'll get a new delegate
method on UIApplication,
application performFetchWith
CompletionHandler.
And the idea here is you'll get
called back at this point, say,
we fired you up, you go off
and do your network traffic.
And then at the end of that,
you're handed a completion
handler that you have to call.
That's how you tell us when
you're done with your transfer.
The background fetching
interval is controlled
by this method on UIApplication.
It's setMinimumBackground
FetchInterval.
You can use one of these two
constants, UIBackground--
UIApplicationBackground
FetchIntervalMinimum
which is the slowest callback
interval that you can give us.
ApplicationBackground
FetchIntervalNever is please
don't call me at all.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You'll have to call
this method at launch.
Make sure that you get set
or you can turn yourself
off during your run.
And your own values above
minimum will work as well.
So, for the remote notifications
mechanism, if you're using--
if your app uses a server
and the server knows
that it has new information
for one of your applications,
you'll be able to get a push
notification from the server
and you'll get called back
on this delegate
method application
didReceiveRemoteNotification
FetchCompletionHandler.
And you'll also add that remote
notification background mode
to your Info.plist.
The handler here is, again,
your opportunity to go out
and do a bunch of work 'cause
the userInfo dictionary is the
push notification userInfo
dictionary you've been
getting before.
And again, when you go
out and complete that,
you'll call the completion
handler
with a UIBackgroundFetchResult.
And you don't have a lot of time
to be able to do these things.
You've got a certain
fixed amount of time.
If you don't call that
completion handler in time,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we may not actually fire
you up the next time
for either an opportunistic
fetch or for a remote fetch.
So you need to make sure that
you're getting your work done
in a very short amount of time.
The UIBackgroundFetchResult,
this is the completion
handler signature.
When you call the completion
handler, you're going to pass
in one of these three
values, ResultNewData,
ResultNoData, or ResultFailed.
And this is how you tell
us exactly what happened
so that we know "Well,
if the result failed,
maybe we'll call you back
again in a few minutes
and maybe it will succeed then."
Or if you had no data, then we
know that "Well, maybe every day
at 7:50, there isn't any data
and we don't actually
need to fire you up."
All right, so that gives
us some ability to be able
to tune the behavior of the
system to your user's behavior
and your app's behavior as well.
So the new multitasking
also has new Foundation API
and NSURLSession.
So this is really a replacement
system for NSURLConnection.
It handles data, upload
and download tasks.
Sessions have identifiers,
so you can actually restore
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from an identifier much the
same way you can create things
from state restoration.
There's a new delegate on
UIApplication that gets called.
So if we know that
you've got one
of this background transfers
going, you may have to fire
up in order to handle things
like authentication
or transfer of data.
So application handleEventsFor
BackgroundURLSessio:
completionHandler gets called.
You get the session identifier.
We instate the session
identifier--
the URLSession from
the identifier
and then do your behaviors.
So-- and again, here
you're going
to call the completion handler
when you're done
handling the callbacks.
And this completion
handler just is--
is a void void, so you can
just call it immediately.
There is a talk on What's
New in Foundation Networking
in the Mission, Wednesday
at 9:00.
If you're doing any this
kind of downloading or work
with connections or sessions,
you're definitely going
to want to go see that talk.
So, you saw in the previous
talk about all the changes
that we've made for rendering
and things like that,
so let's talk about views
and images a little bit.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have some new image
rendering modes in UIKit to deal
with the way that you might
actually display an image.
So, if you are working with
template images before,
you are probably going
out to UIImage imageNamed,
pulling an image off of disk,
calling rendering context
with a bunch of color
and stuff like that
and then slamming that color in.
So you actually do a
bunch of work to be able
to colorize a template of image.
This actually takes
care that for you.
So once you have an image
in hand, you're going
to call UIImage
imageWithRenderingMode.
And that rendering
mode has three options.
Automatic means that
we will do something
with this image in
a given context.
I'll talk about that
in a second.
ImageRenderingModeAlwaysOriginal
means always use the pixels
as they came off of disks.
So if you've got a non-template
image and you want to make sure
that it doesn't get
changed when it's put
into a different context,
you'll be able to use this.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Template means go
ahead and colorize it
or apply the template the way
that the context defines it.
So what's the context?
The context is defined
by a new UIView property
called tintColor.
So, Andy talked about the fact
that we've taken the
tintColor concept
and hoisted it all the
way up to UIView, right.
So UIView now has this
top level tintColor idea.
It's hierarchical.
You can set it on your window
which will push the
tintColor all the way
through your application
and things like controls
and images will respond to that.
And you can also pull from that.
So, if somebody set
it on a higher view
in your view hierarchy and then
you go down to a much lower view
and call tintColor, you'll
find out what the tintColor is.
You can render in context with
that tintColor if you like
or just find-- you know, use
it for your own purposes.
What does this look like?
So, the default tintColor
is this blue that you use.
What I've got here is
a top level UIView.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's a UIImage view there
which has the little chevron
and that's a UIButton
that says "Onward."
And if you call, for
instance, set tintColor red,
the only thing I've done here
is that image has the previous
on image rendering
mode set to template.
So if I call set tintColor
red, everything that's
in that view hierarchy
inherits that tintColor.
So you don't have to do any of
the rendering context anymore
and all of our controls
will take care of this.
This is a really good way
to be able to apply, say,
a theme color or a signature
color to your application.
We also have this thing
called the TintAdjustmentMode.
And when we present
popovers on the pad
or when present alert
sheets on the phone,
when we cover the content,
we're going to put a
dimming view over that.
And one of the things
that we'd like to be able
to do is indicate that things
with a signature tintColor
are no longer inter-actable.
And so, the TintAdjustmentMode
allows us to say, "OK,
this is a gray automatically
desaturation.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you don't want that behavior,
you can change the
TintAdjustmentMode
so that it doesn't
desaturate, OK."
So this is what it looks
like with it's desaturated.
You can tweak that if you
do actually want that--
those elements to
not get changed.
When you find out about
changes to the tintColor,
frequently this kind
of tintColor changes don't
require layout changes.
You don't have to
go back through
and re-layout all your views.
You just need to change
the colors, right.
If you implement
tintColorDidChange
on your UIView subclass,
you'll get called and told
when either somebody changes the
tintColor up at the top level
or the view hierarchy
which you inherit,
or when somebody calls
set tintColor explicitly,
or when any of these
TintAdjustmentMode
changes occur.
So that's your opportunity to do
things like call the tintColor
from high in the hierarchy,
do a rendering context,
and get the look with your
tintColor that you want.
So View Animations can
be a little tricky.
And we've introduced
a new method
called performWithoutAnimation.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And by introduce, I
mean, we discovered
that we were needing this a lot
and we probably figured you
guys needed it a lot too.
It's very easy to get
caught up in either some
of UIKit's default animation
block or some animation block
that you've created elsewhere.
And you can even do some layout
changes or some behaviors
that really require fixed layout
that goes into a view hierarchy
so that it doesn't get
accidentally animated
if these things happen.
So you can call
UIViewperformWithoutAnimation.
This is a class method.
And anything you put in that
block will happen instantly
so it won't get animated when
it gets into a view hierarchy
or anything like that.
So this avoids a little effects
where you created something,
for instance, with CGRectZero
and then suddenly it expands
out during an implicit
animation block.
The other thing that we've
done is we've also added new
UIViewAnimation level
KeyframeAnimation API.
So you don't have to drop down
the CAKEyframeAnimation anymore.
You can use
animateKeyframesWithDuration
delay options animations
completion.
So this looks very similar
to the UIViewAnimation
API you already have.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Once you've got that
you can also put
in
addKeyframeWithRelativeStartTime
relativeDuration animations.
And you can compose this
with the UIViewAnimation
blocks as well.
So what's you're getting here
is the ability to do things
like start animations
consistently at relative times,
have those animations
run a proportional value
of the containing animation.
And there are a ton
of options for this.
Some of them are familiar
if you've been using the UIView
Animation mechanism before.
So UIViewKeyframeAnimation
options, layoutSubviews,
AllowUserInteraction,
all of those are the same
as the UIViewAnimation
API you're already using.
There are few, OK.
And there are new timing methods
for calculating how those
relative values will run
through the animation.
So this should be a
really easy way to be able
to do the really subtle, really
timed animations that you'd had
to dropdown to KeyframeAnimation
for.
So, you can stay up at
the UIView level here now.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Andy talked a little bit
about motion effects
in the previous talk.
Motion effects are the
things where when you pick
up the device and
you start moving it,
that you get those effects
like things are floating above
or below various
aspects of the interface.
Motion effects apply relative
values to key paths of a view.
So what you'll do is specify
which key paths you want,
those things will get
applied to the view.
And it applies the animatable
properties of the view.
So if it's a CA animatable
property, you'll be able
to use it with motions effects.
And the idea is that
you're going
to produce a very subtle effect
that really intrigues your user
and really indicates the content
or the focus of your
application.
So the motion effects--
the easiest motion effect to
use is a canned one that we have
in UIKit called
UIInterpolatingMotionEffect.
There's one initializer
and it was KeyPath type.
And the KeyPath is the property
on the view that you want
to effect, and the type is
one of these two things.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's either along the horizontal
axis or along the vertical axis.
And so, you'll specify, if you
want to do something in both,
you'll have to create two of
these and decide with KeyPath
and which type you're
going to be affecting.
It interpolates between
the minimumRelativeValue
and the maximumRelativeValue,
right.
So you'll be able
attach these to a view.
And having it attach
to those views
as the device moves
will take care
of doing all the application
of that effect to the view.
So you can do things like change
the center, change the size,
change the offset, you know,
all of the various
animatable properties,
you can change the
frame as well.
If you want to write your
own, you can do that.
You can use the UIMotionEffect
Abstract superclass.
There's one method on it,
keyPathsAndRelative
valuesForViewsOffset--
ViewerOffset, there we go.
The ViewerOffset is expressed--
we don't use UIOffset very much
in our API if you've seen
but just as a reminder,
that's a horizontal
and vertical offset.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So horizontal is obviously
that the axis that we're using
for the interpolating motion
effect as well as the vertical.
You'll overwrite this and
provide-- you'll get a--
you know, provide a dictionary
of the key paths that you want
and what values given the
inputs of that UIOffset.
So this is how you can write all
of your own more
complicated motion effect.
You'll add or move them to the
view with just addMotionEffect
and removeMotionEffect.
And if you need find out
what affects are on the view,
you can go ahead and call
the motion effect's accessor.
These are really,
really interesting APIs
because there's not
much to the API
but it concentrates on behavior.
So what you'll be able to do
is add these things gradually
to your application and
touches here and there.
And it'll really make
your application pop, so.
We've made some enhancements
to collection views, all right.
Collection view is
really flexible.
There are really interesting
ways to be able to combine them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And you're really able to do a
large scale layouts without lots
and lots of individual layouts
subview tweaky little calls.
One of the things that we've
added is a convenience API
for switching between two
collection view layouts,
setCollectionViewLayout animated
completion is a new method
which compliments the old one
that didn't have the
completion handlers.
Now, if you are animating
it, you can find out exactly
when that animation completed.
So this is just a
little one off method
to help you out with that.
But one of the things we've
done in terms of switching
between two different collection
view layouts is added a really
easy way to be able to
interpolate between the two
with what's called
UICollectionView
TransitionLayout.
And a transition layout is a
UICollectionViewLayout object.
You hand it two other collection
view layouts, the current lay
out and the next layout,
and then we'll take care
of interpolating
between those two
as you drive the
transition progress.
So if you're needing to update
values in there yourself
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for a custom subclass,
you'll get called
with updateValueForAnimatedKey
or value forAnimatedKey
so you find out what's happening
as the
CollectionViewTransitionLayout
is firing.
But for the most part,
you'll just be able
to call this transition,
setTransitionProgress property
and say, "You know, I'm 10
percent, 20 percent, 30 percent,
40 percent of the way through
it," and we'll take care
of interpolating between
all of the elements
in your collection view layout
in the starting collection
layout and the ending one
and take care all of the
movement of the views
and everything else for you.
So, this transition API is
really handy if you combine it
with the UIView controller,
API to be able to switch
between navigation
controllers and handoff
that collection view
itself that we're talking
about in the previous talk.
So, collection view layout, very
powerful, very easy now be able
to ship between two
different layouts.
View controllers, of
course, are the unit
of composition for UIKit.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We've made a lot of
changes to view controllers
to accommodate the new
API-- the new appearance.
We've also made a number of
changes, try to make it easier
for you to be able participate
in a lot of the things
that we do in terms of canned
animations and stuff like that.
But of one of the
first things I want
to mention is
wantsFullScreenLayout.
So, a lot of what you were
doing in iOS 6 in terms
of full screen layout was
dealing with things like this.
Here's a picture of the dog.
He was helping me out with
my presentation last week,
cleaning things up or, as
I like to call it, snoring.
This is a non-full screen
layout iOS 6 view controller.
And if you were going to call
wantsFullScreenLayout yes,
and then if you set your
navigation bar appearance
to be translucent and
your status bar appearance
to be translucent, you
get something like this
and this is the classic
barb with full screen layout
which is, you know,
you're not really--
I'm not stretching out the
content here to make sure
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that it fits the
full screen layout.
One of the things that
we want to make sure
that you guys are doing is
using full screen layout
because iOS 7 deprecates
this property entirely.
wantsFullScreenLayout
is no longer useful.
We will treat as if it
were yes all the time
for [inaudible] or after 7.0.
So, with Bud resting
here, you can kind
of see how the content is slid
up under the navigation bar
and-- but the way that--
in iOS 7 that we're
going to have you specify
which edges get stretched
in a situation like this is
with this extended edge API.
And some of this is in flux,
but this is what in
Seed 1 right now.
It may look a little different.
We're still tinkering
with some of the names.
But the extended edge API here
is specifying that the edges
for extended layout for
your view controller,
this property is going
to be all by default.
We want to be able to take
you views and expand them
to their full content size.
But if you want to specify
only the left and right edges
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and leave the top and
bottom the way they are,
you would logically [inaudible]
some of the flags together.
You can also check
if the extended layout
includes the opaque bars.
This is no by default in iOS 7.
And automatically
AdjustsScrollViewInsets is how
we're going to take a look at
the scroll view that's probably
at the top of your view
controller and say, "OK,
I can adjust the content
insets to make sure
that the content is actually
positioned correctly inside a
navigation controller or a Tab
bar controller because now all
of those bars, the Nav bar and
the Tab bar and the Tool bar
or Tab bar at the bottom have
that blur translucent effect."
So we want to make sure that
all of your content is winding
up in the right place.
These methods are how we're
going to help you adjust
that content automatically.
So automatically
AdjustsScrollViewInsets will
take of a lot of
those numbers of you.
And this also takes care things
like when the device rotates,
exactly how far you adjust
those insets because, of course,
on the phone, when you
rotate to landscape,
the Nav bar's a little
shorter, so.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We also we have new
API for content size.
So in many cases, we take a
view controller from you guys
or from-- you take one
from another component
like address book or something
like that, and you're going
to make a child view controller
of your view controller,
you want to find
out how big it is.
So preferredContentSize is
a way for view controller
to tell UIKit or tell
parent view controllers,
"I'd like to be this
size," right.
And this is actually replacement
for the content size review
in popover call because
we're going
to use this call
everywhere now in iOS 7.
So if you want to tell us how
big your view controller ought
to be right when
we initialize it,
this is your opportunity
to do it.
And it's a great way
to be able say, "OK,
I'm going to take
this view controller,
make it a certain size, how
big do you want it to be?"
So, layout is very important.
In terms of the status bar
appearance, there's new behavior
for the status bar and the
status bar actually has
no background.
What's you're seeing in iOS 7
is the navigation bar getting
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
taller and the status bar
being over laid on it.
UIStatusBarStyleDefault
is what you see--
it's got what we
call "Dark content",
meaning the status
bar information is all
in black or dark color.
Status bar--
UIStatusBarStyleLightContent
has white text up there.
So if your content
is going to be dark
or otherwise not contrast
with the default, you may want
to set UIStatusBarLightContent.
And this refers to the content
of the status bar itself.
These other two properties,
StatusBarStyleBlackTranslucent
and StatusBarStyleBlackOpaque,
those refer to the background
which really doesn't
make any sense anymore.
They don't have a
background now.
So, those are deprecated.
You can stop using them.
So if you recall with-- there
are two major sections of UIKit
or behaviors in UIKit where
we do these transitions,
where you slide, you do a push
pop in navigation controllers
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or for a modal transition,
the presentation slides
up from the bottom.
Those are all canned
transitions.
You haven't been able
to participate in
those until iOS 7.
So iOS 7 introduces
custom transitions in all
of our API that does it.
So you're talking about
navigation controller push
and pop, we've got
modal transitions.
You'll be able to drive
these both off a timer.
So if you're just doing a
straight push or a straight pop,
you'll be able to participate in
that with your own transition,
or you'll be able set up
an interactive transition
with the user actually
sliding their thumb across
and you'll get all kinds of
events about things like whether
or not they made it all
the way across [inaudible],
whether they canceled
the transition,
or whether they made
it all the way across
and actually finished
the transition.
There's a new delegate method
of UIViewController called
transitioningDelegate.
The transitioningDelegate is
going to be the object called
to find out how to
do this transition.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, let's say you've got
an UINavigationController,
you're pushing a new
view controller on it.
If that view controller has a
transitioningDelegate property
set on it, that object's going
to get one of these methods,
animationController
ForPresentedController,
presentingController,
sourceController.
So the sourceController or
the presentingController,
you're given all of
the view controllers
that are participating
in the transition.
And animationController
ForDismissedController,
this is basically the equivalent
of a pop or a dismissal
of a modal transition.
The objects conform
to this protocol,
UIViewController
AnimatedTransitioning protocol.
The protocol is really
useful here because it means
that you can specify any object.
It can be another
view controller.
It can be an object
of your own type.
As long as it conforms to
this protocol, you'll be able
to drive these transitions.
For interaction, we'll ask
the transitioningDelegate
for an interaction
controller for a presentation
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or an interaction
controller for dismissal
when the thing's going away.
So presentation on Nav
contoller is, of course, a pop,
the dismissal would
be-- I'm sorry--
presentation's a push,
dismissal is a pop.
It has its own protocol as well.
So you are in a maze of twisty
little protocols all alike.
They're actually not all alike.
They're very, very powerful.
And for instance,
the AnimatedTransitioning
protocol, it's pretty simple.
The transitionDuration,
animateTransition,
and animationEnded,
these are all methods
that your transitioning
object will get called on.
You can return the
transitionDuration
for a given transition context.
The animateTransition
for a transition context.
This is when you're told, "Go
ahead and do the animation."
We're ready to go do your
slide, do your fading,
do your twirly transition there.
And animationEnded, this
is how you find out when
that transition ended.
So, the animated bits,
this is for the parts
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where things are
happening on a timer,
things are happening
on our context.
Custom transitions
for UIViewController
InteractiveTransitioning,
you'll be told when to
start the animation,
the interactive transition,
right?
So just like the other API,
this is where you're going
to start the interaction.
And the completionSpeed and the
completionCurve are used to find
out when the user got far enough
across, did they finish or not,
and if they didn't
or if they did,
how fast do you want the rest
of the animation to run, right?
So when you're sliding
your thumb across
and you're driving one of these
things based on user gestures,
if you get all the way across,
then it must have
run the completion,
I think half way across, a
little bit more than half way.
And that means, yes, you
can actually do the rest
of the transition as
if they completed.
This is how you specify how long
it takes and what the curve is.
And the curve is
the UIAnimation bit.
Here's the meat of it.
The UIViewController
ContextTransitioning, again,
this is a protocol that
your objects conform to.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is where you put all of
the information that you need
in order to drive
these animations.
You'll need to supply
a container view.
Frequently, this is the
parent view controller's view.
Whether or not it's
animated, whether or not
in it's interactive, whether
or not a particular transition
was canceled, you'll be able
to do all of that and
find out from this
that the transition
was canceled.
You'll also specify -- you can
specify presentation styles
and all kinds of stuff.
This is incredibly powerful.
And this is the mechanism that
we're using, for instance,
to do the slide transition in
navigation controllers now,
so you'll be able to participate
in all of those things yourself.
We've got a Custom Transitions
Using View Controllers talk
in Pacific Heights
on Thursday at 11:30.
If you've ever wanted to be able
to participate in these things,
that's the talk to go to.
So, let's talk a little bit
about some new stuff
in State Restoration.
One of the things that
we've noticed in terms
of our own usage of state
restoration is there are times
where your content or the state
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you're restoring doesn't
really match the snapshot we
took when your app got
killed before, right.
So, one of the new
methods that's available
in state restoration
is ignoreSnapshotOn
NextApplicationLaunch.
So, you've discovered as
a function of starting
through the state restoration
mechanism that allow,
you know what, the
snapshot that's going
to get taken won't
make any sense.
You can call
ignoreSnapshotOnNextAppLaunch.
That method will prevent
us from taking a snapshot.
You'll get the default
ping when it comes up.
You'll be able to still do
state restoration things
when your app comes up but
it won't have the old content
if it doesn't make sense.
One of the other things that's
been a very popular request is
for objects that aren't views
or view controllers to be able
to participate in a state
restoration machinery.
So you may have your
own model objects
or you may have your own
informational objects
or created models, things like
that, that are all going to need
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to participate in
state restoration,
you can use this method,
registerObjectFor
StateRestoration
restorationIdentifier.
So just like view controllers
can have restorationIdentifiers
just like other views can
restorationIdentifiers,
you'll now be able to specify
a restorationIdentifier
for arbitrary objects.
You'll call UIApplication
registerObject
ForStateRestoration
restorationIdentifier,
tell us the object,
tell us the identifier.
And as long as you conform to
the state restoring protocol,
we'll go ahead and
restore that object along
with everything else during the
state restoration mechanism.
So this is a great way be
able hand us more information
and you guys can do a little bit
less work in terms of archiving
and saving off your additional
state 'cause we'll keep track
of it for you.
We also now support a couple
of interesting features.
If you're using Core
Bluetooth and you've paired
up with a Bluetooth Central or a
peripheral in your application,
we can now state restore
those things for you as well.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So UIApplicationLaunchOptions
BluetoothCentralsKey,
when you get the state
restoration method callback,
one of these things
in the userInfo dictionary
will be the--
all of the identifiers
for the Bluetooth Centrals
that we can determine
that were present
when you went down before.
So, you'll be able to
pull all those back up
and reconnect very easily.
And if you were connected to
peripherals, you'll be able
to get to all of
those peripherals back
out of the array that's
returned by this key as well.
So, you don't have
to go back and try
to repair everything without--
and keep track of
all of that stuff
because we'll take
care of it for you.
Let's talk a little
bit about AirDrop.
AirDrop is new iOS 7.
You've got the Activity
View Controller that comes
up in AirDrop as an option.
One of things that you'll
do is go ahead and look
in the
ActivityItemSourceProtocol,
make sure that your
object conforms to that.
You'll update your
Info.plist which will create
or register the UTIs for
the things that you're going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be able to accept
as an AirDrop.
And there's a new
Documents/Inbox directory.
This directory lives in
your application's wrapper.
And that wrapper-- the Inbox
directory will accept all
of the things that
are being AirDropped
to your application, right.
So whenever your
application activates,
you'll want to take a tour
through this directory and see
if there's anything new in there
that you'll want to pull in.
New documents, new things
that other users have shared
with you are going to come along
with these app activations.
And you should check this even
if you don't get the
usual application:openURL
:sourceApplication :annotation:
call because these
things are going to come
in from other places and
they may come in frequently.
So somebody AirDrops 10 or 12
things to you, you might want
to be able to queue
that work up.
You don't want to do all of
the transition work of "Oh,
I received this thing and then
I'm going to move it over here
and process it somehow."
You want to defer that until a
point where the application is--
you want to make sure that the
application to stay responsive.
You don't want to block
the user doing that.
So you might want to queue
this stuff up if you discover
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that there are 12 or 15
things in the Inbox directory.
This is tremendously
exciting because it's going
to be a very easy behavior-base
way for you guys to add really,
really, really subtle effects
but really fantastic
physics-base effects
and animations to
your application.
The idea is to be
able to provide fluid,
very responsive animations
that enhance the interactions
in your application, all right.
This is not something
that you should be using
that says, "Hey look.
This is animating and it's
bouncy and it's physics."
It should be really,
really carefully considered.
And the concentration of
the API is on behaviors.
We don't want you to have to
write lots and lots of code
to be able to get basic things
like views dropping
down from the screen.
The Lock Screen effect
where you bounce the camera,
you bounce the Lock
Screen to find the camera,
that's very few lines of code.
It's attaching behaviors to
a view rather than having
to write all of the
physics behavior behind it.
What you'll do is create one of
these UIDynamicAnimator objects.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And a Dynamic Animator
concentrates
on a reference view.
Most of the time, you'll be
using this view initializer,
initWithReferenceView.
That view contains-- it's going
to apply behaviors
to everything in it.
You'll add dynamic behaviors
or remove dynamic behaviors
depending on what's going on.
And you can also find out if
you're writing one of your own,
all of the items
in a given rect.
So you may want to be able
to do things like only look
at the visible rectangle and
only animate those things
that are actually
visible if you're going
to write your own
dynamic animators.
You can also find out
whether or not it's running
so you'll be able
to know whether
or not the animation
has come to rest.
And there's a delegate that
tells you also when things come
to rest, when things
started up again.
So, one of the things that we're
doing with this is making sure
that you're concentrating on the
behavior, we're concentrating
on the bookkeeping
for the physics.
Dynamic behaviors are
just a tree of all kinds
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of supported things for gravity
and collisions and
stuff like that.
So you'll add or
remove child behaviors
to a given dynamic behavior.
And a dynamic behavior
defines all kinds
of timings and things like that.
One of the things that you can
do is you can also implement an
action block.
It gets called at every frame
of the dynamic animation.
So if you need to do something
that our built-in behaviors
don't do or can't really support
without additional help from
the system as it's running,
you can implement
this Action method.
It shouldn't be too
common, but you can do it.
What are those supported
behaviors?
Attachments, so if
you want to be able
to have one view
follow another view,
you can attach the
two views together
and they'll animate together.
CollisionBehavior, if two
views are going to bump
into each other and bounce off
of each other, you
can specify that.
GravityBehavior, how
much gravity is involved,
and that's how we control how
fast that Lock Screen drops back
down when you're
bringing the camera up.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
A PushBehavior is if you
give it a view an impulse
as if you were giving it a force
and it's going to slide off
and bump into something else.
We have a new unit
of measure I think
that we're introducing there.
You'll have to go to
the Animation talk
to find out what it is.
A SnapBehavior, SnapBehaviors
are really interesting.
They allow you to be able to
specify essentially a well
or a snap so that when a
view overlaps another one,
it folds into place
at that location.
And if you need to do
something that isn't setup here,
UIDynamicItemBehavior is your
opportunity to participate
in the system yourself.
So DynamicItem is just something
that conforms to this protocol,
center, bounds, transform.
And that's how we move things
around on the screen
during the animations.
There are two Dynamics
talks, Getting Started
with UIKit Dynamics
right here at 4:30.
The demos are awesome.
And Olivia will an absolutely
fantastic job talking
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about this.
Advanced Techniques with UIKit
Dynamics, Thursday here at 3:15.
It's very composeable.
It's tremendously powerful.
There's a lot of stuff here.
If you're interested in this
kind of physics-base animation,
you're going to want
to see this talk.
So, let's talk a
little bit about text.
We've always had a concentration
on beautiful typography
and really, really
crisp beautiful text.
In IOS 6, we introduced all
of the NSAttributedString
components that enable you
to do things like mix
and match runs of text
with different styles.
You know, bold, italic,
underline, things like that.
We also piped that all
the way through UIKit.
So, buttons and text fields and
text views and stuff like that.
Really, we're able to do--
you're able to do far more
typographic things with it.
We've introduced a new
dynamic types sizing mechanism.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, dynamic type, this is the
text size view controller that's
in settings.
The user can go and slide
this slider left and right
to decide how large or small
they want their primary content
to be, right.
And that slider is piped
to the
preferredContentSizeCategory
method-- property,
rather, on UIApplication.
This is how you find out
what the user selected.
And that preferred content
size categories can be the--
essentially, the text size
for the primary content text
that you're using and that'll be
based with one of these values,
extra small, small,
medium large, extra,
it's like a t-shirt
but with-- for text.
So, this specifies sort of the
base relative size of the text.
When it changes, you'll
find out when it changes
because you'll get a
ContentSizeCategory
DidChangeNotification and a
ContentSize CategoryNewValueKey,
and this is your opportunity
to be able to go back,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
find out what changed,
relay out your text.
So, again, with the dynamic
text bits, you're going to want
to be using auto-layout because
that will help you scale your
layout as the text size changes.
They mentioned this
one method here,
preferredFont ForTextStyle,
right.
Most of our content falls
within certain bins.
There's a body.
There are some headlines or
a subject line or something
like that or a smaller
text that's interstitial
like a caption for a
picture, something like that.
All of these styles,
you can pass
into preferredFontForTextStyle.
We'll go through
and evaluate that,
figure out what the appropriate
size, weight, all of the things
that would apply to that
is in relative terms
and produce a new
UIFont for you to use.
So this method
preferredFontForTextStyle is
very, very important.
It's the single chill
point to be able
to get relative text styles
and fonts for your application
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and they'll scale relative
to the primary content
size that you want.
One of the things
that we've noticed is
that the NSAttributedString
system is very powerful.
You can specify attributes.
You can do all of these things.
But you're pretty much getting
the rendering that we give you.
So in IOS 7, we talked about
this a couple of times,
but in IOS 7, we're
introducing Text Kit.
Text Kit is an Objective-C API.
It's inspired by the Cocoa
text system from OS X.
So if you've been using the
Cocoa text system on OS X,
a lot of the concepts
that we're going to talk
about here will be
very, very familiar,
and this wraps Core Text.
So this is our high level API
for our low level text system.
So let's talk about the
classes that are involved here.
This is just an application.
It's got a UITextView in it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
That UITextView has
an NSTextContainer.
And NSTextContainer is
the largest component
of the text system for layout.
And then we get an
NSLayoutManager.
And the Layout Manager is the
thing that's actually in charge
of doing all of the
drawing and the bits.
And an NSTextStorage is the
actual NSString that's backing
all of this, right.
And one of the great things
about Text Kit and one
of the fantastic things about
way this to setup is if you want
to participate at any level
of this, you don't have
to subclass the whole stack.
You just subclass an
NSLayoutManager if you want
to change the way maybe glyphs
render, or a TextContainer
if you'd like to change the
way text flows or wraps.
Or if you need to be able to
manage your own specific kind
of text storage that isn't
just a straight array
of Unicode characters, you can
subclass that as TextStorage
and you can participate at
any level of this hierarchy.
Let's talk a little bit about
TextView and TextContainer.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
An initWithFrame textContainer
is the new designated
initializer on UITextView, OK.
So if you specify a
nil TextContainer,
you'll get the default
that UIKit uses.
You can also find out what
that TextContainer is.
And as a convenience,
the layoutManager
and textStorage methods
are call-throughs
to the TextContainer
from UITextView.
We're just piping those through
to make it a little easier
to get to.
So, all you have to do
here is if you're going
to change your TextContainer,
call that.
TextContainers get initialized
with a size, so they get setup
with a specific size
for the frame
that they're being laid out in.
And they also have
a LayoutManager.
So if you're going to--
if you're going to
subclass LayoutManager,
you can provide your
own subclass.
If you don't provide one here,
again, you get our default,
so you get the default behavior
all the way down the stack.
You can also change
the lineBreakMode
and lineFragmentPadding.
So things that you've never
really had a lot of control
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
over before, where things
break, how they break
with the default break modes
and the fragment padding
for how things get split out.
lineFragmentRectForProposedRect
atIndex writingDirection
remainingRect, there are a lot
more methods on TextContainer,
and these are just
a few of them.
But this is the kind
of control you get.
Given a specific rectangle at
an index and a character index
of your Text Screen
will tell you what the
baseWritingDirection is,
you'll fill in a remainingRect,
in return, a rectangle for that.
So if you want to change
where this stuff lays out,
this is one place to do it.
So you're going
to get exceptionally fine
during control over where all
of the glyphs wind up.
One of the most-- one
of the coolest things we've
done is exclusionPaths.
So, if you're doing a picture,
for instance, of the flowers
that you saw in the
previous presentation,
it's got an irregular
path around it,
that would've involved a lot of
work to be able to try to figure
out where is the bitmap,
where are the places
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that it's overlapping.
With exclusionPaths,
all you have
to do is provide
us a UIBezierPath.
The text will automatically
flow around that path.
And as you change it, we'll
re-layout it automatically.
[ Applause ]
It's a lot simpler.
LayoutManager has a bunch
of different global options,
things like
showsInvisibleCharacters,
showsControlCharacters,
the hyphenationFactor you can
tweak how aggressively words are
hyphenated, usesFontLeading,
whether reusing the leading
from the font system
or something else,
and allowsNonContiguousLayout
and hasNonContiguousLayout.
So, if you've invalidated
a section of the text,
we don't have to re-layout
the entire [inaudible] one
to be able to redisplay
the text.
So NonContiguousLayout
is a great performance
when especially on
embedded devices.
And this concept
is almost directly
from the OS X text system.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you have NonContiguousLayout,
you can find
out from the LayoutManager here.
What does LayoutManager do?
LayoutManager is really the
workhorse of the text system.
So a lot of the features
involve things like invalidation
and there are probably 15
or 20 invalidation methods.
One of them is something
like invalidateLayout
ForCharacterRange
actualCharacterRange, so
you'll be able to take portions
of the layout and invalidate
them yourself or find
out when they're invalidated.
Glyphs and glyph properties.
If you've ever wanted to
get involved with what winds
up on the screen in place of
something in your TextStorage,
this is one part of
LayoutManager's job.
You can find out many glyphs
are in the run, that's just,
you know, what characters
are there.
glyphAtIndex and isValidIndex
tell me what glyph is being used
for the character at this index.
And then you can do things
like getGlyphsInRange
and you'll get a CGGlyph
back with properties,
characterIndexes and bidiLevels.
All of these things
help you decide what's
in the LayoutManager as
well as what gets drawn.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So speaking of drawing, you'll
be able to actually get involved
with what hits the screen based
on the text runs you
have in your TextStorage.
So you can draw a background
for a glyph range at point,
that's how you'll
be able to do things
like put your own
graphics behind things.
rawGlyphsForGlyphRange atPoint,
if you want to put your own
CGGlyphs in place of a range
at a point, you'll
be able to do that.
So you've got complete control
over how text gets
rendered on the system.
drawUnderlineForGlyphRange
underlineType baseline--
all of these different styles,
what kinds of underlines,
what kinds of bold gets used,
all of that stuff is controlled
by the LayoutManager,
you have all
of these methods
available to you.
So there is a fantastic
control over text on iOS.
NSTextAttachment is
another class in Text Kit.
You'll be able to put pictures
and images inside the text
runs inside of UITextView.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Much easier, yeah.
So, we are very, very
serious about this.
This is an incredible
technology.
It's a fantastic opportunity
for you to really take control
of the typography in your app,
especially if you're
writing advanced text
processing applications.
We have three talks on this.
Introducing Text Kit,
come back after lunch,
after the lunch time
speaker, we'll we've talking
about it right here in
the Presidio tomorrow.
Advance Text Layouts and Effects
with Text Kit, that's going
to get into all of the bits,
things like all the
LayoutManager stuff,
where to overwrite things,
that's in Mission,
Thursday at 2:00.
And Using Fonts with Text Kit
right here in the Presidio,
Friday, bright and
early at 9:00 AM.
You'll find out how to
effectively use fonts
from your application
with Text Kit
and everything else
that that implies.
These are fantastic
technologies.
It's all stuff that we're using
in iOS all over the place.
If you don't take
advantage of this,
I'm not sure what to tell you.
This is fantastic stuff.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We're not the only people
working on this stuff.
There are many, many, many
new features across a number
of different frameworks in iOS.
One of the more exciting
things, Multipeer Connectivity,
the Game Kit guys and the IMG
guys have been working very hard
at producing a new framework
for local network
connectivity involving things
like session management,
who's involved,
who's joined a session,
and multiplexing data
across that session.
You'll be able to setup secure
sessions yourself as well
as file transfers
and things like that.
So, if you're writing something
that involves collaboration
or you're writing
a multiplayer game,
this will be a fantastic
talk to go
to in Mission, Wednesday
at 10:15.
If you are at the Platform
State of the Union,
you probably heard
about SpriteKits.
SpriteKit is a cross
platform, high performance,
sprite-based game framework.
So, this makes it
tremendously easy to be able
to write fantastic
iOS-based games,
Mac OS X-- OS X-based games.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It has image atlas support
and really tight integration
with UIKit and Appkit.
One of the things that these
guys did was to be able
to pipe UIGestureRecognizers
directly
into this entire
OpenGL-based rendering system.
So, you'll be able to do very
idiomatic UIKit-like things
with SpriteKit on iOS.
The game Controllers
framework, you'll be able
to pair arbitrary
Bluetooth game controllers
with your iOS device.
So if you're doing
something with games
and you want those
shoulder buttons
and the analogue joysticks
and everything else to work,
you'll be able to find
out about all of that.
That's at the Integrating
with Game Controllers talk
in Pacific Heights
at Tuesday at 3:15.
MapKit, of course, they
have been very busy.
There's a new Directions
API that you'll be able
to take advantage of, 3D
cameras for your maps,
map tile overlays,
snapshots of your maps.
They're working with Geodesics.
You'll be able do all of
these things in your app
for what's new in MapKit
right here Thursday at 9:00.
CoreLocations adopted the new
Bluetooth LE beacons bits,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so you'll be able to take your
device and actually turn it
into a location-based
beacon where people can find
out how far away
those beacons are.
There are some new region
types or region monitoring
and more control over the region
monitoring you've had before.
What's new in CoreLocation,
of course,
in Presidio, Thursday at 11:30.
Accessibility is a
huge deal for us.
One of the things that
we are really proud
of is making our apps as
accessible as possible for users
who are differently abled.
There's new UI-- there's new
API to be able to participate
in the Guided Access system.
So, Guided Access was a
feature introduced on iOS VI.
Now, your app can actually tell
the Guided Access system what's
available to it.
Accessibility in iOS in Pacific
Heights, Tuesday at 9:00.
If you're doing anything to
make your app more accessible,
please go this talk.
GamesCenter now also has
a new turn-based API,
so you'll be able to
better manage turns
in your application.
There's turns tabs,
modes for bidding.
New leaderboard improvements and
some system integrity features
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to make sure that
nobody is packing max
into your high score
fields anymore.
So What's New in Game Center
in Mission, Wednesday at 3:15.
There are many more talks
and many more a labs
than I can list here.
Please consult your
schedule for that.
If you have any questions
about the technologies
that we've talking about,
you know, John Geleynse
and his team here,
Jake Behrens is
of course the UI
Frameworks Evangelist,
still wearing plaid
every day this week.
And we also have, you know,
all of these fine people.
If you're interested in
games and things like that,
some of these people
are better to talk to.
So, thank you very much.
Come see us in the
labs, take advantage
for everything we've
been talking about.
Thank you.
[applause]