Core Bluetooth

Session 703 WWDC 2013

Core Bluetooth and Bluetooth Low Energy enable a new category of Bluetooth accessories which have an incredibly long battery life. With CoreBluetooth, iOS apps can talk with shoes to find out how far they’ve run and jumped, make toys come to life, fly a paper airplane, find car keys and remote controls, open a door lock, and find out why a check engine light is on. Learn what’s new in CoreBluetooth and the new ways that iOS apps can interact with Bluetooth Low Energy accessories.

[ Silence ]

Good afternoon.

How is everybody?

Really? That's exciting.

[applause] Good.

Good. Well, welcome to the afternoon of day 2 of the Worldwide Developers Conference.

My name is Brian Tucker and I am ultimately responsible for Bluetooth here at Apple and it's a honor and a privilege to spend a few minutes to talk to you guys about what we're doing specifically in CoreBluetooth, but in some sense of what we're doing in Bluetooth in general.

And in a major way where we think Bluetooth is going.

Right now, Bluetooth is just absolutely everywhere.

I'm seeing it Well, I went to a Consumer Electronic Show this winter and I literally saw Bluetooth everywhere.

I saw it in trade show booths walls.

I saw it in people's shirts.

I saw I think I saw a couple of tattoos on people's arms.

I swear. Bluetooth is literally everywhere.

So it's super, super exciting times for us to talk about this stuff.

So speaking of which, what are we going to cover?

So we're going to be covering these particular areas.

I'm going to focus a little bit on BLE and the State of Union of where BLE is currently.

We'll get into the evolution of CoreBluetooth kind of where we started to where we are today.

We'll talk about CoreBluetooth in iOS 7.

Jason is going to take you through that and some of the cool new features that I think you guys are going to dig.

Jason has a demo, a code demo on that.

He'll go through to the code tying in to some of the things that he's talking as it relates to iOS 7.

And then finally, we have some tips and best practices that we've learned by listening to you guys in the forums as well as all the phone calls and visits and conversations that we've had over the last year or so on the do's and don't's around some of this technology.

So State of the Union, so where is BLE today?

Well, I think this number pretty much says it all, a billion devices.

Right now, we're there is estimation that over a billion Bluetooth low energy devices will ship by the end of this year and that includes the last couple of years.

But that's remarkable considering this technology really kind of came in to its own just a couple of years ago.

So it's just crazy to think that we've reached this point so quickly.

In fact, if you look at the projection over our BLE devices are going to be in the market just in the next few years.

It's just up and up and up and this is conservative on my opinion.

It's absolutely amazing.

And this kind of ties into those used cases that I keep talking to you guys about, around all the areas, healthcare for example.

I mean, I was in the lab earlier today and group after group after group came up and talked to me about healthcare and it's not just one element of it.

It might be a blood glucose monitor.

It might be something that literally controls a limb attached to your leg that controls the robotics that's a part I mean it's just crazy where these products are going to go, sports and fitness, security, we talked a little bit about already, toys.

I hope all of you got to see the demo and the keynote on Monday which was awesome, and that was all Bluetooth LE, pay systems, time services, proximity.

We have some new stuff in proximity that we're going to talk about today and it's going to come up and more in a Core Location session later tomorrow I believe is when the Core Location session is.

So without further adieu, I'd like to invite up Renaud who is going just to talk about the evolution of CoreBluetooth and get us going.

So, Renaud?

[Applause]

Thank you, Brian.

So, we introduced CoreBluetooth in 2011 and we were the first ones to support Bluetooth Low Energy, the mass produced device in the market.

So if you remember in iOS 5 we introduced two classes, the CBCentralManager and CBPeripheral that allowed you to scan for devices, connect to them and then exchange it with them, which allowed you to do a lot of which a lot of applications already.

In iOS 6, we implemented the other side of the Java rule of specification which is they [inaudible] a peripheral rule and gets over rule.

And for the CBPeripheralManager, you were able to implement you on services and Field CBCentralRequest.

We also introduced for the first time or peripheral database caching mechanism which drastically improves performance especially on discovery as you may already use that in your app.

Well, iOS 7 is all about LE, Evolved.

It's about refining OAPIs based on new feedback and because we monitor, first and foremost the mailing list and the [inaudible] forums.

We also looked at all your radars that you sent us.

And we are refining OAPIs and we're also filling the gaps.

We're also putting the last remaining pieces of the puzzle to provide user-based API, so best and the simplest API you can use.

So here's what you're going to talk, a high level agenda.

We simplified Device Management in iOS 7.

We got more intelligent peripherals.

We improved performance again.

And pretty drastically again, we solved the problem of application persistence that some of you may have and we also did some built-in services right into the OS.

But before I move to these points, I want to have a discussion with you about the simulator.

In 2011, we had a simulator's report for all coverage of APIs because low energy was an emerging market.

There was almost no device available.

We were in shipping iOS devices until late in the year with iPhone 4S.

And that made development very difficult for you and for us.

Therefore, we introduced a simulator.

In 2013, nowadays, things are very different.

The market is exploding, like Brian just told you.

There are many, many LE-compatible devices on the market including all our shipping iOS hardware and most of them are hardware.

And you also have access to fantastic third-party development kits running on less fantastic OSs, but very fantastic anyway.

And as we move forward and implement more and more feature in CoreBluetooth and we're moving in a breakneck speed.

It gets harder and harder for us to give the simulator up to par with what's running on the hardware.

We cannot continue properly supporting all the [inaudible] goals that you guys may be able to buy from third parties that you can plug on your Mac.

And run it exactly as it should on an iOS device.

And for these reasons we are now seeing that we're dropping simulator support.

So best way to test CoreBluetooth is really on the iOS hardware itself with all the behaviors specific behaviors to iOS, because all hardware has specificities that a simulator cannot obtain.

So we're dropping simulator support.

I'm sorry about that.

Let's move on to the good stuff.

So I'm going to go into the major changes in the API that we are doing in iOS 7.

There's more, more There's much more that you can see.

I'm going to put that down.

There's much more in [inaudible].

But I'm going to talk about the major ones.

So first of all, like I said, we simplified device management.

And you probably all know this property.

You probably all hate this property which is UUID of CBPeripherals and CBCentrals.

Another time in 2011, we didn't have UUID class in the foundation framework.

Therefore, we use a CFUUIDRef.

Since then we now have the NSUUID and we're going to deprecate a UUID property and we have a new one which is called "IDentifier".

And which is for all intents and purposes the same value, but as a convenient NSUUID.

And also these identifiers, I know because are now going to be created at discovery, because we know that you had problems with these being created at connection time.

So they will always be there.

I guarantee it to be there and they are much more convenient to use.

So UUID is deprecated.

And so peripheral retrieval was also was always very wonky.

So UIVs retrievePeripherals method that you gave an array of UUID to [inaudible] peripherals callback comes to delegate.

Same thing for the connected peripherals, we have the same kind of asynchronous delegate callback.

This was always wonky.

We didn't like it.

You didn't like it.

So we're changing that.

In iOS 7, we're introducing a new method called retrievePeripherals WithIdentifiers.

And whereas before UUIDs are synchronous callback you had to wait for, for your objects.

Now, you don't have to do this anymore.

This is asynchronous method, it returns to you directly as the objects you want to work with.

Same thing for the connected services, we also have asynchronous method for the connected peripherals, sorry.

And you can also pass an array service you're interested in you are interested in.

So that you don't get just an anonymous list of peripheral as you get peripherals that you are only interested in.

And once you use these methods, you cans continue using your CBPeripherals like you use them before by, for example, connecting to them.

And so we saw that you guys, these are a lot of boilerplate code to find out whenever a CBPeripheral was being connected to it any point in time.

So you had your upper classes just around that, just to get this property.

And we have the folders be simple Boolean that told you whether a peripheral was connected or not.

We are deprecating that as well and we're introducing a tri-state instead that tells you whenever a peripheral is connected connected to or simply connected at any point in time.

Simple change is going to we think is going to simplify a lot of your code, is going to be great.

We also improve all service and validation API.

So for those of you that cared about that, we had this kind of bazooka callback that nukes the world service database on a peripheral or when database changed.

And that wasn't really good, because you had to restart, rediscover all services and restart all services from scratch.

Well, we have a more fine grain callback that gives you exactly which services when validated, and all services that were not been validated are still valid and you can continue using them without restarting anything.

So again you see all these all these APIs are about refining and fixing of things we that are not proper that were not proper previously.

All right.

Anyway, going to now that's finished for the API changes.

I'm going to invite Jason to the stage to talk more about new iOS 7 features.

[Applause]

Thanks Renaud.

So next I want to talk about something that's very near and dear to our heart here at Apple.

I think it's super important and that's performance.

So in iOS 7 we've made a ton if performance improvements.

And don't worry I'm not going to bore you with the details of each and everyone that we've done.

But I am going to talk about two main areas of improvement that we're really excited about and we think you guys are going to love.

The first of those is caching.

So as Renauld said earlier, we first implemented the database caching in iOS 6.

And what caching does is it allows us to remember the attributes that we find on a remote device.

So the next time one of your application wants one of those attributes, we don't have to go backout over the air.

And these lets us really make things go a lot faster and save a lot of power, 'cause we're cutting back on the unnecessary conversation.

So in iOS 6, we are currently caching two attributes, cache services and their characteristics.

And this is working really well because once you do your initial discovery it they're all in the cache and discovery will fly the next time around.

In iOS 7, we've taken the caching that we've done and we've extended it, and we've added caching for characteristic descriptors.

So now, every attribute that you can discover in a remote device's database, services, characteristics and characteristic descriptors will be automatically cached for you by the system.

So we're really excited about that.

But you might notice there is one attribute up there that's we haven't talked about yet.

That's characteristic values.

And there's a good reason for it.

So up to this point, all of the attributes that we're caching are static.

Their contents never change.

But characteristic values can be dynamic.

You see what I mean by that, you we can look at the heart rate measurement characteristic value as an example.

So right now, if you're to read that heart rate measurement characteristic value, you'd see that it's at 190 beats per minute, which by no small coincidence is right about where my own heart rate is at the moment.

But later on if you were to read it perhaps once I got off this giant stage with this bright lights in my face, you might see that it's dropped down to under 100, good thing.

So how do we cache this?

What do we do?

Well since the system doesn't know whether a characteristic value is static or dynamic.

Your application knows, because you guys are the ones who were using this service.

So what we are going to do is when we discover characteristic, if we've previously read that characteristic value, we're going to pre-fill that out when we send you the characteristic up in your discovery call.

So that if you know that you just discovered a characteristic that is static, you know it will never change, you're done.

You don't even have to issue that we're going to wait for that response.

There's nothing left for you to do.

So we're really excited about this.

We think this is this can be great for a lot of your used cases.

And the best part about this is you don't have to do anything to get this.

Just like the caching iOS 6, it's all handled automatically for you by the system.

The second performance improvement that I want to talk about is something that we've seen a lot of discussion around, and that's sending data.

So when we are first taking a look at the Bluetooth Low Energy technology, we're trying to figure out, OK, what are people going to want to do with this?

How are they going to use it?

So we're thinking its Bluetooth Low Energy, it's a packet-based protocol.

It's good for sending small amounts of data back and forth, but it's not really fast.

So people will send things like your heart rate.

Or you might send your GPS location.

And of course there are always the crazy ones out there.

And they're going to they might send something huge like all of the information for one of your contacts.

So maybe a little naive of us.

But to be fair, there were applications that sent all of those things.

But then we started seeing apps that we're sending a little bit more.

Things like photographs or they'd be thinking the week's worth of activity data.

And then we learn that some of you are successfully, I might add, using CoreBluetooth to updates to their devices.

So once we kind of got over the shock, we took a look, you know, obviously things are growing by leaps and bounds.

It's not a single heart rate value anymore it's entire files.

And we crunch some numbers.

And based on this current rate of growth, we're pretty confident that somewhere out there, there's a government contractor who's laboring a way on an application that's going to transfer the entire digital collection of the Library of Congress when you walk into the building.

Frankly, it's the scares the hell out of us.

But since some of you appear to have confused Buetooth low energy with 80211N, we figure that the least we can do is take a page from Wi-Fi and try to make things go a little faster.

So in iOS 7, we worked on improving our throughput speeds.

How do we do this?

The primary way we've done this is by implementing the MTU exchange request.

And for those of you who don't know, MTU stands for Maximum Transmission Unit.

And that's the largest amount of data that we can send in a single packet.

Now when we increase this, we can send more data in one go.

And when we're sending large amounts of data, it means we can send it more efficiently.

It might help to kind of see exactly what this means when we're talking about changing MTU.

So I'm asking you to get creative with me for a moment and we're going to imagine that when you're transferring data via CoreBluetooth, you're actually sending it by Rail.

So you have same data to send, you package it up, you take it down to the train station, throw it out on the train, the train leaves.

When you have small MTU, like what we have for the default you can put a very small amount of data on each train.

So you end up with a lot little trains, and there's a reason why you don't often see a train engine pulling a single car behind it, because it would be incredibly inefficient.

And the same holds through for our Bluetooth Low Energy.

So when we increase our MTU, like I said before, we increase the amount of data that we can send at once or put on a train if you will.

So we end up with that same train engine pulling a lot more data behind it.

So by doing this we've cut down on the overhead a ton and that allows us to send more data in the in the same amount of time.

So now in iOS 7 when you make a connection from your app to remote peripheral, one of the first things that we're going to do once that connection goes through is try to negotiate a larger MTU with that device.

And we did some internal testing while you're working on this to try to characterize the amount of speed improvement that we have seen.

So we wrote a test app that streamed large amounts of data via notifications, which is a used case that we've seen a lot of you doing.

And we saw up to a 20 percent increase in throughput speeds there.

And you don't this comes with the standard disclaimer, this is very used case dependent.

It's going to depend on a lot of things you may see less, you may see more.

Things that could affect us are your connection interval, the number of connection events, what you had for breakfast that morning, the face of the moon, you know, you name it.

There's a lot that comes in the play here, but all of this to say that it can be a very nontrivial speed boost for those of you who are sending large amounts of data.

And even if you're not you should still see a bump in kind of your standard activities like your discovery, your reads and your writes.

And again, let's save the best part of this for last, because you get this all for free, you don't have to make any changes to your application to start taking advantage of this.

So we spend a lot of time talking about how to make things faster, faster, faster, faster.

But for all of you who are familiar with the story of the Tortoise and the Hare, you know that it's not always the fastest one that wins the race.

Sometimes it's Raphael the running Teenage Mutant Ninja Turtle here.

So for all of your Tortoises out there, we're going to talk about how to give you more staying power.

But first let's take a look at the current state of multitasking with CoreBluetooth.

So today, the user launches their apps, they work well, they do everything they're supposed to, they look great while doing it, but at some point despite your valiant effort that user is going to want to do somethings else.

Depressing, I know.

They're going to background your application.

But that's OK, because that's why we came up with these two great backgrounding modes.

And your peripheral managers can continue to host their services in the database and field request from its remote central.

And this work great.

They allow your application to continue to use CoreBluetooth even when it's not on the foreground.

But as many of you may be aware, there's a problem.

Because while your application is running in the background, the system may terminate it if it needs to free up more memory for the foreground application.

So it doesn't take a computer engineer to see that there might be a problem here, because a lot of things that you guys do with CoreBluetooth are really long-term, some of these used cases can take hours, they can even take days.

If you imagine an application, a home security application that wants to reconnect to your Smart Lock when you get home in the evening, well, a lot of times if you've been using you phone heavily throughout the day, that application might not be running by the time you get back.

So the question is, "Can we allow the system to reclaim the memory that it needs while allowing your application to continue to use CoreBluetooth?"

And the answer is no.

So I'd like to thank you all for coming to our session today and we'll see you down at the lab.

No, I'm just kidding, of course, the answer is yes or we wouldn't be here right now.

And not only is it yes, but we've come up with a really simple way that we think you guys are going to love.

So what are we doing?

Well, the systems going to watch the state of your application.

It knows when it's running.

It knows when it's in the background.

And it knows when it gets terminated.

So when that happens, when it's gets terminated, we're going to look at why.

And if it's because the system needed free up more memory for the foreground app, and your application was performing some long-term action with CoreBluetooth at the time, then we're going to step in on your application's behalf and take over and we'll continue to do everything that it was doing when it was in the background.

At some point later, when you need your application again, it will bring you back and we're going to give you back everything, we bring you right back up to speed where you were before you went away.

So we're calling this So we're calling this feature State Preservations and restoration.

Those of you might be familiar with the UIKit feature the same name.

It's pretty similar conceptually.

So this is an optional feature, for those of you who don't run into the background or who aren't interested in performing long-term actions in the background, there's nothing for you to do here.

If you do care, you should know that it's fully supported by both of our manager classes, CBCentralManager and CBPeripheralManager.

And there's not much work that you need to do to adapt this.

It's pretty simple.

You're going to have to create a unique restore identifier when you instantiate your manager objects.

And you're going to have to implement a single new delegate method.

That's it.

So how does this work from the system perspective?

Well, when your application is terminated, right before it goes away, we're going to take a snap shot of everything it was doing.

Assuming it was performing some action with CoreBluetooth.

For things like central manager things this is what you are discovering, the devices that you try to connect to or you had already connected to, and all of the characteristics that you were subscribed to on these devices.

And the peripheral manager side may keep track of everything as well, what you're advertising, all the services that you'd publish in the database, and all the centrals that were subscribed to your characteristics.

So once we take the snapshot, your application is still terminated, it's no longer running.

But like I said, we've stepped in and we're doing everything on its behalf.

And we said that at some point, something is going to happen and we said we'd bring you back.

So any event that the system either can't handle without you or that you need to know about will trigger us to re-launch your application.

And these are things like that peripheral you're trying to connect to finally completed or someone subscribed to a characteristic that you're hosting, or your got an update to a characteristic that your were subscribed on.

And at that point we'll re-launch you back into the background where you were.

And allow you to run for a short period of time.

The application is then going to reinstantiate all the managers that I was using before it went away.

It's going to get that one delegate callback where we give you back all the state that we're keeping track of for you.

And then it's kind of business as usual.

You'll see that power on event in your didUpdateState callback.

And you're going to get whatever event triggered us to re-launch and you'll get that delegate callback as normal.

So I know it might seem like there a lot of moving pieces here, but I said it was simple and I'd never lead you astray.

So I'm going to show you how simple it is by taking an existing background capable application and adding support for state preservation and restoration.

[ Pause ]

All right, so here is our app and it's a very simple heart rate monitor application, it looks for all the heart rate monitor devices that are near you.

It connects to them and it finds and subscribes to the heart rate at heart rate measurement characteristics that we looked at earlier.

It's been pretty stripped down just for illustrative purposes for this demo.

But it should look pretty familiar for any of you who have worked with the CBCentralManager and CBPeripheral classes before.

So before we get started, I'm just going to take you in kind of a quick tour through the code here so you can see what we're working with before we start making changes.

So this is a single view controller.

Like I said very simple application.

Down here in viewDidLoad where the magic starts, you can see that we instantiate out central manager single central manager object.

And this object is going to be around for the lifetime of our application.

So as you all know after we instantiate our manager, we're the first thing that we're going to get is a callback on didUpdateState.

So in this situation when we see that the state has been powered on, we simply begin scanning for devices that are advertising the heart rate service.

At this point when we find the device, we're going to get a callback to didDiscoverPeripheral.

And there are a couple of things that I wanted point out in here.

So the first is that you can see here, we have a list we keep a list of heart rate monitor devices around.

So when you find a device and you want to use that device, you need to keep a reference to it.

So the system knows, "Hey, this application is trying to use this device, we better keep it around.

So we looked to see if we have this OS in our list; and if not, we put it in there.

And at that point we call connect.net [phonetic].

Hopefully, later on that connection will complete and we'll get our didConnectPeripheral callback.

And at this point we simply set the delegate and then we move on to kind of the service interaction part of our phase of our application.

The first thing we do is we simply discover services and we're only interested that heart rate service, pretty straightforward.

Later on when the command completes, we'll get our didDiscoverServices callback.

We're going to look and see, hey, were we able to find the service?

And if so, the next step we're going to look for that heart rate measurement characteristic.

Once that completes, again, we're going to check to see, were we able to find it, and we're simply going to call set notify value to subscribe updates on it.

Later on when that value changes, the peripheral will send us the new updated value, we'll get a didUpdateValue for characteristic callback.

And since this is such a simple app, we're not really doing anything here other than logging that information.

OK, so I said this is a background capable app, of course it wants to do all of this in the background.

So we're going to go to the info.plist here and see that it is in fact specified the correct required background mode, app communicates using CoreBluetooth, which as you all know is the appropriate one.

We're going to be using a CBCentralManager and you want to continue using peripherals while in the background.

So one thing I want to note, you notice that even though this application is geared toward CBCentralManager, everything that we're going to talk about here for this preservation and restoration feature applies equally to peripheral manages as well.

So the first thing that it said before was that this is an optional feature, so we need the opt-in.

And we're going to go back down to this viewDidLoad here where we instantiate our central manger object.

And we're going to move it to a new init method.

It looks pretty much the same as the old one, but now we've got this options dictionary on the end and we need to provide a single new option for this and that's our restore identifier.

So by providing this restore identifier key, we're doing two things.

One, we are telling the system and the application, we're giving them a way to uniquely refer to this specific manager.

The second thing that we're doing is telling the system, "Hey, I want to support this feature."

So I need to give it a restore identifier and I like to just do something descriptive here, something like heart rate central since this is a central manager we're using to find heart rate devices.

You can name it whatever you want.

The only thing that you need to be aware of is that it should be unique within your application.

If you give two managers the same restore identifier, both the system and your app is aren't going to able to know which is which.

OK, so now, we've opted-in.

And I said, the second thing that we needed to do was to implement our new delegate method.

And that delegate method is central manager will restore a state.

When the system is persisting some sort of long-term action on your behalf like we talked about earlier and something happens that we decide to re-launch your application, this is the very first delegate method that will be called.

Let me reiterate because this is important.

This is the very first delegate method.

No longer is it didUpdateState.

If you are restored, you will first get a call to will restore state and that's your application's chance to bring itself back up to speed with what has been going on in the system because it has been gone, it doesn't know.

So, we're going to get back a variety of things in this.

And the first thing that we'll do in this application, we're always scanning.

So we are scanning from the background.

When our application got terminated, we are still scanning.

The system stepped in and continued scanning in our behalf.

So now, when we're coming back, that scanning is still happening.

So, we can see the services that we're scanning for and the scan options that we provided to the scan call.

Again, in the case of this app, since we're always scanning and we're always scanning for the same thing this is already kind of expected.

We don't really need to do anything with this.

The next thing that we're going to back is a list of all of the devices that we had tried to connect to or were connected to.

So, in this situation we actually do care about these because in this app once we find a device we add it to our list of Heart Rate devices because we need to keep a reference to it.

So, here we're coming back starting up with devices that we may already be connected to.

So, they again we need to keep a reference to them and they're going to go on our list.

So, we just go through any peripherals that were restored with, go right back into that Heart Rate Peripheral list and we set the delegate.

Now, for some of your applications this might be enough, really simple we haven't done a lot here but there are two other things that and one in particular that you really should at least think about.

And the next thing that I want to take a look at is our initialization process for this application because before we started supporting this feature, every time our application started up we'd be starting up with a clean slate.

Now that we support restoration, we might be getting restored with stuff that's still happening on our behalf in this system.

So, we're going to go to a Data Update State Method here and pretend that we've just been restored.

So, we've gotten that call to Will Restore State.

So, as we saw before when power goes on the first we do is start scanning.

If we've been restored we're already scanning, in this situation calling up one more time isn't really going to hurt anything.

It'll actually be optimized a way anyway because we're providing the exact same parameters as we were as we're already scanning with.

So, it's OK to leave it, we don't need to get too tricky here.

But the next thing that we want to do is because we may have been restored with those peripherals, we're going to take a look and see, do I already have connected peripherals.

So, I might not like I said, we might not be starting with that clean slate anymore.

So, we're going to look through our list of Heart Rate peripherals and see "Am I connected to this device?"

And now, if we really want to be robust which I do because I'm trying to set a good example here for all of you, we could've have gone away at any point during that kind of initialization discovery process that we do when we connect to a device.

So, we need to be able to handle that but it's really really quite simple.

So, the first thing that we'll do is we'll look and we're going to see have we discovered that Heart Rate Service.

If not, that's our starting point we just got something go discover that service and everything will kind of fall back through that state machine.

Next, we're going to look and see, OK, have we discovered the Heart Rate measurement characteristic?

Again, if not, that's where we know we need to begin by trying to discover that characteristic.

And finally, we're going to look and see, are we subscribed for updates on that characteristic?

And if we are, we're done.

We don't need to do anything else, we've done restored, we're still connected to that Heart Rate device and we're still subscribed in our app as back up to speed with everything.

It's just got away for updates.

Now, there may be one more thing that you need to consider for those of you who have multiple managers or maybe you have a manager that isn't always around.

So, you instantiate it sometimes in your app and get rid of it.

You might be wondering, this all looks great but if I have to instantiate my manager in order to restore it, how do I know what manager I need to instantiate?

Very good question.

And the answer to that is in your application delegate, in this did finish launching with options method.

Because when we're relaunching you, we will give you back the list of all of the identifiers representing the restored managers that we've been keeping track off for you in this system.

So, you can see that you can retrieve all the identifiers for the peripheral managers that you were using at the time you went away and the central managers.

In this application, we don't care again about peripheral managers as we're only using a central manager.

And we're going to go through and what you need to do at this point is tell your application, "Hey, these are the managers that I need to reinstantiate.

If you don't reinstantiate a manager that is being preserved for you in the system, after a reasonable amount of time, the system is going to assume that, "Hey, he must not want this anymore and we're going to clean it up for you."

So, any long term actions that was still performing, those will stop at that point in time.

In the case of this app, we have been lucky there's nothing for us to here because like I said we have one manager and it's around for the lifetime of the application.

So, it's a this is pretty simple, just a recap, we've the first thing that we did was look at our central manager, we changed the initialization call to provide a restore identifier for it.

We implemented that single new delegate method will restore state which gives our application a chance to kind of get back into sync with what has been going on in the system.

And then we took at look at our initialization process and did update state.

And we made sure to be able to that we're able to handle possibly starting up with devices that we're already connected.

And I also show you guys how to handle the possibility where you have multiple multiple managers being restored.

So, that's it, hopefully you agree that there's not a whole lot of code involved here.

This isn't as complicated as it may have seen.

And, you know, with this little amount of change to our application, we now don't have to worry about being killed in the background.

So, I'd like to invite Renaud back up here.

And he's going to talk to you about the great new built in services in iOS 7.

So, Bluetooth Low Energy has been around for a few years now.

Four years if I count correctly.

And as you see you guys come up, we start our profiles already for it.

And we feel the technology is mature enough now and our stack is mature enough that we can make this directly into the system, and that's what we're going to do with iOS 7.

So, what did we do?

So, first of all we implemented some services when we act as a GATT client and this is basically a HID Over GATT Profile as we talked about this morning in the accessory session.

The HID Over GATT Profile which is a bad name implements these free services.

These are the HID service, the battery service and the Device Information service.

What's special about that and the fact that it's built into a system is that it works just like Bluetooth Classic devices.

So, you will be able to discover Bluetooth flow energy HID devices directly from the Bluetooth settings pane like a Bluetooth Classic would be.

And once you are paired with Bluetooth Energy HID Device, iOS will automatically manage the connection and reconnect to it if the connection goes away therefore giving this illusion that it works just like a normal Bluetooth device that customers are used to.

So, that's what we use on the GATT client side.

But we have also interesting things on the GATT server side.

So, if you connect your accessory to an iOS device and you implements have GATT clients roll.

And you discover services on an iOS device you will now be able to see these services implemented.

And first of all we have the battery service which is trivial, I'm not going to spend much time on it.

We also implemented the current time service which is a nifty service if your accessory requires an accurate source of time, we provide accurate time and date and the time zone information.

So, for example, things like watches can use that.

But there's one more thing an iOS dream, I'm saying that on stage.

And this one more thing is about Notifications.

We've seen especially in the last year a lot of accessories going on the markets, the so called "Companion Devices" that are for example smart watch that are all about displaying to you or relaying notifications that are happening on your iOS device.

But they all use methods to access the notifications that I'm not very good for your hockey and all that and you guys probably know what I'm talking about.

But these are three other command solutions that are being used nowadays.

So, first one is the Message Access Pro or the Message Access Profile also commonly known as MAP over Bluetooth Classic.

The problem with MAP is that it was developed originally for an automative usage.

It was not meant to be used by a small smart watch on your wrist.

And it actually doesn't it's very constraint, it only does SMS's, MMS's and E-mails very well, anything else that you pass of a MAP is ugly and it's not going to go over well.

There is also low energy's profiles that have come up from the [inaudible] for example is the Alert Notification Service.

The problem with it is that it is very, very limited, it's very simple and it's too simple, it's not good enough.

There's also a full solution that we've seen a lot which is you guys developed a custom application tailored to your specific accessory.

And those problems are obvious we've did this solution as well which is that when it's heavyweight, you have to Run a full iOS app and any point on the customer's device which is not very good.

And your data you are able to send through this method is also limited to what the app and send both allows and what the customer allows you that your app to see which is not much as you may know.

So, all the solutions are not very good and that's a state as it is now but we come up with all solution that we think you're going to love.

And the solution we call it the Apple Notification Center Service also known as ANCS, I may say ANCS in the next few minutes.

This is also a GATT server service.

So again, if your accessory connects to the nearest device and discover services on it, it will see this service implemented on it.

It is Apple's specific uses on [inaudible] 128 bits UUIDs.

And it basically allows you to be notified about any kind of event on your phone.

And that's includes all the phone functionality events, for example your incoming calls and your voice mails.

It notifies you about your IMs and all the messages you can get for Facebook or anything else.

It notifies you about calendar.

For example if you are in 5 minutes it will be carried over this information would be carried over this service.

And what I'm getting at basically is that I need notification and notification center will be carried over this service.

There's no preferential treatment, anything which is in notification center will be sent over this service.

You have full access to anything that's will be notifiable on iOS by default.

And again, like the HID service I just talked to you about, once an accessory has been recognized as using ANCS, iOS would automatically manage a connection and reconnect for you.

So, your app doesn't have to do that anymore.

We will do that for you.

So, detailed specification will be posted on the developers portal soon.

We still have a few things to work-out.

But look forward to that and, well, [inaudible] is going to be out really soon.

But before I finish that, I just want to give you like a sneak peek of the mechanisms on who it works and you will see it's really simple and straightforward.

It's not complex at all.

But it [inaudible] very powerful.

So, let's take the used case of an iPhone connected to a smart watch.

For example, in this case a very blue smart watch.

And the user just received a new iMessage.

Well, we will send a message over ANCS telling you that the user just received a so-called new social notification and we will create a UUID for this notification which is going to [inaudible] a handle to retrieve more information about it.

In this case, we just use one.

And the accessory as supposedly to retrieve more information about this notification which is exactly what it does now where it can go back and ask for attributes.

In this example, it wants the title and message.

There's a list of attribute to provide.

In this case, we just want two.

And iPhone will provide all this information to your accessory.

In this case it's the title is actually the sender of the iMessage and the message is the body of iMessage and it's Jason because Jason is part is looking to get beers pretty soon.

Of course at this point your accessory is free to do whatever it want.

You can blink an LED or you can displays the entirety of the message and a big display.

Whatever you accessory implements, it's up to you at this point.

Later on when the iMessages is read or the notification is dismissed on the device, we will also notify the accessory that this notification is now invalid and you're free to dismiss the alert on your device as well.

So, a full synchronization mechanism between notification center and all these events and your accessory and as pretty much ANCS and this was just a sneak peek, it's capable of much, much more it's very powerful, very simple as well.

We try to keep it simple and look forward to that onto the developer portals again.

I just want to quickly finish by some tips and best practices that I've come up by monitoring the developer forums and, you know, and getting your radars because radar [inaudible] is not a black hole as I assure you, all the radar you filed they're going all queue and we looked at everyone of them.

So, here are some few tips and best practices some common mishaps and pitfalls you guys tend to fall in to.

So, I just I just want you to keep track of that.

So, first of all, like we said before, CoreBluetooth needs to know if you intend CBPeripherals.

Please keep a reference to them.

If a CBPeripheral gets locked, we will assume you are not interested in it and the system will take action in your behalf including disconnecting the peripheral implicitly because we do not want to making that connection that is not used by your system at all.

So, keep a reference, it is something that a lot of you probably made the mistake, it's the first time you use CoreBluetooth.

Scan request and connection request never time out and you needed to call them once.

So, it's like an elevator button.

You don't need to press them multiple times.

It's not going to go any faster.

And actually it might be detriment or to the speed of your action.

So, just call it once and everything will work fine.

We'll take care of the rest for you.

It wasn't explicit before but now it's explicit.

CBPeripherals and CBCentrals conform to NSCopying.

And actually most CB objects can be used as NSDictionary keys.

We've seen a lot of you guys using an indirect map between UUIDs and CB objects and all of that.

Just use the CB objects as dictionary keys.

It simplifies a lot of the codes.

I know I simplify a lot of my code by doing that.

So, please just use that as keys and you'll see it's great.

Please, please do not touch the Client Configuration Characteristic Descriptor directly.

This is not going to work and you guys may already have tried that.

These are not going to work.

This is going to break the state in the application.

So, we have an API for that whether set notify value for descriptor which for characteristic, sorry, which is much easier to use and it's going to work instead of that.

Please, please do not game the background mechanisms.

We are not stupid.

We know it's the kind of tricks you guys are using and if you start using them or you continue using them, you're going to get in trouble eventually.

And we hope that we what we introduce today with iOS 7, you will have all the tools and APIs especially with application restoration, things that Jason have told about.

You have all to the tools for you to not have to use these nasty tricks that nobody likes.

We don't like them.

You don't like them.

We know we've provided you everything.

We hope that that you don't need to do that anymore.

And that's it for my tips and best practices session.

And I'm going call back Brian to have the final words.

Pretty amazing stuff, right?

I mean this this in my mind makes CoreBluetooth really the launching platform for really major initiates in Bluetooth Low Energy.

I'm thrilled that we've finally got this stuff in there.

And with the stuff around restoration, you know, preservation and restoration, it completely opens up markets that we know that you guys have tried to participate in.

But now from a consumer's perspective it should work all the time.

It should be 100 percent up all the time.

Every time I walk in front of my home door, it unlocks, right.

Every time that my blood glucose monitor takes reading, my phone knows about it.

And it's not going to work some of the time and not work the other time.

It's now completely bulletproof, consumer-ready, you know, industry leading technology.

And we're super, super excited to bring it to you.

The other thing around Apple Notification Center Service, affectionately called ANCS, is we feel like that that's going to make this [inaudible] products sing and the things that you guys are going to be doing with this.

It doesn't matter if it's a watch like Renaud showed here or something as simple as fashion or jewelry that lights up when you get a text message from your significant other or your child, the things that you guys can make with these things is just going to be awesome and I can't wait to see that.

One thing, I will note on Jason and Renaud, these guys wrote in part CoreBluetooth.

So, these, you cannot hear from anybody more expert in this particular topics.

And both of them will be in the lab this afternoon to answer any questions you may have.

We also have folks like Gus [phonetic] is here who is our senior engineer for all of our Bluetooth server and stack.

Ardy Kumar is here which is one of our audio experts.

We have you know industry leading engineering in this area and they're all here to answer questions for you.

So, if you do have more questions definitely come down into the lab after this session and we would love to help you guys out.

One other question that we get a lot and I don't have a slide for it here but I just wanted to cover it really quick is I get a lot of people asking me, "How do I submit apps that use CoreBluetooth and talk to Bluetooth Low Energy hardware?

And so, the App Store folks have asked me to just give you a couple of suggestions.

When you submit an app that's using a Bluetooth Low Energy device, send the device in as well.

And when you send that device in, the extremely explicit and exactly what that device does, you could provide the services and characteristics that device implements.

Give it the you know describe exactly what the device does.

How to use that device?

A lot of times we'll get a device and it's like a big trunk of plastic and there're not buttons and it's like, OK, that's great, you know.

And it goes on a shelf somewhere.

So, just be explicit in providing that information to us when you send those apps.

And if you have more questions on this, a lot of guys from our [inaudible] team will be in the lab as well to answer some of those questions in more detail as much as they possibly can.

As always our Bluetooth guidelines document is online.

You can search for this pretty much anywhere and it's available if you go in our developer site.

It's absolutely super easy to find.

We constantly keep this updated and this is being updated as we speak.

I don't know if an update is online yet.

Hopefully, it'll be very, very soon.

And in addition to that, for the first time, we now have a CoreBluetooth programming guide or reference manual, finally.

It took us awhile to get this done.

But we have some awesome writers working on this and I know that they have a little bit more work to do to incorporate some of the new things that we've implemented in iOS 7.

But this will be available very, very soon on the developer portal as well.

So, definitely check it out as soon it's there.

It's going to be a huge, huge reference of you guys not only the kind of introduce you the lot of the key concepts that we brought up today.

But then it'll go into lot of the reference around that the actual code and implementation details.

So, check it out.

For more information, we have these people who eat and breathe this stuff.

Craig and Stephen, both of them are awesome guys.

They love to answer any questions you may have around CoreBluetooth or Bluetooth in general.

We also have the developer program, DTS.

It's a little bit more formal.

You're going to get a guaranteed response with that.

Our developer programs, MFI, we briefly talk about that in our session this morning.

You're going to get for more information from those guys at our MFI web landing page on the developer site.

In addition of that, all these other things, the one thing I want to iterate right now before we go any further is right now you guys having your hands hopefully all of you have updated your devices to iOS 7.

You have the new SDK.

You're playing around with it and you're going to come to the lab with all of your code in hand and work with those on that.

And if you haven't, we're going to have another lab on Thursday.

So, hopefully that gives you a couple of more nights to work through upgrading your code.

But bring that to us, if for whatever reason you can't make it, or even if you can make it and you find what you think are bugs, report those bugs especially right now.

This is the time to get those bugs to as so that we can investigate these issues and get them resolve as quickly as possible.

And if by the way send an email to Craig or Stephen as well just to let them know, hey, I found this issue, it's the problem.

The developer forums are both active, very active for iOS and Mac.

We have a great community in that space that you guys are helping each other to solve a lot of these problems.

We personally cannot respond to everything that's going on in those forms.

But rest assured we read every single post.

I personally read every single post in those spaces.

I can't always respond but I love hearing the feedback.

And certainly we take all that information and internalize it.

As far as what's going on, with other sessions.

There was a session this morning you cannot go back in time.

If you can, good for you.

But if you can't, you can watch this later.

The WWDC app is making a lot of these sessions available almost instantly.

So, definitely go check it out.

And then we didn't talk a whole lot about proximity.

Well, because they're talking about that in Core Location.

We felt like that's a location services technology and the Core Location guys should really go into that.

There is a session on Thursday that you guys should check out.

So, I want close was just talking about these used cases again.

And I want to kind of reiterate how important we think Bluetooth Low Energy is to the future of accessory communications.

I mean all of these used cases are profoundly important to the consumer.

And when they have iOS products in their hand and it just naturally communicates with these devices we really are starting to realize this concept of the internet of things.

And it's just incredibly powerful.

And it's super, super exciting to be an engineer working in communications because of the nature the fact that we can now truly put a radio in everything around us and have it fully integrate with the consumer's applications in their devices.

And ultimately it means this idea of connecting the world that we can connect all these devices in this heterogeneous ecosystem that's just going to create incredibly profound experiences for our customers.

So, with that, I'd like to thank you for coming for our session.

Enjoy WWDC.

We'll see you guys in the lab.

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