Embedded - 345: Do What Apple Says
Episode Date: September 24, 2020Gretchen Walker gave advice on creating a BLE iOS application. Gretchen wrote The Ultimate Guide to Apple’s Core Bluetooth on the PunchThrough (@PunchThrough) blog. There are many other good posts o...n the blog about BLE from a device perspective and app development (iOS and Android). PunchThrough also makes LightBlue, a great BLE debugging app you can find wherever you find your mobile apps. PunchThrough is hiring embedded software engineers in the Minneapolis, MN area. Chris and Gretchen both recommend Ray Wenderlich’s site for learning about Swift. Chris also liked the Big Nerd Ranch books: iOS Programming and Swift Programming. Elecia liked the NovelBits.io writeup about getting maximum throughput on BLE. Apple Accessory Design Guide
Transcript
Discussion (0)
Welcome to Embedded.
I am Alicia White, here with Christopher White.
Remember when we asked if you wanted a show about making BLE iOS apps?
Enough of you said yes that we found an expert to speak with us.
Somebody better than me.
We can compare Christopher's experience with Gretchen Walker's.
Hi Gretchen, Thank you for joining us.
Hi, guys. Thanks for having me.
Could you tell us about yourself as though we met at an Embedded Systems Conference?
Sure. Well, my name is Gretchen Walker, as you said.
I'm a mobile software engineer specializing in iOS apps for Bluetooth-connected products.
So I work remotely right now for a design services company called Punch Through, which is based in Minneapolis.
And I have been living in San Francisco and working for Punch Through for the past five years or so.
Punch Through sounds familiar.
You make light blue.
Yes.
You've used it?
Oh, yeah.
Extensively.
I love to hear that. We love to hear that.
For years.
Oh, that is so awesome. We love to hear that.
Okay, we'll talk more about what that is and why you'd use it.
But first, we want to do lightning round where we ask you short questions and want short answers.
Are you ready?
I am ready.
If you had a complete blank check,
what iOS app would you want to write?
Oh, gosh, that's a curveball.
You know, I have to think about that.
Yeah, I don't think I have a good answer for that
off the top of my head.
Is that okay?
Yes.
Sorry.
That one threw me.
Which is more exciting to you you machine learning or virtual reality oh um well i don't know a lot about either like i've never played around with either but um
i think they're both exciting in their own way obviously but i i think virtual reality is cool
i think even more so i think augmented reality is cool just because, you know, you can use it.
It's already happening with just like your basic devices.
And I kind of love that interaction between the phone and your environment and like the virtual space.
So I think that's what I prefer.
What do you like to listen to when programming, if anything?
I actually cannot listen to music while programming.
Like the second person who said that.
Really? Yeah, I feel like everybody else in my office does.
And yeah, I've tried, you know, I could maybe do something with no words,
but otherwise it just kind of distracts me.
I might have to be in the right mood and I could listen to like some, I don't know,
EDM or something, even though that's not actually what I listen to normally.
But yeah, I probably couldn't listen to any music that I normally would because I'd probably get too into it and get distracted.
Do you have a favorite programming language just depends on what I'm using the most because you get used to it.
And then when you switch to something else, you're like, what is all this stuff?
Why do they do it this way?
So I don't know if you can relate to that.
Oh my God, I need semicolons.
Yeah, exactly.
But no, so I've been writing in Swift, or most of the time Swift, and some Objective-C for the last five years.
So Swift probably has to be my default favorite.
Python's also nice because it's just something anyone can pick up.
But yeah, as far as practicality, then I would have to think about it for why I like a language for more academic reasons.
Do you have a tip everyone should know?
Can it be non-technical?
Yes.
Yes.
Okay.
So for anyone out there who's an awkward dancer, that's me for sure.
I don't know if anyone else feels like they don't like dancing in public. So the number
one thing that you could do that you probably aren't doing enough of is just bending your knees.
And I mean, like really bending your knees and just sitting into them. Because yeah, my whole
life, I was one of those people who hated dancing in public. And a couple years ago, I decided I
needed to do something about it. So I started taking dance classes of just all different kinds. And the biggest takeaway was just to remember to keep your knees soft and
it gives you a much better just range of motion around like across the rest of your body.
All right. I want to ask you about BLE iOS apps now.
Sure. Say as a hypothetical that I'm an embedded software
engineer working on a BLE device peripheral, and I want an app to show off to my clients to make
sure that my clients are aware of the work I'm doing. I have an iPhone. What do I do? Where do I start? Well, you have an iPhone, so that's a great start.
Next thing you need is Xcode, which is the IDE that Apple provides to develop for
any of their platforms. And that's free, but it can only be run on a Mac. So if you don't have one,
that's much less free. If you don't have one, just, you know,
go out, drop a couple thousand dollars. So yeah, sorry, Windows users, but it is Mac only.
And that's classic Apple, isn't it? So that's the first things you'll need. And then you'll
probably want to get an Apple developer account of some kind. So you mentioned distribution of your app.
So in that case, you would need like the standard, it's $99 a year.
So drop a little more money on a standard developer account.
And so that will allow you to build releases and distribute by the app store
or test flight to beta testers. But if you just
want to play around and develop for yourself, you can start out with just like a free account,
which I think they have now. And the only drawback with that is you can't distribute.
And then also, I think the builds that you put onto your phone are going to expire after like seven days. So it's just for at home use.
You mentioned TestFlight. What is that?
TestFlight is a tool for distributing beta builds of your app to other people. And originally it
was a third party tool, but Apple bought it. It was one of the most popular.
So Apple bought it and integrated it into their platform.
So now it's just the Apple tool that you use to distribute your beta builds without going through the App Store.
And it works kind of like the App Store, right?
That the interface to submit things is the same.
They actually review it a little bit, which I found to be quite annoying.
Oh, yeah. same they actually review it a little bit which i found to be quite annoying oh yeah so you do get
you get kind of used to the experience of what it's like dealing with the app store
review process a little microcosm it's not quite as bad but uh it is yeah that's you know and that's
um that's if you there's actually two ways to distribute by a test flight so you can it sounds
like you went through um you know adding external test, and then you might have also seen there's the option to add internal testers.
And if you do, that means you have to actually add people to your account,
and you can just give them minimal permissions.
But yeah, that's probably not sustainable
if you have a wide base of users you want to distribute to.
But it does mean you get to bypass the App Store submission or review process that you ran into, which is especially annoying for Bluetooth devices.
Did you run into that?
Yeah, they rejected me about four times before I finally figured out the right incantations in the info P list for the permissions they wanted.
I think I had to put in warnings, like hey this uses bluetooth you know pop up
a pop-up message and stuff and yeah and they find different steps of the way to reject you they break
it up into different steps so it's not just like you build it and then you upload it and they tell
you right right away if it's if it's wrong there's like four steps that you have to go through and
each of those could they could just reject you and then you have to go through them all again. Yeah, so Apple kind of likes to have fun there with their developers.
So what is involved with releasing through TestFlight?
What's a plist?
Oh, a plist.
So it's actually, I think it's an XML file under the surface.
Yeah, the source is an xml file but it's just basically a list of it's it's a
really simple just representation of i think it's like a dictionary or uh an array usually at the
root level um but anyways it's just like a list of well it depends on the p list but um anyways
it's just a list of keys um they're the info.plist is probably what you're thinking of that comes with every app.
And that just lets you input.
There's certain settings for your app.
And then keys that you mentioned, like this app uses Bluetooth.
So you have to have that key for the app to even run on a phone and use Bluetooth.
If you don't have that key, then the second your app tries to run, it'll crash as soon
as you try to use anything with the Bluetooth library.
So there's stuff like that, or it needs certain other permissions like the camera, or it needs
to be able to run Bluetooth in the background.
So that's where you specify things like that.
So when Chris made the app, in order to get it on my phone to test with my devices, I had to give him my Apple ID.
And then TestFlight invited me?
Yep.
So you will need to either, if you're doing like the external testing route,
which it did sound like you went through,
I think you can just use any email.
I might be wrong there.
Well, yeah, okay.
Maybe it does have to be an Apple ID, actually.
I'm not sure.
I know if it's an internal tester,
it definitely does because you add it to,
you add them to your Apple developer account
and that's got to be an Apple ID.
But yeah, for external testers too,
maybe it does have to be an Apple ID. And so what that's going to look like on the user side is
they have TestFlight downloaded and then the first time you release a build to them,
they should get an email from TestFlight. And so they have to go into their email,
not into TestFlight. That's a mistake people make.
And so they go to the email, and you have to click the link to download the app,
or it'll open in TestFlight or something.
And then from there, you can use TestFlight to get updated builds.
But yeah, the first time you have to go through the email,
and people don't necessarily realize that,
and they're like, why isn't it showing up in TestFlight?
The whole TestFlight thing was kind of confusing. realize that and they're like why isn't it showing up in test flight well the whole test flight thing
was kind of confusing i mean it's good that it's there because you don't have to go through the
whole app store and you don't have to show off things that aren't ready but as a as somebody who
who talks to our clients and has to explain well you do this and then this and then this and this
and this and this and then finally you program the boards with the firmware I give you and you can try it out.
I know.
They don't make it easy.
And it's all about the security and wanting to make sure you sign and provision the app properly.
But yeah, I don't know if you've ever tried distributing on Android what
that's like in comparison. Have you ever done that? I've been near people who've done that.
That's close enough. Yeah. So Android, you're just going to, you know, build a release and
you get a.apk file. That's the app file. And you can just throw it around, drop that onto
somebody's phone and it'll run and that's it. Yeah. I mean, it is cumbersome, but it does have some nice features, right?
Because the user, if they have a problem, it automatically does a screenshot.
You can submit stuff and report things right from the app and then it'll go straight to the developer.
And, you know, they get a backtrace and a screenshot and a description of the bug.
So it has some nice features, but it is rather painful to go through.
Exactly.
Yeah.
No, that's true.
There's trade-offs.
Okay.
So that's all.
I guess that's before the app is knowing about Xcode and Mac, and after the app is knowing
about TestFlight and distributing it, at least to your team.
But as I'm developing the app, what do I need to know?
Do I have to use Swift?
Should I use Swift?
Is there something else I should use?
Yeah, so Swift is definitely the way to go these days.
You don't have to use it, but I'd heavily recommend it.
The other option is Objective-C.
And trust me, one look at their method syntax and you'll never want to come
back. Swift is definitely what Apple's pushing these days and what they want you to use. So
what Apple wants, Apple gets. It looks pretty C-like to me.
Swift? Yeah. I mean, the syntax.
Some of it. Some of it is it is yeah it's a weird hybrid
of like there's some C things
there's some things that are a little bit more like
I don't know maybe a little more like Python or Ruby
or something where it's very
kind of clean
you don't have your semicolons
or anything like that
and then they have some of their own
sort of
unique syntax,
like returns are, you indicate a return with like a,
you draw an arrow with a dash and a right caret
and put the return type.
So I don't know.
But it's actually what it is kind of similar to is Kotlin,
which is Android's version of Swift that they came out with.
So if you're familiar with that and you're moving from Android to iOS, you'll
be in good shape.
For an embedded developer coming from C, it's
kind of jarring, right? Because it's
not, I mean, it's an
object-oriented language, but Apple
pushes protocol-oriented stuff. There's a lot
of more generic language concepts
that somebody has to become familiar with
coming from straight procedural C.
Right, yeah.
You're not using those raw types ever
like you use in C.
So in that sense,
maybe Objective-C you'd be more comfortable with,
but Swift is just more like...
No, I've tried that.
I mean, that's the thing.
I'd rather learn something totally different.
Honestly, I'd feel the same way.
You're right.
You're right.
You definitely should.
So, yeah, Swift is definitely the way to go.
Like any language, it takes some getting used to.
And like I said before, it's any new language, you feel like, oh, why do they do things like this?
It's so much better in the language I usually use.
But then you get used to it and it gets better.
Do you have any suggestions for resources to kind of learn swift from the beginning um i mean yeah you know obviously they
have their docs but that's not necessarily something to that's user-friendly to just dive
into um so personally i i don't know if they i don't know if they actually have a tutorial but
on on this on swift specifically, but are you familiar with Ray
Wenderlich? I think that's how you say his name.
Yeah, I mean,
they have tutorials for everything
and that
they probably have something,
some resource for Swift, but
I can't think of a specific guide
that I
remember using.
Yeah, I remember when I was learning, I did a bunch of the tutorials on that site.
So that was really good.
Some of the other stuff I used, there's a couple of books from Big Nerd Ranch that I liked.
Those were good.
Is it Big Nerd or Big Ranch?
Is it Big Nerd Ranch or Big Nerd Ranch?
I don't know. I never really thought about it until now.
Go on.
But yeah, and then there's a whole bunch of Udemy classes and stuff, but really the way Ray Wendell looks at it and the books were the best. But there was some learning curve, at least for me.
There always is.
Yeah. learning curve at least for me there always is there yeah so does swift work with bluetooth i
mean you've told me i should use blue that i should use swift and i already said i was doing
bluetooth so there must be some something to connect them library framework what is it
sure um yeah so the core blue apple provides this library called Core Bluetooth,
and that is what you would use to interact with Bluetooth devices on iOS, Mac OS,
I think also maybe TV and watch OS.
So that's what you would use.
And is this Bluetooth like the old Bluetooth that was audio or BLE? Yeah, this is actually, yeah, it's not clear, but it is, it's technically was developed for Bluetooth low energy.
And there was a separate, a separate library for interacting with Bluetooth classic devices.
And that, yeah, the way Bluetooth classic works is super different.
And I'm not even very familiar with it because it's not something we are asked to do really anymore.
Everyone's kind of using Bluetooth Low Energy.
And these days, they're tryingAT table to a Bluetooth classic device. Peripheral supports that. They have a new API in Core Bluetooth to be able to retrieve those kinds of devices
and connect to them and read their GATT table.
And then you use the same APIs to read their GATT table and all that.
And I haven't played around with that too much because I haven't really found a device that works like that.
But that's kind of exciting.
So what does Core Bluetooth give you?
What kinds of things will it do for you? Or at what level is it kind of exciting. So what does Core Bluetooth give you? What kinds of things will it do for you?
Or at what level is it kind of at?
Extremely high.
Extremely high level.
Yeah, if you are at the point that you've already developed
like an embedded BLE device and gotten it working
or even gotten it halfway working,
you probably know more than you even needed to
to work with cord Bluetooth successfully. So if you just know your basics of Bluetooth, you've got
two roles that a device can take on, the central and the peripheral role. The peripheral role is
probably your embedded device in this case, and it's going to be advertising and the central is going to want to scan for that device and connect to it and discover its services and characteristics and then read and write and subscribe to notifications on those characteristics.
I basically just described the API and what it looks like.
That's just what the API looks like.
Like, those are the calls.
They don't get more complex than that. So it handles a lot under the surface,
which also means it occludes a lot from you. So there's a lot of control that you might want to
have that you won't have and a lot of visibility that you won't have into what's really going on
and just certain parts of the Bluetooth stack and the process.
That's my second question, is what doesn't it do?
It doesn't tell you when it completes things.
Well, yeah, so I'd say that one of the biggest things that people complain about,
and especially our clients will expect to be able to do this,
and then we have to explain that there's no insight.
It's pairing and bonding.
So if you are familiar with that, what pairing and bonding technically is different from just a standard connection?
Are you familiar with that?
Oh, yeah.
If you want any security, any security at all,
you have to do the pairing and bonding.
You have to type in the number that it gives you.
Which iOS just pops up randomly when it feels like it.
Yes.
It's not part of your app.
No.
And then it creates this bond that they can talk,
which you can never get rid of unless you go to the secret place in the settings menu and tell it to forget the device.
We're going to talk a little bit about that.
But yes, pairing and bonding, it's horrible.
Exactly.
So that's, I mean, yeah, it's something you do want because it's a standard security.
So a lot of devices, you will want to have that. But it does just create all these issues because um yeah like you said you
you that your app has no idea like you'll get um you'll call connect to a device and it will
technically connect because that's a separate thing from pairing and bonding that you know
pairing bonding comes after connection so you get your did connect call back and you think you're
ready to go um but then you might still well it also depends on how pairing and bonding is triggered.
There's a couple of ways.
It can either be like on connection or the way Apple likes you to do it is you have like an encrypted characteristic.
And when you try to read from that or write to it, that's going to trigger pairing and bonding.
But again, you just don't know what that, yeah, when that dialogue's popped up and if the user said yes
or if they're just sitting there and not noticing it.
And then, like you said, again, you have no control over it.
You don't even know if the device is a bonded-type device
and you can't clear it yourself.
You have to tell the user, hey, if you want to actually clear this device,
you've got to go to settings and clear it and forget it.
And you can't even deep link to that menu.
You can link them to settings, but just the high-level page.
So that's the kind of stuff that Core Bluetooth frustratingly does obscure from you.
At the risk of asking you to do my homework for me, What I ended up doing is, since I want it to pair and I don't
want the user to be ambiguous, as soon as I connect, I go ahead and just randomly read one
of the encrypted characteristics I know is out there to force it to pop that up if it's going to.
You mentioned a way to do it on Connect, but you said apple doesn't like that um so yeah they have this uh accessory
design guidelines uh pdf that they've put out and um it's i mean it's huge but there's a section on
bluetooth and it just it lists all of the rules that it likes you to follow it likes its devices
to follow so one of them is um say says that it prefers the encrypted, or sorry, the insufficient authentication method
of bonding or triggering pairing and bonding,
which is, yeah, reading from an encrypted characteristic.
So I don't actually know what it looks like
on the firmware side because it's not my wheelhouse,
but there is a way you can configure
on the firmware side to also just do
like on i i think on connecting and then um you can also configure it to whether it should just
be like it's called just works where it you know just pairs and bonds and it doesn't pop up that
um it pops up the pairing like do you want a pair dialogue but it doesn't do the pin number you can
configure whether whether it should enter a pin or or just give you a pop-up.
You have to have the PIN or it's really not secure.
Ah, I don't know.
You're getting the PIN, Christopher.
There's no way to do it without the PIN.
She's doing the firmware, so I'm glancing at her going,
hey, maybe you should try that, and she's saying no.
I'm not sure I could speak to how much extra security having the PIN provides.
I mean, because it's really just from one side, right?
You know, just making sure that, well, I guess it depends where you're getting that PIN number from,
because sometimes it's something that's printed on the device.
But yeah, I mean, usually if you really want to have proper security with Bluetooth,
you probably want to just have your own layer of encryption on top of the Bluetooth encryption at the app level.
So I'm not sure.
I don't know if I can speak to how much the pin itself really provides.
It provides against casual intrusion.
And for example, the app we're working on,
I have dev info outside the pair bond because you can read that on Connect.
You don't have to know anything about the system.
Dev info is the GAT, which is the list of characteristics that is standard on Bluetooth.
It describes a device.
It's the device info.
And so, yeah, I have that outside.
And so he has to read one of the encrypted things in order to get bonded.
And our pins are set in manufacturing.
And then he has to go to a website in order to get the pin for this device.
So it's pretty complicated.
But it is more secure than having your PIN be 1, 2, 3, 4, 5, 6,
which is the default TI password.
And so many people still use it.
It's not a good PIN.
Yeah, I've definitely seen that before too many times.
But yeah, I suppose, I really, you know, I always like everything.
It comes down to your use case.
Like, is that something that you want to have to make users do?
Or like, you know, some a lot of the time we're working with certain medical devices
and you have an older population maybe.
And so then you have to worry about any extra step in the process, like numbers
they have to look up.
It might be easier to just, or a better user experience to handle the encryption and the
security elsewhere that's more under the surface.
Well, that's actually, actually now I am going to ask you to do my homework for me.
We do set the pin in manufacturing, and then it's on a a server and the iOS app has to go ask the server
what the pin is
I can't provide the pin
and so I think you put the pin
you're going to put the pin on the screen
and then when it pops up to the user
it has to copy from
the app
to the iOS pop-up
I can't do that
there's no way to avoid that no the app to the iOS pop-up. I can't do that.
They're going to have to type it.
There's no way to avoid that?
No.
The pairing pop-up is from the system.
That's silly. I don't even know it's there.
Yeah.
You're just going to have to put up the pin number for that device.
Please type what this says right here.
That's what we're going to have to do.
That's silly.
Yep.
That's what they make you do.
Okay, so I've heard
through some
shouting that
the message passing system
is
complicated?
And it's
all messages and there's no...
I mean,
I'm an embedded developer.
There should be something that's like the initialization section and then there should be the loop and you should just do loop over and over again.
The occasional interrupt that sends you maybe an event to the loop.
That's how it works, right?
That's how all computers work. I mean, that is probably, I mean, there is like your app does have a main loop that you
don't touch really um you know it's that's actually in c and that's a yeah a file you'll
never probably play like touch when you're developing an ios app but um yeah the the way
that apple and their apis handle um asynchronous callbacks is via delegation,
which a lot of people don't like.
I don't even think Apple likes it anymore.
They did eventually start introducing some APIs or some alternative methods within APIs
that you pass in as a parameter,
you pass in a Lambda function.
And so then at can, then at least
your code where you call the method and then the callback code is all in one place, like maybe in
the same function. And so that's just so much better for readability, I think. And I think
that's what most people prefer. But yeah, delegation, I don't want to get too much in the details of it, but it does mean that your callback methods are going to be in a completely different place from where you called the original code.
And that does mean that you have to then to remember what was going on, you have to store state in static class variables, which is kind of gross.
Usually you want to avoid doing that too much.
So yeah, that's why people have been moving towards other paradigms they you know block block block based callbacks are nice and then like well sort of expanding on that the rx pattern
has become more and more popular there's there's rx there's like an rx swift library i think
there's actually two out there
that make everything more reactive
and so people have been trying to get around Apple's initial API designs
for forever
When Apple just introduced Combine, which is their version of Rx
so I guess they'll start doing that
I found the whole API really frustrating and kind of unswift-like
It's Objective-C-like, I guess doing that yeah i found i found the whole api really frustrating and kind of unswift like it's objective c like i guess yeah yeah uh and and i just keep getting in corners where
stuff will happen because it's just these callbacks and there there's only one like
you said there's these delegates which is like an object that gets called back
and there's only one of them so like if if, if I'm in a different section of the beat,
the Bluetooth stuff I'm working on,
you know,
dealing with different,
different part of the peripheral,
I still get the callback in the same place.
And so it's like,
okay,
what does this pertain to?
Oh,
this isn't what I was.
So I'm,
there's like this implicit state you have to maintain like,
oh,
I was thinking about this,
but now I just got a message from Bluetooth.
It's about this. And that's not what i'm thinking about right now so i shouldn't
have got that message uh so yeah i i feel your pain um yeah delegates are definitely a one-to-one
kind of relationship thing so yeah if you find yourself you have multiple classes that kind of
need to access those you you could pass you know pass the delegate uh handler off you know assign each
class to the delegate uh property of the the main class if you you know but that's not great so the
other way to do it is then implement kind of like a a notification layer you can use like internal
notification app notifications to to um notify multiple different classes what of what's
happening that's probably what i'd recommend if you're just quick building like you know some to notify multiple different classes of what's happening.
That's probably what I'd recommend if you're just quick building
like a little layer on top of that.
Okay.
So you just said that's what you'd recommend.
Okay, so Swift, Core Bluetooth, and Rx or Combine.
No, I wouldn't start with that i wouldn't start delegates but do something
with classes and delegates yeah i would just i would go with the delegate stuff to begin with
yeah yeah because that's what they that's the simplest path forward it's it's not the end of
the world especially if you're using something if you're building something simple and more of just
like a prototype kind of kind of deal and that's really where I'm asking my questions from, is a prototype sort of thing.
Because as an embedded engineer, what I most likely want to do is be able to say,
here are all of the things the device can do.
Go give this to a shiny app company who can make it pretty. How much do I need to know about all the other things about BLE, all the power
management and GATs and characteristics and read, notify, write, and that sort of thing?
Do I need to know those or can I just kind of glide through?
Will it work for me?
Will it explain things as I go with core Bluetooth?
Yeah, I mean, I don't know if the docs are as straightforward as they could be.
Probably want to find a tutorial and hint, hint, we have a blog post about this that will help you out.
But yeah, the power management stuff, absolutely, you don't have to worry about.
You don't really have any control over that other than just kind of minor things you can do to worry about the phone's battery life.
But the, yeah, the services and characteristics, it's again, it's these very high level object representations of what they are. So you'll just see you have like, you know, everything in core Bluetooth API is prefixed with CB for core Bluetooth. So you'll have a CB service and a CB peripheral. And each CB service has an array of CB characteristics. And they have, they all have, you know, like a UUID property. And, you know, maybe like the descriptors on them. And then, you know, the characteristics have a value property, and that's just like a data type, a Swift data type object. So that's, you know, if that sounds reasonably straightforward, then hopefully it does, then that's all you need to know. you said before that if i had programmed the ble side on the device i probably would already be
there and yeah that's what it sounds like but if i haven't i wouldn't start with core bluetooth i
would learn about bluetooth first yeah yeah yeah and even bluetooth i think um that's that's there's
a lot to know about it especially if you are working on the embedded side but yeah from a
mobile standpoint um you really just need to know like the basics of kind of what how bluetooth organizes
data and you know what the what the buzzwords are well back to the delegation buzzword
one of the reason it's there is because everything in bluetooth BLE is very asynchronous. You don't necessarily, nothing happens in real
time because you're going over a wireless network. And so when I say I want to know the value of this
characteristic, you know, it goes off, it does it, it eventually calls you back and says it was this and as chris
was saying you may be doing something else entirely by the time you get that notification
right is there a way to organize the code that makes it easier to deal with the asynchronous
nature of it all um yeah i i think that is if that is something that you're very
concerned about and you don't like the whole you know having to use it again it's so use case
dependent so it's hard to like imagine i guess what what your what your needs are but um you
know if it is something that's just really bothering you then maybe that is when you
want to look into either writing your own kind of layer on top of core Bluetooth, which we've done for clients developing SDKs.
We've written an Rx layer on top of the core Bluetooth library, or you can write just more a block- based layer on top. And so that will then give you code that's more, you know, you call again,
you call your code and then you have the callback code in the same place.
And so you can access like local variables you might have defined when you
called it and stuff like that, you know, so that's,
that's probably the best route forward if you're not happy with just having to store state in class variables or wherever.
Yeah.
And the delegation thing, that's one of Apple's design patterns they loved for a long time until they didn't.
Yep.
They stuck that on all kinds of stuff.
I also found error handling to be a pain,
and I think this goes along with the asynchronous stuff.
And this may just be an iOS app thing,
and I'm not good at it,
but it seems like when I get a notification from Bluetooth
down in the delegate,
bubbling an error up to where it makes sense to have some context about
what it's about is really tricky.
Do you have any advice for,
for error handling for Bluetooth?
So is,
are the errors you're talking about like errors that you want to send from
your device up to,
or are you just thinking more like interpreting the other errors that core
Bluetooth has built in?
There's something I might want to present to the user, like I got disconnected or trying to think of another one at the moment.
Right.
Like just so being able to interpret the errors that core Bluetooth might bubble back up to you and then being able to interpret that for the user.
Bond failing too. Bond failing, yeah. Oh, yeah. might bubble back up to you, and then being able to interpret that for the user.
Bond failing, too.
Bond failing, yeah.
Bond failing, I mean, that might come.
So this is one of my biggest problems with core Bluetooth, is the errors that they can send you are extremely poorly documented.
Almost not documented.
They list them all,
but there's no indication
of when they might send them. And not to mention, there's also two different. So, like, you know,
you have an error, like an NS error or an error superclass, and then there's actually two different
types of CB errors. There's, like, CB error and CB at error, which is to do with, like,
specifically the that profile.
So yeah, but there's no indication of if you might get one of those types versus the other.
And so you have to cast it to find out and see like, okay, is this a CB error or is this a CB at error?
And then from there, you can try to handle all of the different errors that they could give you.
But again, you don't know which methods are likely to for sure give you them back
or which errors are actually still in use.
There's probably some old ones that aren't.
I don't know.
So yeah, that's one of those things where we don't end up really,
a lot of the time we don't end up really doing a lot of very specific error handling.
It's just because we don't see those errors too often.
So a device disconnection would be not even an error. It's either
a did disconnect callback or failed to connect callback.
So that's easy. But yeah, it's hard to even think of specific
examples of other errors because I don't really...
I'm probably encountering more errors because we're both developing at the same time.
So it may not be something as realistic to worry about,
but if I see them, then I start getting worried because, oh, this might happen in real use.
Hey, I apologize that I hadn't byte swapped everything yet, okay?
You did. Some things were just swapped differently than others.
I think I might be spoiled because, you know,
the firmware I end up working with is from people who have been working with Bluetooth and embedded devices for a while.
So I probably get a little bit spoiled not seeing some errors that maybe a more fresh-to-BLE embedded developer might be producing.
So maybe I have a skewed point of view
on how often those come up.
It's developing a custom GAT more than anything else,
trying to decide how to display things.
And we're using TI's firmware update SDK,
which does its own things.
So we get errors from that that are just like, oh, everything's destroyed.
I've used that stack before a long time ago.
These days, I feel like every project I work on, a lot of people use Nordic.
Not every project.
Nordic's probably the most popular one.
Yes, and with good reason.
Yeah, I think they definitely have the most.
I've used both multiple times in multiple generations.
Choose Nordic.
Sorry, TI.
That's my takeaway, too.
I'm not an embedded engineer, so I don't really have to deal with it, but I do have to kind of deal with the fallout from it.
You mentioned a blog post.
I believe that is the ultimate guide to Apple's core Bluetooth that's on the Punch Through blog.
Yes.
Is that right?
Yep.
Which I wish existed two and a half months ago.
I know.
It just came out.
It was written and then had a lot of editing and stuff to go through.
But yes, that just came out in the last month or two.
Yeah.
So actually, our blog is a really great resource.
I do recommend it. I know it's our blog, but
I would definitely suggest it
as a resource for
not just...
We do have these two
ultimate guides that we've released
this past year for
Bluetooth on mobile. So we have one for Android
and one for iOS. And if you think the
iOS one looks comprehensive, the Android one is just insane. It's awesome. My coworker just did a
fantastic job putting that together because there's so much more to know about Android BLE
than there is for iOS, I'd say. Why is that? Well, it's more complicated. The biggest reason
is because you are dealing suddenly with not just a single manufacturer.
You're dealing with just a wide range of manufacturers.
And they each have their own different Bluetooth chip set.
And they also might have their own different fork of Android, which could include, especially with Bluetooth, since they're interacting with different hardware,
it might include internal tweets to the Bluetooth stack,
the Android Bluetooth stack.
So it might work differently.
And then also the versions are way more,
you have a much wider range of Android versions
being actively used across,
depending on the make and model of the device.
So yeah, between all of that, that just creates a lot of problems with Android. versions being actively used across depending on the make and model of the device so um yeah
between all that that just creates a lot of problems um with remembering that we had
many serious serious issues with that oh bringing back memory did you block this out
yeah well i didn't work on android so i only heard the screaming from
other people so yeah that's my life too i just sit here why is samsung killing our app
just because it feels like it yep oh yeah god samsung's the worst because they're the most
prolific that's not you know google um they're the most prolific you know i would say phone that
um has its that has a really just a different stack um and a different um you know they're so their own
fork of android and different chipset than like what google uses and since google controls the
you know they own android they control the api and these days and and the os so yeah
well i want to go through the posts a little bit um you wrote the ultimate guide to Apple's core Bluetooth.
There's one about unit testing Android BLE code with RX Android BLE, which I guess is a unit testing system.
There's the ultimate guide to the Android, I guess not core Bluetooth, but whatever that is.
And using RX versus Delicates with core Bluetooth.
Oh, that just came out. So there are a lot of resources here that describe how to solve the problems
that we're all looking at when we're trying to start doing app development.
Yep.
I just want to make sure that those were mentioned.
And then LightBlue.
Tell us about Lightblue.
So Lightblue is the app that you'll want to use if everything we just described
sounds horribly time-consuming and exhausting and you're scared.
This is true. I mean, I use LightBlue before I have an app to develop. Yeah, that's exactly what it's really, I think, useful for.
But it's one of many potential functions for that app.
So, yeah, if you just...
So LightBlue is an app that we developed first
to privately test our own in-house Bluetooth devices
way back in 2011, 2012,
which is when Bluetooth 4.0, which is Bluetooth low energy,
first came out on, I think it was the iPhone 4S.
And so, yeah, we were already working with that.
And so you can use light blue.
And then we realized we might as well release this to other people
so they can use it too.
There wasn't any similar tools at the time available on the App Store.
So it's still available free, and you can use it to scan for
and connect to your devices, examine services and characteristics,
read, write, subscribe, export your log data.
And you can even, and this is one of my favorite features, configure and emulate your own peripheral device.
So if you want to go on the other side of things and have your phone act as a peripheral, you can completely configure it top to bottom.
I haven't done that yet.
I thought about doing that when I thought Chris was going to be ahead of me in iOS development,
but I caught up, and so my device was mostly ready for him.
I have also used NRF Connect, which is similar.
It shows you the characteristics and lets you connect and bond. Yep. Pair and bond or whatever.
And it lets you do the over-the-air firmware updates for Nordic,
if that's what you're using, if you're using their code.
Yes.
But LateBlue has a nice interface and is pretty reliable,
so I use it a lot.
Well, that's great to hear.
Yeah, and each app has different things that they probably
are better suited for. So our feelings aren't hurt if you also find Nordic's app useful.
It's something that we are always trying to build out Lightblue when we have time internally,
because primarily we are a contracting company. So we're working on other external projects,
but whenever we do have a little downtime
for our mobile engineers,
we're always trying to add to it
and get suggestions from users
and look at what our own firmware engineers need
to try to build up the next big feature for LightBlue.
And it is available on Android and
macOS as well.
One of the things I really liked about it at Fitbit was
we didn't really have a low-level
config app. We had the
user-facing app, which
doesn't say anything about Bluetooth. It communicates
with the devices with Bluetooth, but
you're not interrogating characteristics
as a user. It's connecting to your watch
and showing you all the important data.
But as a developer, there was no separate dev app to kind of,
okay, I need to look at this device and see what these things specifically are
and these configurations.
So it was nice to have that on the side as well.
This is the debug app that I can talk to this Bluetooth device
and look at everything I need to look at without it being massaged through the user-facing code.
It's kind of like inspecting your HTML pages, your web pages.
Yeah, absolutely. And you can interact with it, too.
And it's funny you mentioned Fitbit because
it's a funny, completely unintended use case
for Lightblue, but a lot of people, at this point it seems like hundreds to thousands of people have turned to LightBlue to find their lost smartwatches.
And we have Fitbit to thank for that, actually, because I guess they list us on their website as a resource if people ask for your device.
But you can use LightBlue basically.
It's not what it was written for at all, so it's not something we necessarily explicitly cater towards.
But you can use it because we have the little signal strength indicator on the scan list.
You can use it as kind of a game of warmer, colder, and walk around your house.
And a lot of people have found their Fitbits that way, which makes us happy.
That should have been your tip.
Yeah, actually, you know, that is a good tip.
I scratch it.
That's my tip.
I always tell my mom that tip, and she never remembers to use it,
but she's always losing her Fitbit.
I mentioned that we created a custom GAT
because we had specific information,
but I also mentioned that we used an off-the-shelf standard Bluetooth one,
the device information, and I've used the battery one before.
And a lot of people use the UART service that makes your device act like it's a UART.
What is the best way to go about as I'm trying to design the system to make it an easy app?
Should I have a custom GAT?
Should I try to use something off the shelf even if it doesn't quite fit? Or should I just
use the UART service for everything? Put my own command handler on top and that'll be so easy.
Yeah, so again, it's entirely use case dependent. So the reason to use a standard GAT characteristics
is usually for broader compatibility with like a variety of central devices and apps that you might want to be able to connect to your device and read things
like battery level or heart rate, you know, and then they'll already know what they are and how
to format them without you having to write any of that mobile side code. So maybe like just a more
interesting question is like how to format your data and, format your data and turn your GATT table.
And so it just really depends, again, on your use. a single serial stream for all your transmissions, you now have the option to separate out and
define multiple data buckets, data streams for different data types and purposes.
So if you have a bunch of different sensors and you want to read information about them,
you might designate a separate characteristic for each of them, and then you can update
them in parallel whenever each one has a new value.
So you don't need to provide any metadata to the other side
to let them know what the value is.
The app will just know based on what the characteristic it came from was.
But that said, it's very common to default back
to that kind of standard serial port paradigm.
So often the devices that we work with require, you know,
a complex set of commands in both directions to be able to do more complex things,
like, you know, maybe you're reading, like, high-volume logs
or resetting a system component or, you know, performing a firmware update.
And so this would require us to define and implement a custom protocol of messages
with various kinds of payloads.
And at that point, it's just easier usually to use a serial-type paradigm for communication.
So we'd have at least an RX and TX characteristic,
which is similar to what UART looks like,
over which the majority of the communication occurs.
So that's very common in BLE products these days.
It is. It's kind of inefficient.
Although as a developer, it's very easy because you can,
as an embedded developer,
you can just send everything to the serial port
as well as the BLE device.
And when you're developing, you just type it in the COM port,
or in TerraTerm or whatever you're using for a terminal program.
But it's usually pretty inefficient,
and it requires more battery on the device side.
And since we're talking about Bluetooth Low Energy,
that's usually an important
piece of the puzzle is trying to reduce the overhead on the device side so that you
you don't have to send as much data or all of the bits you're sending are the important bits
and you're not bothering to send the other things? I think people, first of all, do a little bit overestimate
how much power the BLE module draws from their overall devices, battery life.
But there are some things you can do to optimize that.
And so one of the things would be to,
rather than trying to minimize your payload payloads you want to you know
configure your connection parameters so you can kind of have like two modes or um two or more
maybe modes for transmission so if you are actively trying to transmit data especially like a large
amount of data you'd probably want to go into like a higher throughput mode. And so you actually, you want to, it's better to maximize like your, you know,
your power usage to maximize, I guess, decrease, maybe decrease your connection interval and
latency to maximize throughput. And it's better to get like a whole bunch of data through quickly than to try to space it out and use less power on each transmission or anything like that.
And then when you're done, you can go back into like a low power mode where you have higher connection intervals and higher latency and you can kind of just sleep.
So that's one way that I guess we deal with that.
Does that answer your question at all?
Do you have any others?
I didn't exactly have a question.
It was more of a statement that UARTs are fun,
but they're not always the best.
But they are really useful.
And you mentioned configuring the parameters, which is a pretty big thing on the device side.
Yeah.
There's how often do I advertise?
How often do I connect?
Lots of choices you have about, you mentioned interval. And this gets pretty complicated because you can, for example, with the device we've been working on, for the most part, we're in a situation where we want to be able to talk as far as we can.
And so we're fairly low data rate, but lots of space between so that we don't collide into other devices of similar nature.
But when we do the firmware update, we're going to assume you're close to us.
We want to go as fast as possible to get this over with because it isn't a big pipe.
And the firmware update of the device is going to take a minute or two,
and you don't want to stop halfway through.
Right.
So changing these parameters is important on the device side.
Do you have any of the same parameters on the phone side?
You really don't. It's another thing that iOS completely obscures. And I think part of the
reason is because you're not the only app using Bluetooth. You know, it's still one Bluetooth chip
and it's actually also, well, you're probably not using this as a central, but you can also go,
you know, use the phone as a peripheral. And then in that case, you have a GAT table and you're
sharing the GAT table with everything else on the phone that needs Bluetooth. So, yeah, I think just that's why Apple can't really give you any insight into that.
But that said, I think it generally is the embedded device that does all of the requesting
and setting of connection parameters, and then the central can reject or accept them. Is that what you found in your
experience? Yeah, so Apple only accepts some of them. So, you know, you have to guess some.
Yes, absolutely. And again, Apple has this, I don't know if you've seen it, the Apple accessory design guidelines doc.
And so, yeah, it lists all of those rules there.
So it has rules for what your connection parameters have to be and sort of some ranges.
And then also for advertising intervals, what it suggests using in different situations.
And its range of what it suggests using is smaller than the range that BLE suggests,
or the Bluetooth committee.
So you can't just go with defaults all the time, which is very sad.
Yeah, absolutely.
I know.
And that's the frustrating thing is because, you know, especially if you're trying to target Android and iOS, they might have completely different, sometimes opposing, you know, suggestions or best practices. the bonding triggers. So Apple wants you to use insufficient authentication,
which means you read from an encrypted characteristic,
and that triggers bonding.
Whereas we've done a lot of tests on a variety of Android devices,
and what works best, what's most reliable for the Android device really depends on the manufacturer and the stack.
And so for some of them, they seem to prefer insufficient auth.
Some of them, it's more just like on connection.
And then some of them, maybe it's a little inconclusive.
So yeah, it's something you just have to consider.
This is why we always answer, it depends.
Yeah, that's really the answer to everything in software, isn't it?
In tech.
And if anybody out there is wondering
about how to set those parameters,
Mohamed over at novelbits.io
has a couple of really good blog
posts about maximizing throughput
and minimizing power or
whatever your goal is. Because
BLE has multiple goals.
And you have to figure out what you want
and then you have to figure out the parameters to get it.
I will say we also have some great blog posts on that stuff, on maximizing throughput.
Yep, we have a whole host, actually, of embedded resources in our blog repertoire.
So definitely check those out if you're curious.
I will check them out, and I might get a few from you to put in the show
notes yeah absolutely are there any things in the ios app that affects the power of the phone
um that's the kind of thing that's yes but it's hard to really pinpoint, and it's not something we worry too much about on the mobile side.
First of all, if you're actually trying to measure it, that's not an easy thing to do.
It's so hard to set up a controlled environment with an iPhone where you are really isolating um the effects your app has on your
app's behavior has on the phone versus just other activity that could be going on um so yeah when it
comes to maximizing like phone battery it's just kind of what you would think is you know if you're
doing if you're constantly waking the app up in the background to do lots of like high volume
transfers which on its own might have
limitations um and could get your app killed by the os if you're doing it too much but um
you know if you're doing that kind of thing yeah that could or if you're i don't know just yeah
high throughput maybe um for a long time like large long long reads and writes, that could affect it. But yeah, overall, it's not
something we have to worry about too much on the iOS side.
Chris, do you have any questions that you wish you'd known when you started or that
you want the answers to now?
I guess the big takeaway is that you have way less control
than you do as an embedded developer working on the device side.
So just expect to just do what Apple says and accept it.
Absolutely. Do not try to fight Apple. It won't end well.
Oh, I guess we didn't really talk about debugging at
all oh right do you have magical debugging methodologies uh are you wondering about
debugging your like help using xcode in your and your um app to help you debug your bluetooth
device your embedded device or are you thinking more about just debugging your own app code?
I think the app code on the iOS device,
because debugging my embedded device, I'm probably using LightBlue.
But if I were to try to make an iOS device,
I mean, do you guys have printf and everything?
You don't have a JTAG.
I can't connect to the JTAG on the phone.
It's got more than I know how to deal with.
I'm very bad with the debugger because it does a lot of things
and I'm not quite sure what they all are.
And then they have other things like instruments,
which I haven't used very much.
You can play the keyboard?
Yes.
But I mean, there's a lot of visibility into the apps,
but it's sort of overwhelming to me.
So I haven't really spent a lot of time in that
other than set a breakpoint and see what's going on.
Yeah, and so like you said,
Xcode does have all of your typical debugging tools
that you'd expect from, I think, most IDEs.
So you've got print statements and a debug console
that the print statements will dump out to,
and setting breakpoints to examine the code.
And it has some nice other visual things where you can examine
the state of all the local variables or like the variables in that environment
and the scope relative to where you set the breakpoint. So you can see like, hey, like,
why don't I, you know, why is this value not what I think it is? What does this array contain? You
can examine objects pretty much like their whole hierarchy. So that's cool. And then, yeah, and
then you did mention instruments.
Even I don't play around too much with the instruments.
There's so many.
There's a lot that Apple provides,
and I think there's also some of them are third-party.
So I can't speak too much to those.
But even Xcode has a couple of other cool tools,
like there's a UI
debugging mechanism well it's kind of it's it's like you can freeze your app at a certain where
you know wherever you are in it and it'll show you the UI stack in like a 3D model that you can
drag around and rotate and that you can see like oh my gosh my button that I wasn't seeing it's
20 pixels or 20 points off screen and it's
or it's you know it's only one point wide and then um so that's cool or there's also like a
thing that you can pause and get like track down memory leaks um in your code so there's all of
that's available just right from xcode from the main where's that one which one no reason no reason
that one um i do, I find it annoying sometimes
because it takes so long when you press it occasionally
to actually show up.
But yeah, it should be if you're actively running your code,
you have that debug console on the bottom.
And there's two windows, but either one.
And then you have a place where you can step over breakpoints or pause your app.
And then it's one of the buttons there.
It's like a little, it's like three triangles, I think.
Sorry, three triangles, three circles connected.
That's the little icon for the debug memory graph.
Okay.
I'm using SwiftUI, and I think it's just the way SwiftUI is, that it has some memory leaks inherent in it.
Oh, yeah.
But I do need to track down maybe where they're coming from.
Why are you using SwiftUI?
It seemed like a good idea at the time.
It's not that you shouldn't.
It's really cool.
I'm excited about it.
I haven't sat down and tried to really play around with it yet
because it's so different.
It starts out really easy until you try to do something
that it's not really well designed to do.
That's exactly how I felt about Storyboard,
so that doesn't surprise me.
And Storyboard, for those who don't know,
that's like Xcode's GUI.
It's like a drag-and-drop UI builder GUI.
And now they've replaced it with SwiftUI.
We didn't talk about that at all.
That's fine. That's four other shows.
Yeah, Xcode UI, iOS UI building. Just find a tutorial for that.
It's probably not great to talk about without any visuals anyways.
It's a lot of like, go to this menu.
I did have one more question that I just remembered.
A lot of times it's not, okay, just make me an iOS app.
It's make me a mobile app that runs on everything.
Is there any best practice for I need an iOS and an Android?
And well, I guess there's nothing else anymore,
but it used to be there was Windows Mobile.
Sidekick was from 2002
Is there any hope for doing anything cross-platform
or any advice for how to make that easier
or is it just get two teams and build two apps?
Yeah, that's our recommendation always
is don't try to do cross-platform
I'm sure things keep improving.
I'm sure that there are good tools out there.
And we haven't dug into it super recently.
Again, just because it's always seemed like
it causes more problems than it's worth
to try to do one cross-platform code base
instead of maintaining two native ones.
And that's usually because no matter how cross-platform it is,
there's still this underlying,
you have to end up working directly
with the individual Bluetooth libraries themselves.
And there's a lot of differences between,
I mean, not a ton,
but there are differences between the way Bluetooth works on Android and on iOS. this entire dispatcher library, and that handles queuing and dispatching messages
so that you don't get buffer overruns.
And I guess Android just doesn't handle that very well on its own, but iOS does all of that
for you. So that's just one example where I would imagine it would be kind of a
nightmare unless you were able to inject your own
layer to handle that in Android
or maybe the cross-platform library handled it for you,
you'd end up just doing, it's a lot of headache.
So, yeah, we always recommend to our clients,
we steer them away the second they try to do a cross-platform.
That's good to know.
I mean, so many times I'm like, you can't have to write two apps.
But it sounds like, yes, you have to write two apps.
You may not start out writing two apps, but you'll end up writing two apps.
Actually, you'll probably end up writing three.
Right, right.
That's exactly right.
Let's see.
You are hiring, or Punch Through is hiring.
Could you tell us what you're hiring for?
Yep. We are currently hiring embedded engineers.
So if there are any of you listening who is an embedded engineer and you are in the Minneapolis general area or you are thinking you want to move there, then please reach out to us.
You can just go to to punchthrough.com.
We have a careers page.
Or, yeah, just email us directly, I think, info at punchthrough.com
or careers at punchthrough.com.
I might actually have to check that, so I don't know if you want to strike.
You might want to strike that, and maybe I'll just look that up later.
There will be a link in the show notes.
Yeah, definitely you can go to our website and go to the careers page. And is it remote or you should want to be in Minneapolis?
It's yeah, you'll, you'll, we, we'd like to hire people in Minneapolis. We used to have a San
Francisco office, which is where I came from. But these days we are pretty much fully just
Minneapolis with a couple of remote satellites here and there.
Okay.
And Gretchen, do you have any thoughts you'd like to leave us with?
I would say Bluetooth is, you know, it's a niche space and it does require a lot of cross-platform knowledge of complex systems.
So yeah, don't get discouraged if you're having issues spinning up an end-to-end connected product
or the whole thing is just feeling really overwhelming.
There's a reason we have completely separate teams,
full teams dedicated to handling mobile versus embedded versus hardware.
So if you do manage to create something that works
even on a small scale on both sides
or even on one side of the equation,
that's still extremely impressive
and something you should be proud of yourself for doing.
Cool.
Thank you so much for being with us.
Thanks, Gretchen.
Thank you guys so much.
Our guest has been Gretchen Walker,
mobile software engineer at PunchThru. Thank you guys so much. Mike. And of course, thank you for listening. You can always contact us at show at embedded.fm
or hit the contact link on embedded.fm. And now a quote to leave you with.
Carl Sagan or Dr. Seuss? I vote Dr. Seuss.
From there to here, from here to there, funny things are everywhere.
I thought that was from Apple's core Bluetooth talks.
Could be.
Embedded is an independently produced radio show that focuses on the many aspects of engineering.
It is a production of Logical Elegance, an embedded software consulting company in California.
If there are advertisements in the show, we did not put them there and do not receive
money from them. At this time, our sponsors are Logical Elegance and listeners like you.