Core OS • iOS, OS X • 43:52
In addition to providing services to iOS devices, Bluetooth LE peripherals can also use services provided by iOS devices. Learn how to advertise Bluetooth LE services in your iOS apps.
Speakers: Khrob Edmonds, Joakim Linde
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good afternoon and welcome. My name is Joakiim Linde and I'm here to talk to you about the Core Bluetooth framework. In iOS 5, we introduced the Core Bluetooth framework with support for Bluetooth Low Energy. We got a tremendous response from you, so thank you, especially from the sports and fitness industry and the mobile health industry. In iOS 6, we're introducing some new and exciting functionality targeted towards social media and proximity sensing.
At the end of this presentation, you will see a demonstration showing two iPhones exchanging data wirelessly, triggered by proximity sensing. We think this is very exciting, and we're sure this will help your application and the relationship that you're trying to build with app developers. But before we show the demo, I'd like to introduce to you the Core Bluetooth framework.
We'll start with covering the object model. Brian talked a little bit about this in the morning session. Then we're going to talk about the two roles: the central role, that's also the client, and the peripheral role, that's the server. After that, we're going to dive in and talk a little bit about tips and tricks and reminders. We got a lot of feedback from you guys over the past year about this. We're going to move on and talk about iOS backgrounding, how to discover devices efficiently, and this concept called pairing. Then we're going to wrap up with a demo.
So let's dive right in. The Core Bluetooth implements support for the Bluetooth low energy protocol stack. We're not going to bore you with all the details of the Bluetooth low energy stack. We've taken care of all of that so you can focus on just using it in your application.
And the Core Bluetooth framework provides a fairly complete API so your application can make use of the Bluetooth low energy technology. The key thing with the Core Bluetooth framework is it gives you, the app developer, control over almost everything. It puts the application in total control so it can make use of the Bluetooth Low Energy as best as possible.
So let's dive in and take a look at some key concepts. We have the central role and then we have the peripheral role. The central role is normally implemented on a Mac or on an iPhone or an iPad. And the peripheral role is, for instance, a heart rate monitor or some other accessibility or some other accessory. New in iOS 6 is that we now support for the peripheral role built into iOS as well.
So the peripheral is the one serving up data. So it acts as the server. And the central is the one consuming the data. And this acts as the client. This is a similar relationship as we have with web browsing, where the web server serves the data and we as the client gets the data.
How do we implement this on the Core Bluetooth object framework? The central side is represented by a CB central manager object. This is the object where you control your local central. The remote side, the peripheral, is represented by a CB peripheral object. The same way on the peripheral side we have a CB peripheral manager that implements the local peripheral.
And this is the object that you interact with when you try to interact with your client. You interact with this peripheral on your local device. And the remote side, the CB central in this case, is represented by the CB central object. So that was the main objects of the Core Bluetooth object model.
As Brian mentioned in the earlier talk, we have a couple of other objects as well. Data objects. And this is where we have to introduce the concept of a characteristic and the service. A characteristic is basically a fancy name for a variable. And the variable has a value. You can take these characteristics and group them together into a service. And we use the CB service object to represent that group. We also have immutable versions of these and mutable versions of them.
and we're going to take a look at the mutable versions when we dive into the peripheral side. We also have a couple of helper objects. Everything is represented by UUIDs in Core Bluetooth. So we have a dedicated object for that, the CBUUID object. And then we have a request object that you get when you do read and write. So we're going to get to those in a sec.
So let's dive in and look at the central. There's three easy steps. First one is, you have to discover
[Transcript missing]
running iOS 6, or even a thermostat that's sitting on the wall in this room. All of these devices can be peripherals. They all send out advertising packets.
So we can find them. And they sit there. The heart rate monitor sends out an advertising packet. The iOS 6 device sends out advertising packets if it's in peripheral mode. Or the thermostat on the wall sends out these advertising packets. That's how we find these devices. And we as a central in this case, just sit back, open up a receiver and start listening for these devices, these advertising packets.
So how would we implement the central role in the Core Bluetooth framework? Well, it's a fully asynchronous interface. So we have our CB central manager object, and it has a delegate where we get the callback. And we start by saying, calling the method scan for peripherals with services on the CB Central Manager.
When we call this, we can say we can scan for every single devices that are out there and we get to receive all advertising packets, or we can be a little bit smart about it and say, I'm only interested in devices that has a certain service, and that service is represented by a UUID. So for instance, if I'm only looking for heart rate monitor belts, I just specify the UUID for heart rate monitor service.
The radio will go off and start listening for these devices and do the filtering for you. and you're going to get a number of callbacks, one for each advertising packet that we receive. Did discover peripheral. With that callback, we also get a CB peripheral object that you can use if you want to connect to this device.
Once you've found a device that you're interested in, you stop scanning. So we don't have to spend any power opening up our radio anymore, listening for devices. And call Connect Peripheral, supplying the CP peripheral that you just got with the Did Discover Peripheral callback. Since we just recently saw this device, we now know that it's fairly close by and setting up a connection to it is going to be fairly quick. And once a connection is set up, you get a callback, "Did connect peripheral?" We've discovered the device, we've set up a connection to it, and we're now ready to start exploring this device.
So, as Brian talked about in the morning, this peripheral contains a tree structure of services and characteristics. And what we're going to do is try to replicate that or copy that tree structure to our local device so we can start interacting. We're going to use these objects so we can read and write to them.
As an example of that is, for instance, in a heart rate monitor, you can have a service, the heart rate monitor service. It can have two characteristics or variables, one of them being the heart rate and the second one being the body sensor location. This is where on your body this heart rate monitor is located. It could be over the chest, on your arm, on your finger, on your hand, earlobe or foot. Let's see how we do this in Core Bluetooth. Now we're going to start interacting with the CB peripheral object that we got earlier.
and we call the method Discover Services. We can of course ask for all services, but we can be smart about it. If we're just interested in the heart rate monitor service, we just ask for that specific service. Core Bluetooth now goes over the air and gets the data back and you get a call back, "Did discover services?" Now you can call "Discover characteristics for service" and asking the system to fetch all the characteristics, or in the heart rate monitor case, the two characteristics.
Ask the system to fetch those and once those are available, you get "Did discover characteristics?" Next, we're going to take a look at how to interact with a device. So now we have set up a connection to it, we discover the services, and now we take one of these characteristics that's under a service, and we can start reading and writing that variable.
So for instance, if I want to read where on my body this body sensor location is located, I can call read value for characteristics. The read request goes out to the device, fetches the value for that variable or characteristic, and you get a callback, did update value for characteristic. And that works fine if you're just going to read it once. But in the case of my heart rate, I don't really want to read it every single time.
Instead, I'd like the heart rate monitor to send me an updated value whenever there is an updated value. Normally, heart rate monitors measure the heart rate about once a second. So I want to tell the heart rate monitor that I'm interested in this value, so please notify me when it changes.
So I do that by calling the method setNotifyValue for characteristic. Now the heart rate monitor knows that whenever the heart rate monitor changes or whenever I have a new measurement for this value, You get a callback, "Did update value for characteristic?" This is kind of cool. Your application just sits back and relaxes and waits for these values to come in. You don't have to worry about, "Oh, should I pull it again?" and all this.
So instead, sit back, relax. When there's a new value coming in, you can update the UI, you can log this value, do what you want with it. So far we talked about how to discover, explore, and interact with a device. Now we're going to talk about how to reconnect to a device. So there's three ways.
to reconnect to a device. The first one is scan and connect. And this is what we just did. We scanned for the device to see if it's around and then connected to it. The second is you can reconnect to this device using a UUID. And you go UUID again. Would it be better to use a Bluetooth address here and refer to it? Well, Bluetooth addressing is kind of complicated in Bluetooth Low Energy.
The address changes over time and we do that to obfuscate things. So instead we've abstracted all of this away for you and all you need is a UUID to represent that device. You can take this UUID, store it somewhere, and then a couple of days later come back and say I want to reconnect to this device.
And the third way is another app running on the phone. And the phone might already have set up a connection to that peripheral. So you can go and ask what other connections exist and maybe I should use one of those. So let's dive in and take a look at number two, how we would do that in the Khrob Bluetooth framework. Option three, I let you guys do that as an exercise at home.
So we have this UUID representing the peripheral that we want to connect to. Now I need to take that UUID and go to a factory. So they can produce a CB peripheral object for me that I can use to call connect peripheral. And the way I do that is I call retrieve peripherals, supplying the UUID of the device that I'm interested in. And I get a call back, did retrieve peripherals.
with a CB peripheral object that I now can take and call Connect Peripheral. Since we didn't see the peripheral through advertising, we don't know if that peripheral is around. So when you call Connect Peripheral, that could take a while. It could take an hour, a day, or even a week. The cool thing with this is next time iOS sees this device somewhere around, we will call So your application gets to know that the peripheral is now available and you can start doing data with it.
So far, we've been very much focused on the central side. The central could be a Mac or an iPhone. What we're going to do now is move on and take a look at the peripheral side and how we can implement the peripheral side on an iOS 6 device.
So implementing a peripheral device allows a Mac to talk to an iPhone. It also allows an iPhone to talk to another iPhone. And the cool thing is, this is while your app is in the background. We're going to talk a little bit later about more about backgrounding and how that is done.
Let's start with taking a look at how we're going to implement the peripheral side. So there's three easy steps. The first one is we have to build our tree with services and characteristics. The second one is we have to take that tree and publish it and start advertising, sending out these advertising packets. And the third thing is sit back and wait for the read request or write request to come in for these variables and characteristics that we just published.
So the first thing is we have to build the tree. And this is where the new CBMutable services and CBMutable characteristics comes in place. So we start by instantiating a CBMutable service, and then we instantiate one CBMutable characteristic for each of the variables that we would like to publish.
So these variables, we can have static data in those variables, and we can have dynamic data in those variables. If it's static data, we can supply it with the tree when we build it. It's not going to change. We can just attach it up at that point in time. That means that CoreOS, if there's a read request coming in, Core Bluetooth will take care of that read request and respond to that automatically.
If you have dynamic data, You can't really supply it at this point. So for instance, in the heart rate monitor case, you just supply nil and the Core Bluetooth framework will give you a callback when that data is being asked for and you can supply it at that point in time. So next is we have to start advertising to the world, tell the world we put this nice tree together and start advertising it, sending out these advertising packets. How do we do that in Core Bluetooth? Well, now we're going to start interacting with the CB Peripheral Manager.
We're going to call add service. We're going to supply the tree that we just bid with the service and the number of characteristics. Core Bluetooth then goes off and does some checking on it and makes sure that everything is fine and you get a callback saying "did add service". Now the tree is installed. Now we need to start sending out these advertising packets.
We do that by calling start advertising. You also supply the content of the advertising packets that are going to be sent out. We're going to talk about that in a couple of slides later. But for now... Here's how you start sending out the advertising packets. You get a notification coming back saying, "Did start advertising," and you're all set. You publish your tree.
You started advertising, now you're ready to just sit back and wait for requests coming in. So we have this peripheral, it's an iOS 6 device, sending out advertising packets to another iPhone. That other iPhone says, "Oh, this looks like an interesting device. I'll set up a connection to it and start exploring it, see what services and characteristics is available there."
Until it hits a characteristic that has dynamic data in it, and in that case it has to start asking your application for what the value of that data is. Your application starts with getting a notification on the delegate saying "Central did connect". And then when it's a read to one of these dynamic variables, you get a "Did receive read request". This is the time when you take the request and you respond to it, respond to request, and you supply the value.
This loop can continue now for a number of times. It can read one characteristic or read a number of characteristics until the central says, I've got the information that I was looking for, and it disconnects. And you get a notification about that as well. Central did disconnect. We talked about earlier that there is another way of doing this, that you can actually subscribe to these notifications instead. So the way that is done in Core Bluetooth is that you see that the central connected, you get a call, central did connect.
And then a center can say, I want to know whenever this characteristic or this variable changes. You get to know, because a delegate will be called, the did subscribe to characteristic delegate will be called. That's a cue to your app to start supplying updates to this variable on a regular basis to the central on the other device. And you do that by calling update value. You can do that a number of times until the central says, it's time for me to disconnect and go away. So you get a notification saying the central did disconnect.
And at that point, there's no one interested in this value anymore, so you stop calling update value. So all of this, we can have an iPhone talking to another iPhone while the app is background. And we think this is pretty cool, and we're sure this will tickle some imagination of yours, and you will come up with really, really cool applications for this. So let's dive in and talk a little bit about what we've learned over the past year. We've got tremendous feedback from you guys. And we're going to start by looking at iOS background.
We allow application to do Almost anything in Core Bluetooth while they're backgrounded. They can scan for devices, they can advertise in the background, they can even connect to other devices while the app is in the background. And it can interact with other devices while the app is in the background.
Of course, this consumes power on the device, so we want to make sure that the user is aware that this is going on. This is why we ask of you to have a start and stop concept in the UI. The user can say, "Yes, I want to start it, and yes, I want to stop it."
You also have to put some magic words in the Info.plist so we can grant you this privilege. But we ask of you to be very, please be mindful. We're giving you a lot of power. Your application is allowed to run in the background. You can go off and do all this cool stuff. But please, we ask of you not to access the internet more than every 15 to 30 minutes to preserve battery of the iOS device. We give you a lot of power, so please be mindful. So we have this foregrounded apps, and we have backgrounded apps.
And when an app is in the foreground and it's trying to discover devices around it, we go off and do a high intensity scanning. And it's basically, we know the user is looking at the screen, the screen is on, and it's expecting results. So we turn on the radio. and really scan with a high intensity. When the app goes in the background, or when the screen is off, we use low intensity scanning to save power.
We want you to be aware that when your app is in the background, that it takes longer to discover devices. It takes longer to connect and see what's around you. One thing, if you're an accessory manufacturer, one thing that you can do To help is to really advertise with a short advertising interval. Sending these advertising packets out very, very often will help The application finds you even when it's in the background.
So imagine I have this heart rate monitor. And I put it on, it starts advertising. And I have my phone. and I would like the application sitting in the background on the phone to pick up my heart rate monitor as quick as possible. For it to pick it up, we suggest that you advertise about every 20 milliseconds with a really high intensity. You don't have to do it for forever, but maybe for a couple of minutes. And then go back to low intensity advertising. So if you are Accessory Developer, please advertise often when you want us to discover your device.
[Transcript missing]
Name of my heart rate monitor, saying this is Joakiim's heart rate monitor. Or if it's a thermostat on the wall, it could contain the name of the room. The advertising packet also contains the transmit power at which this advertising packet was sent. This is kind of convenient because in the Core Bluetooth API, every single advertising packet we let you know about, we also supply you the RSSI value, the read signal strength, the received signal strength at which it was received.
You can use these values to figure out the approximate distance to the device. You can see if it's very, very close or far, far away. We think this is pretty cool and you will see this in the demo that Khrob is going to do in a couple of minutes here.
It would be sad if we had to connect to every single device to figure out what services it provides. It could be kind of a bad experience, have to connect to it and then connect to the next one. So instead, you can put the most important service, this one service that you want everybody to know about, in the advertising packet. Of course, it's the UUID that you put in there.
You can also put some key data associated with this service. For instance, if you have a thermostat on the wall, you could put the temperature of the room. So it's constantly advertising saying, "I am a thermostat." Here's the temperature of this room. Here's the name of the room. If you want to know more or maybe change the setting of this thermostat, you'll then have to connect to it. But at least you know, "I'm interested in this device. Let me connect to it and start interacting with it."
Remember I said in the beginning that Bluetooth Low Energy is all about low energy. So the advertising packet has some limitations. It's very short. It's only 31 bytes. So you have to be careful when you put the data in here that it all has to fit. We have to live within these limits. So only 31 bytes. So these UUIDs. We've talked a lot about UUIDs. There's two types of UUIDs. There's 16-bit UUIDs and there's 128-bit UUIDs.
16-bit UUIDs is basically reserved for the Bluetooth SIG and they assign them. They normally assign them in specifications that they produce. If you want to know more about the 16-bit UUIDs that exist, you can go to developer.bluetooth.org. And they have a nice table there for you. They have a nice table there for you.
There's also the 128-bit UUIDs, and those are actually assigned by you. Now you go, "Oh, great, then I can come up with this cool UUID that's 1, 2, 3, 4, 5, 6, 7." The guy next to you probably has the same brilliant idea. So instead, we recommend that you open up a terminal window on Mac OS and type UUID gen.
And it will generate a truly random 128-bit UUID and the probability of someone else using that UID is very, very, very close to zero. So we talked a lot about advertising and how to discover devices. Now we're going to dive in to see what happens when you connect the device. As Brian mentioned in his talk, when you connect to a device, You set up a timetable when these devices are going to interact.
and initially, Core Bluetooth, when it connects to a peripheral, sets up a very short connection interval. The reason for that is we want to make sure that the data that we're fetching, the services and the characteristics, we get them very fast. The peripheral might say, "Whoa, that's a little bit too short for me. I'm going to consume a lot of power." Maintain this connection interval so it can actually request a longer connection interval and that way saving power.
Of course, this leads to latency involved with it, so this is a design decision that you have to make. We have guidelines for what connection parameters we support. Those are documented in the Bluetooth design guidelines. We suggest that you take a look at that. Setting up these connections, the first time you set it up, you go and look for the services and you look for the characteristics and it takes a while to get those. Second time, you go and look for the services and characteristics again. We found out a better way to do that. In iOS 6, we actually introduced caching.
That means that the discovered services and the discovered characteristics are cached locally on your device. We only cache the data structure. We don't cache the actual values. When you do a read or a write, those are still live variables. Since this takes up a little bit of space on our device, we only do it for paired devices.
The cool thing with this is, this is fully transparent to the app. So your app thinks the second time it connects to the device, I'm going to go and read the services and read the characteristics. In reality, we have this small stash on the side and we go and get the values from there. I mentioned these paired devices. So let's talk a little bit about pairing. Pairing is always triggered by the peripheral.
The central tries to do a read or write to a peripheral. And the peripheral has the ability to reject that read or write. They go through the pairing process and you end up with an encrypted link. It's only paired devices that you can have an encrypted link with.
So let's take a look at how this works. Your app issues a read or write to a characteristic that gets sent over the air to the peripheral. The peripheral says, "I don't know who you are," and rejects this with insufficient authentication. Core Bluetooth then goes off and tries to pair with this device. But before we do that, we have to go and ask the user. So we pop up a notification to the user saying, do you really want to pair with this device? We're going to create a bond with this.
Do you really want to do that? And the user says yes. Then we move forward. request pairing for the peripheral and part of the pairing process, encryption keys are generated on both sides. We're going to use these encryption keys on the link that we later on are going to set up.
Core Bluetooth then automatically goes and retries without your application having to worry about it. Retries the read or write. And now we have a paired relationship and it's done over an encrypted link. And the peripheral now responds to it because he knows who it comes from. Last, I'd like to talk a little bit about state. One thing that's important is not all iOS devices or Macs support Bluetooth Low Energy in the hardware.
And before you start in calling the Core Bluetooth framework, we want to make sure that you're actually on a device that supports Bluetooth Low Energy. You can check that in the CB Central Manager or in the CB Peripheral Manager. There's a variable called state. And this property can have a number of states. It can be unknown. When it's first instantiated, it's unknown. It can be resetting.
This is normally when we start booting up the system. And then, if Bluetooth Low Energy is not supported on this hardware, the state is unsupported. Or it could be powered off. In that case, your application will have to go and tell the user, "Bluetooth is turned off on this device.
You might want to go into Settings and turn Bluetooth on so I can use Bluetooth." Key thing you want to look for eventually is that it's powered on, Bluetooth Low Energy is supported on the device that your app is running, and now your application is all ready to start using Core Bluetooth. With that, I'd like to invite Khrob up to the stage for the demo. Thank you, Joaki.
G'day all. Now, if you're all like me, a lot of your Bluetooth experience will be sticking on some really cool noise-canceling Bluetooth headphones and tunneling down so you just, you know, you focus and you're blocking out the outside world. But hypothetically speaking, what if you were to find yourself in a large conference center with 4,999 other really, really cool people that you actually get along with really well and share, let's say, quite a few common interests?
Well, you might meet some of them and you want to exchange your contact details. Now, that might involve going to contacts, typing in their number, sending them a message with your details, step by step by step by step. You know, wouldn't it be much nicer if you could just do the equivalent of pulling out a business card, handing it over, they take it from you, and you're done? But, you know, eco-friendly and everything, we want to save trees, so let's just do it electronically, phone to phone. So in this demo, I'll show you how to set up your phone.
your phone into a peripheral mode So essentially you're turning this into a peripheral like the heart rate monitor or the thermostat on the wall that is your business card. So let's have a look at what we need to do. So it's quite simple. First up we need to start our CV peripheral manager. Once we've done that we need to create the tree, publish our service, so Core Bluetooth knows what information we want to put out in the world.
Then we need to advertise the service and then we basically sit back and relax until a central comes along and says, "Hey, you're advertising this UID that I'm interested in plus your RSSI, the power, tells me that you're actually really, really close." And when it does that it connects and we start talking. So just quickly the class itself, very, very simple.
We have the CV peripheral manager, we just called that one manager. We implement the CV peripheral manager delegate so we get all the right callbacks from the asynchronous services. We have a mutable service which I've called vCardService and a mutable characteristic which I've called vCardCharacteristic. Note that because we're on the peripheral side we want to be using the mutable versions of these because we set the information in them, not Core Bluetooth.
So turning on Core Bluetooth, very, very simple, stock standard in it function. And we call CV peripheral manager alloc and in it with delegate. Of course we're going to set it to ourself because that's, you know, we implement the protocol. And we set the queue that it's going to run on.
In this case we're just setting nil which will choose the most appropriate queue to, you know, do all the callbacks and everything on. If you need to do something a little bit more clever then feel free to set whatever queue you like for that. Now the second part of turning on the peripheral manager as Joachim was just talking about.
was checking that state, which is very simply done. We get the callback, peripheral manager did update state, and it even says the peripheral. So we do a switch on the state. If it's CB peripheral manager state powered off or resetting or unknown, we know that something's not quite right with the setup.
Maybe it's an older phone or an older MacBook Air, doesn't have the low energy Bluetooth. So we deal with that here. But if we do have the magic one, CB peripheral manager state powered on, then we can go ahead and set up our service. Now, the service will have several characteristics.
Well, it could have several characteristics. A service is a collection of characteristics, as we've just seen. So you could have a service that has a UID that expresses that it's the vCard service. And you could have a characteristic that says this is my first name, this is my second name, this is my phone number, this is my address.
And that's absolutely perfectly valid use case and way to do it with core Bluetooth. Each of those things is a very small piece of data. And as we're low energy, we want to send small pieces of data because we can do that very, very quickly. We're going to do something slightly different today.
Instead of a readable characteristic for each of those different things, we're going to set up a notifiable characteristic that when the central connects, it can subscribe to. Now, remember, when you subscribe to a notifiable characteristic, you're going to get a notification. So if you have a notifiable characteristic, any time that characteristic changes, the connected central will get a callback saying, hey, this value changed, and here's the new data. So let's go ahead and set up that tree, which represents that.
So, as just said, everything is identified by UUIDs, or CBUIDs that is. So we're setting up a string for each of the two, one for the service, one for the characteristic. And then we can use the CBUID helper function UUID with string, pass in the strings from up here, and there we get service and pipe UUIDs.
[Transcript missing]
This is exactly the same as above. We've just made the, you know, I've just repeated it for clarity. UUID with string, passing the string, we have our new UUID. Make an array of the services. Make a dictionary, pass in that array.
and make sure we use the right key. There's one for each of them, clearly defined in the header docs. CB advertisement data, service UIDs key and then starting to advertise, simple as telling the manager to start advertising this information. Hell of a lot nicer than packing bytes. So now we're advertising. What's going to happen then is we're walking around the conference. I meet someone and say, you look pretty cool. You're working on really interesting stuff.
Here's my card, essentially. And when they get close, his app is in central mode and it's going to go, hey, wow, someone's broadcasting this data and the RSSI is very small. So obviously it's very close. So it'll connect to us. And as the peripheral manager, we'll get a callback saying central did connect. Now, many apps are going to use that for their own ends. There might be something very important they need to do. We're not particularly worried about that. It's like, hey, connect away. We're all good with that.
But then it's going to explore us and it's going to hit the characteristic that we want and say, oh, there you go, there's your pipe characteristic. I know that if I connect to you, if I subscribe to that, you're going to send me a whole lot of data that represents a vCard.
So they're going to call subscribe to characteristic and on our side, we're going to get a callback. What callback is that, you ask? Peripheral manager central did subscribe to characteristic. Very, very simple. That comes in without us having to do anything. And once it happens, we know that we can loop through the data that represents our vCard one chunk at a time, send each chunk over to the central, and then send an end of message. Now, I just want to reiterate again here that when you're sending characteristics... When you're sending chunks, this is low energy. We can't send video files.
We can't send massive, massive stuff. Keep it small. The chunks in this case, they're 20 bytes a pop. So I've got a little helper function that just goes to my Anastata that contains the vCard and pulls out... The next chunk, the next 20-byte chunk, and keeps on doing that until the vCard's already sent. But once we have each chunk, we need to actually update the value of our characteristic. So, again, back to our CV peripheral manager.
Update value, pass in the NSData for the characteristic, the vCard characteristic, and like magic, it'll go over to the central. The central will get their response, their callback, saying, "Hey, this characteristic updated the value." They'll pull it in, they'll pull it in, they'll pull it in, and the app here streams them all together until it gets updated. And that's the end of message one, which, again, very, very simple.
Just getting an NSString, turn it into some NSData, and using exactly the same call as before, we update the value for the characteristic. And when the central gets that, it goes, "Okay, that's the end of message. I have all the data I need. I will disconnect to you -- or disconnect from you, and you're free to go and share your card with someone else." And really, it's a very simple thing.
That's it. Now, I know I've been a bit long-winded in explaining how it goes, so let's have a look at just how quickly this all happens in real life. Okay, so that's a phone set into central mode, so it's scanning, looking out for people in peripheral mode. And so I've got this chap in peripheral mode. I'm going to very simply select the card that I want. He's up there. Now, when I bring it close, hand the card over, flash, flash, flash, and you're done.
and just because it's really, really quick, let's see it again. ♪ ♪ There we have it. Back to you, Joaki. Thank you, Khrob. Wasn't that an amazing demo? I'm just trying to imagine all the applications that you guys are going to build using this. Wow. So many use cases for this.
So if you want to know more, we have Steven Schick and Craig Keithley here. They are our evangelists. They'd be happy to answer all your questions. We also have a Bluetooth mailing list where I try to answer as many questions as possible. So please post questions there as well. We also have the Apple Developers Forum. Under Core OS, there is a Core Bluetooth Forum. We try to answer your questions there as well. Previously today, you heard Brian speak about the introduction to Core Bluetooth. Thank you.