Embedded

View Original

345: Do What Apple Says

Transcript for Embedded 345: Do What Apple Says with Gretchen Walker on BLE iOS apps.

EW (00:00:00):

Welcome to Embedded. I am Elecia White here with Christopher. Remember when we asked if you want a show about making BLE iOS apps? Enough of you said yes that we found an expert to speak with us.

CW (00:00:19):

Somebody better than me.

EW (00:00:20):

We can compare Christopher's experience with Gretchen Walker's.

CW (00:00:24):

Hi, Gretchen. Thank you for joining us.

GW (00:00:26):

Hi, guys. Thanks for having me.

EW (00:00:29):

Could you tell us about yourself as though we met at an embedded systems conference?

GW (00:00:37):

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 PunchThrough, which is based in Minneapolis, and I've been living in San Francisco and working for PunchThrough for the past five years or so.

EW (00:00:59):

PunchThrough sounds familiar. You make LightBlue.

GW (00:01:02):

Yes. You've used it?

EW (00:01:04):

Oh, yeah.

CW (00:01:05):

Extensively.

GW (00:01:06):

I love to hear that. We love to hear that.

CW (00:01:08):

For years.

GW (00:01:09):

Oh, that is so awesome. We love to hear that.

EW (00:01:13):

Okay. Well, we'll talk more about what that is and why you'd use it, but first, we want to do a lightning round where we ask you short questions and want short answers. Are you ready?

GW (00:01:22):

I am ready.

CW (00:01:23):

If you had a complete blank check, what iOS app would you want to write?

GW (00:01:29):

Oh, gosh! That's a curve ball. I should think about that. Yeah. I don't think I have a good answer for that off the top of my head. Is that okay?

CW (00:01:40):

Yes.

GW (00:01:41):

I'm sorry, but that one threw me.

EW (00:01:45):

Which is more exciting to you, machine learning or virtual reality?

GW (00:01:49):

Oh. Well, I don't know a lot about either. I've never played around with either, but I think they're both exciting in their own way, obviously, but I think virtual reality is cool. Even more so, I think augmented reality is cool just because it's already happening with your basic devices, and I love the interaction between the phone and your environment and the virtual space. So, I think that's what I prefer.

CW (00:02:20):

What do you like to listen to when programming, if anything?

GW (00:02:23):

I actually cannot listen to music while programming.

CW (00:02:25):

You're the second person who said that.

GW (00:02:28):

Really? Yeah. I feel like everybody else in my office does. Yeah. I've tried. I could maybe do something with no words, but otherwise, it just distracts me. I might have to be in the right mood and I could listen to some, I don't know, EDM or something, even though that's not actually what I listen to normally, but, yeah. I probably can listen to any music that I normally would because I'd probably get too into it and get distracted.

EW (00:02:56):

Do you have a favorite programming language?

GW (00:02:59):

Well, I feel like my 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 did they do it this way?" So, I don't know if you can relate to that?

EW (00:03:15):

Oh, my God! The semicolons.

GW (00:03:16):

Yeah. Exactly, like, "Ugh!" No. So, I've been writing in Swift or most of the time Swift and some Objective-C for the last, yeah, five years. So, Swift probably has to be my default favorite. Python is 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.

EW (00:03:47):

Do you have a tip everyone should know?

GW (00:03:51):

Can it be nontechnical?

CW (00:03:53):

Yes.

EW (00:03:53):

Yes.

GW (00:03:53):

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. I mean, 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. A couple of years ago, I decided I need to do something about it.

GW (00:04:22):

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 across the rest of your body.

EW (00:04:37):

All right. I want to ask you about BLE iOS apps now.

GW (00:04:43):

Sure.

EW (00:04:44):

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, and I have an iPhone, what do I do? Where do I start?

GW (00:05:04):

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. That's free, but it can only be run on a Mac. So, if you don't have-

EW (00:05:22):

That's less free.

GW (00:05:23):

That's much less free. If you don't have one, just go out, drop a couple of thousand dollars and, yeah. Sorry, Windows users, but it is Mac only. That's classic Apple, isn't it?

GW (00:05:37):

So, that's the first things you'll need. Then you'll probably want to get an Apple developer account of some kind. So, you mentioned distribution of your apps, so in that case, you would need the standard. It's $99 a year, so drop a little more money on a standard developer account. So, that will allow you to build releases and distribute by the app store or a TestFlight for beta testers.

GW (00:06:08):

If you just want to play around and develop for yourself, you can start out with just a free account, which I think they have now. The only drawback with that is you can't distribute, and then also I think the builds that you put on your phone are going to expire up to seven days. So, it's just for at home use.

EW (00:06:30):

You mentioned TestFlight. What is that?

GW (00:06:34):

TestFlight is a tool for distributing beta builds of your app to other people. 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, yeah, distribute your beta builds without going through the app store.

CW (00:06:56):

It works like the app store, right? The interface to submit things is the same. They actually review it a little bit, which I found to be quite annoying.

GW (00:07:03):

Oh, yeah.

CW (00:07:05):

So, you get 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-

GW (00:07:13):

It is. Yeah. There's actually two ways to distribute via TestFlight. So, it sounds like you went through adding external testers and then you might have also seen the option to add internal testers. 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?

CW (00:07:52):

Yeah. They've rejected me about four times before I finally figured out the right incantations and the info PList for the permissions they wanted. I think I had to put in warnings, too, like, "Hey, this uses Bluetooth" popup message and stuff.

GW (00:08:08):

Yeah. They find different steps of the way to reject you. They break it up into different steps, so it's not just you build it and then you upload it and they tell you right away if it's wrong. There's four steps that you have to go through in each of those. They could just reject you and then you have to go through them all again. Yeah. So, Apple likes to have fun there with their developers.

EW (00:08:28):

So, what is involved with releasing through TestFlight? What's a PList?

GW (00:08:35):

Oh, a PList. So, it's actually ... Oh, 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 a really simple just representation of I think it's like a dictionary or an array. Usually, it's a read level. Anyways, it's just like a list ... Well, it depends on the PList, but, anyways, it's just a list of keys. 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.

GW (00:09:17):

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 will crash as soon as you try to use anything with the Bluetooth library..

GW (00:09:32):

So, there's stuff like that or it needs certain, yeah, other permission like the camera or it needs to be able to run Bluetooth in the background. So, that's where you specify things like that.

EW (00:09:43):

So, when Chris made the app, in order to get it on my phone to test with my devices, I have to give him my Apple ID, and then TestFlight invited me?

GW (00:09:58):

Yeah. So, you will need to either ... If you're doing the external testing route, which it did sound like you went through, I think you can just-

EW (00:10:08):

Definitely.

GW (00:10:08):

... 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 them to your Apple developer account, and that's going to be an Apple ID, but, yeah, for external testers, too, maybe it does have to be an Apple ID.

GW (00:10:27):

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. So, you go into their email.

EW (00:10:47):

Yes.

GW (00:10:47):

Yeah, and you have to click the link to download the app or it will open in TestFlight or something. 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?"

EW (00:11:04):

Although a TestFlight was confusing, I mean, it's good that it's there because you know how to go through the whole app store and you don't have to show off things that aren't right, but as somebody 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. Then finally, you program the boards with the firmware I gave you and you can try it out."

GW (00:11:33):

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 tried distributing an Android, what that's like in comparison. Have you ever done that?

CW (00:11:48):

I've been near people who've done that.

GW (00:11:50):

That's close enough. Yeah. So, Android is just going to build a release and you get a .apk file. That's the file, and then you could just drop-

CW (00:11:59):

Just throw it around.

GW (00:12:00):

... drop that onto somebody's phone, and it will run, and that's it.

CW (00:12:05):

I mean, it is cumbersome, but it does have some features because the user, if they have a problem, it automatically does a screenshot, and you can submit stuff and report things right from the app, and then it will go straight to the developer, and they get a back trace and a screenshot and the description of the bug. So, it has some nice features, but it is rather painful to go through.

GW (00:12:26):

Exactly, yeah. No, that's true. They're straight offs.

EW (00:12:30):

Okay. So, I guess that's before the app is knowing about XCode in 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?

GW (00:12:51):

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 methods and facts, and you'll never want to come back. So, it is definitely what Apple is pushing these days and what they want you to use. So, what Apple wants, Apple gets.

EW (00:13:16):

It looks pretty C-like to me.

CW (00:13:19):

Swift?

EW (00:13:19):

Yeah. I mean, the syntax.

CW (00:13:23):

Some of it.

GW (00:13:24):

Some of it is. Yeah. It's a weird hybrid of there's some C things. There are some things that are a little bit more, I don't know, maybe a little more like Python or Ruby or something, where it's very clean. You don't have your semicolons or anything like that. Then they some of their own just unique syntax like you indicate a return with you draw an arrow with a dash and a right caret and put the return type. So, I don't know. It's actually what it is similar to a 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.

CW (00:14:08):

For an embedded developer coming from C, it's kind of jarring because, I mean, it's not an object or an inner language, but that Apple pushes its protocol around it. There's a lot of more generic language concepts that somebody has to become familiar with coming to straight procedural C.

GW (00:14:24):

Right. Yeah. You're not using those raw types ever like you use in C. So, in that sense, maybe Objective-C would be more comfortable with, but Swift is just more-

EW (00:14:37):

No, I've tried that.

GW (00:14:39):

I mean, that's the thing.

EW (00:14:40):

I'd rather learn something totally different.

GW (00:14:43):

Honestly, I 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. Like I said before, it's any new language you feel like, "Ugh! Why did they do things like this? It's so much better than the language I usually use," but then you get used to it, and it gets better.

CW (00:15:04):

Do you have any suggestions for resources to learn Swift from the beginning?

GW (00:15:09):

I mean, yeah. Obviously, they have their docs, but it's not necessarily something that's user friendly to just dive in to. So, personally, I don't know if they actually have a tutorial on Swift, specifically, but are you familiar Ray Wenderlich? I think that's how you say his name? I mean, they have tutorials for everything. They probably have some resource for Swift, but, yeah, I had to give a specific guide that I remember using.

CW (00:15:46):

Yeah. No. I remember when I was learning, I did a bunch of the tutorials on that site. That was really good. Some of those stuff I use. There's a couple of books from Big Nerd Ranch that I like and those were good, but-

EW (00:16:00):

Is it Big Nerd or Big Ranch? Is it Big NERD Ranch or Big Nerd RANCH?

CW (00:16:06):

I don't know. I'd never really thought about it till now.

EW (00:16:09):

Come on.

CW (00:16:09):

Yeah. I did a bunch of Udemy classes and stuff, but, really, the Ray Wenderlich site and the books were the best, but there's some learning curve, at least for me.

GW (00:16:23):

Yeah. There always is. Yeah.

EW (00:16:25):

So, does Swift work with Bluetooth? I mean, you've told me that I should use Swift, and I already said I was doing Bluetooth. So, there might be something to connect them. Library? Framework? What is it?

GW (00:16:39):

Sure. Yeah. So, Apple provides this library called CoreBluetooth, and that is what you would use to interact with Bluetooth devices on, yeah, iOS, MacOS, I think also maybe TV and WatchOS. So, that's what you would use.

EW (00:16:59):

Is this Bluetooth like the old Bluetooth that was audio or BLE?

GW (00:17:06):

Yeah, it's not clear, but it technically was developed for Bluetooth low energy, and there was a separate library for interacting with Bluetooth classic devices. Yeah. The way a 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 is using Bluetooth low energy.

GW (00:17:31):

These days, they're trying to move towards more of a high breed of like I think now the Bluetooth low energy stack or spec, I think, is going to support or already supports adding a GATT table, which used to be like a Bluetooth low energy-specific thing, adding a GATT table to a Bluetooth classic device.

GW (00:17:57):

So, if the peripheral supports than, then now they have a new API in CoreBluetooth to be able to retrieve those kinds of devices and connect to them and read their GATT table and then use the same APIs to read their GATT table and all that. I haven't played around with that too much because I haven't really found a device that works like that, but that's exciting.

CW (00:18:21):

So, what does CoreBluetooth give you? What kinds of things will it do for you or at what level is it at?

GW (00:18:30):

Extremely high, extremely high level. Yeah. If you are at the point that you've already developed 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 CoreBluetooth successfully.

GW (00:18:48):

So, if you just know your basics of Bluetooth, you've got two roles that a device can take on, 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, it's 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 these characteristics. I basically just described the API and what it looks like.

CW (00:19:21):

All of Bluetooth.

GW (00:19:22):

That's just what the API looks 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. So, it's good in it.

CW (00:19:48):

That's my second question is what doesn't it do.

EW (00:19:50):

It doesn't tell you when it completes things.

CW (00:19:53):

Well...

GW (00:19:55):

Well, yeah. So, I'd say that one of the biggest things that people complain about, 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.

CW (00:20:14):

Oh, God!

GW (00:20:15):

So, if you are familiar with that, probably what pairing and bonding technically is different from just for a standard connection, are you familiar with that?

EW (00:20:24):

Oh, yeah. Oh, yeah. If you wanted 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, and then-

CW (00:20:32):

... which, which, which iOS just pops up randomly when it feels like it.

GW (00:20:37):

Yes.

CW (00:20:39):

It's not part of your app.

GW (00:20:39):

No. You have-

EW (00:20:41):

... 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 is horrible.

GW (00:20:54):

Exactly. So, I mean, yeah, it's something you do want because it's the standard security. So, a lot of devices, you will want to have that, but it does just create all these issues because, yeah, like you said, your app has no idea. You'll call connect to a device and it will technically connect because that's a separate thing from pairing and bonding that pairing and bonding comes after connection.

GW (00:21:16):

So, you did connect callback and you think you're ready to go, but then you might still ... Well, I also depends on how pairing and bonding is triggered. There's a couple of ways. It can either be on connection or the way Apple likes you to do it is you have 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 dialogs popped up and if the user said yes or if they're just sitting there and not noticing it.

GW (00:21:48):

So, and then like you said again, yeah, 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 got to go to settings and clear it and forget it." You can't even deep link to that menu. You can link them to settings, but just the high level page. So, it's, yeah, that's the kind of stuff that CoreBluetooth frustratingly does obscure from you.

CW (00:22:19):

At the risk of asking you to do my homework for me, what I ended up doing is, since I wanted 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.

GW (00:22:43):

So, yeah. They have this accessory design guidelines PDF that they've put out. I mean, it's huge, but there's a section on Bluetooth and it lists all the rules that it likes you to follow, it likes its devices to follow. So, one of them 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.

GW (00:23:15):

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 I think on connecting and then you can also configure it to whether it should just be it's called just works, where it just pairs and bonds and it pops up the pairing, like do you want to pair dialog, but it doesn't do the pin number. You can configure whether it should enter a pin or just give you a popup.

EW (00:23:46):

You have to have the pin or it's really not secure.

GW (00:23:49):

I don't know.

EW (00:23:52):

You studied getting the pin, Christopher. There's no way to do it without the pin.

CW (00:23:57):

She's doing the firmware. So, I'm glancing at her going, "Hey, maybe you should try that," and she's saying, "No."

GW (00:24:02):

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? Just making sure that ... Well, I guess it depends where you're getting that pin number from because sometimes that thing is printed on the device, but, yeah.

GW (00:24:18):

I mean, usually, if you really want to have proper security of 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 could speak to how much the pin itself really provides.

EW (00:24:36):

It provides against casual intrusion. For example, the app we're working on, I have DevInfo outside the pair bond because you can read that on connect. You don't have to know anything about the system. DevInfo is the GATT, which is the list of characteristics that is standard on Bluetooth. It describes a device. It's the device info. So, yeah, I have that outside, and so he has to read one of the encrypted things in order to get bonded.

CW (00:25:16):

Okay. That makes sense.

EW (00:25:17):

Our pins are set in manufacturing, and then he has to go to a website in order to get the pin for this device.

CW (00:25:23):

Fine, fine, fine, fine.

EW (00:25:23):

So, it's pretty complicated, but it is more secure than having your pin be 123456, which is the default TI password and so many people still use it. It's not a good pin.

GW (00:25:38):

Yeah. I've definitely seen that before too many times, but, yeah. Really, everything comes down to your use case. Is that something that you want to have to make users do or some ... A lot of the time we're working with certain medical devices and you have an older population, maybe. So, then you have to worry about any extra step in the process and 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 into the surface.

EW (00:26:18):

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 server. The iOS app has to go ask the server where the pin is.

CW (00:26:29):

iOS say, "I can't provide the pin."

EW (00:26:32):

So, I think you're going to put the pin on the screen, and then when it pops up to the user and says-

CW (00:26:36):

They're going to have to type it.

EW (00:26:38):

It has to copy from the app to the iOS popup.

CW (00:26:44):

I can't do that. They're going to have to type it.

EW (00:26:46):

There's no way to avoid that?

CW (00:26:47):

No. The pairing popup is from the system.

EW (00:26:53):

That's silly.

CW (00:26:53):

I don't even know it's there.

EW (00:26:54):

Yeah. You just have to put up the pin number for that device.

CW (00:26:59):

Please type what this says right here. That's what we're going to have to do.

EW (00:27:00):

That's silly.

GW (00:27:04):

Yup. That's what they make you do.

EW (00:27:08):

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 the initialization section and then there should be the loop and you should just do the 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.

CW (00:27:42):

No.

GW (00:27:43):

I mean, your app does have a main loop that you don't touch, really. That's actually in C. That's a file you'll never probably touch when you're developing an iOS app, but, yeah. The way that Apple and their APIs handle asynchronous callbacks is via delegation, which, yeah, 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 use passing as a parameter, passing like a lambda function.

GW (00:28:22):

So, then at least your code where you call the method and then the callback code is all in one place like maybe the same function. So, that's just so much better for readability, I think. 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 you have your callback methods are going to be in a completely different place from where you called the original code. 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 gross. Usually, you want to avoid doing that too much.

GW (00:29:05):

So, yeah, that's why people have been moving towards other paradigm. Block-based callbacks are nice, and then, well, expanding on that, the Rx pattern has become more and more popular. There's an RxSwift library. I think there's actually two out there that, yeah, make everything more like reactive. So, people have been trying to get around Apple's initial API designs forever.

CW (00:29:34):

Well, Apple just introduced Combine, which is their version of Rx.

GW (00:29:37):

Yup.

CW (00:29:38):

So, I guess they'll start doing that. I found the whole API really frustrating and unSwift like.

GW (00:29:45):

It's Objective-C like, I guess.

CW (00:29:47):

Yeah. That keep getting in corners where stuff will happen because it's just these callbacks and there's only one ... You just said there's these delegates, which is like an object that gets called back. There's only one of them. So, if I'm at a different section of the Bluetooth stuff I'm working on dealing with different part of the peripheral, I still get the callback in the same place. So, it's like, "Okay. What does this pertain to? Oh, this isn't what I was ..."

CW (00:30:18):

So, 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." So, yeah. That's weird.

GW (00:30:30):

Yeah. I feel your pain. Yeah. Delegates are definitely a one-to-one relationship thing. So, yeah, if you find yourself you have multiple classes that need to access those, you could pass the delegate handler off and assign each class to the delegate property of the main class, but that's not great. So, the other way to do it is then implement a notification layer. You can use internal app notifications to notify most of all different classes of what's happening. That's probably what I'd recommend if you're just quick building a little layer on top of that.

EW (00:31:11):

Okay. So, you just said that's what you recommend. Okay. So, Swift, CoreBluetooth and Rx or Combine or-

CW (00:31:24):

No. I wouldn't recommend that.

GW (00:31:25):

I wouldn't start with that.

EW (00:31:27):

... Delegates, but do something with classes in delegates.

GW (00:31:30):

Yeah. I would go with the delegate stuff to begin with because that's the simplest path forward. It's not the end of the world, especially if you're using something, if you're building something simple and more of a prototype deal.

EW (00:31:44):

That's really where I'm asking my questions from is the prototype sort of thing because as an embedded engineer, what I most likely wanted 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."

EW (00:32:04):

How much do I need to know about all the other things about BLE, all the power management and GATTs, and characteristics, and read notify write, and that sort of thing? Do I need to know those or can I just glide through? Will it work for me? Will it explain things as I go with the CoreBluetooth?

GW (00:32:33):

Yeah. I mean, I don't know if the docs are as straightforward as they could be. You probably want to find a tutorial. We have a blog post about this. So, it will help you out, but, yeah. The power management stuff, absolutely. You don't really have any control over that other than just minor things you can do to worry about the phone's battery life.

GW (00:32:57):

The services and characteristics, again, it's these very high level object representations of what they are. So, you'll just see you have everything in CoreBluetooth API's prefixed with CB for CoreBluetooth. So, you'll have a CB service and a CB peripheral, and each CB service has an array of CB characteristics, and they all have a UID property, and maybe the descriptors on them, and the characteristics have a value property. That's just like a data type, a Swift data type object. So, if that sounds reasonably straightforward, and hopefully it does, then that's all you need to know.

EW (00:33:41):

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 CoreBluetooth. I would learn about Bluetooth first.

GW (00:33:54):

Yeah. Even Bluetooth, I think, there's a lot to know about it, especially if you are working on the embedded side, but, yeah, from a mobile standpoint, you really just need to know the basics of how Bluetooth organizes data and what the buzz words are.

EW (00:34:13):

Well, back to the delegation buzz word, one of the reason it's there is because everything in Bluetooth or BLE is very asynchronous. Nothing happens in realtime because you're going over a wireless network. So, when I say I want to know the value of this characteristic, it goes off, it does it, it eventually calls you back and says, "It was this." As Chris was saying, you may be doing something else entirely by the time you get that notification. Is there a way to organize the code that makes it easier to deal with the asynchronous nature of it all?

GW (00:35:03):

Yeah. I think if that is something that you're very concerned about and you don't like the whole having to use, again, it's so use case dependent. So, it's hard to imagine I guess what your needs are, but if it is something that's just really bothering you, then maybe that is when you want to look into writing your own layer on top of CoreBluetooth, which we've done for clients developing SDKs that we've written an Rx layer on top of the CoreBluetooth library or you can write just more of a block-based layer on top.

GW (00:35:44):

So, that will then give you code that's more, again, you call your code, and then you have the callback code in the same place, and so you can access local variables you might have defined when you called in. So, that's probably the best route forward if you're not happy with just having the store state in class variables or wherever.

CW (00:36:12):

Yeah. The delegation thing, that's one of Apple's design patterns I loved for a long time until they didn't. They stuck that all that kind of stuff. I also found error handling to be a pain, and I think this goes along with the asynchronous stuff. 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 that 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 error handling for Bluetooth?

GW (00:36:52):

So, are the areas you're talking about like areas that you want to send from your device up to ... or are you just thinking more like interpreting the other areas that CoreBluetooth has built in?

CW (00:37:05):

There's something I might want to present to the user like I got disconnected or I'm trying to think of another one at the moment, but-

GW (00:37:14):

So, being able to interpret the areas that CoreBluetooth might bubble back up to you and then being able to interpret that for the user? Yeah. I mean, that's-

EW (00:37:25):

Bond failing, too.

CW (00:37:26):

Bond failing, yeah.

GW (00:37:28):

Oh, yeah. Bond failing, I mean, that might come. So, one of my biggest problems with CoreBluetooth is the errors that they can send you are extremely poorly documented. It's almost not documented. They list them all, but there's no indication of, one, they might send them and not to mention there's also two different.

GW (00:37:50):

So, you have an error like an NS error or an error super class, and then there's actually two different types of CB errors. There's CB error and CB at error, which is to do with specifically that profile.

GW (00:38:06):

So, yeah, but there's no indication if you might get one of those types versus the other and so you have to cast it to find out, and see, "Okay. Is this a CB error or is this a CB at error?" Then from there, you can try to handle all of the different errors that they could give you. 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.

GW (00:38:31):

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 just because we don't see those errors too often. So, a device disconnection would be, that's not even an error. It's either a 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-

CW (00:39:01):

I guess I'm probably encountering more errors because we're both developing at the same time. So, it may not be something that's realistic to worry about, but if I see them, then I start getting worried because this might happen in real use.

EW (00:39:14):

Hey, I apologize that I hadn't bite swapped everything yet.

CW (00:39:18):

You did. Some things we're just swapped differently than others.

GW (00:39:22):

I think it might be spoiled because the firmware I ended up working with is from people who've 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, but ... So, maybe I have a skewed point of view on how often those come up.

EW (00:39:49):

It's developing a custom GATT more than anything else, trying to decide how to display things.

CW (00:39:57):

We're using TIs from our update SDK, which does its own thing. So, we get errors from that that are just like, "Oh, everything is destroyed."

GW (00:40:09):

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 is probably the most popular one.

EW (00:40:20):

Yes, and with good reason.

GW (00:40:22):

Yeah. I think they definitely have the most-

EW (00:40:24):

I use both multiple times in multiple generations. Choose Nordic.

GW (00:40:30):

Yup.

EW (00:40:31):

Sorry, TI.

GW (00:40:32):

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 deal with the fallout from it.

EW (00:40:40):

You mentioned a blog post. I believe that it's the ultimate guide to Apple's CoreBluetooth that's on the PunchThrough blog.

GW (00:40:47):

Yes.

EW (00:40:48):

Is that right?

GW (00:40:48):

Yeah. That's the one.

CW (00:40:50):

... which I wish existed two and a half months ago.

GW (00:40:53):

I know. It just came out. It was written and 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. If you think the iOS one looks comprehensive, the Android one is just insane. It's awesome.

GW (00:41:29):

My coworker just did a fantastic job putting that together because there's so much more to know about Android BLE than there is I'd say.

CW (00:41:37):

Why is that?

GW (00:41:38):

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 wide range of manufacturers. They each have their own different Bluetooth chips. They also might have their own different fork of Android, which include, especially with Bluetooth since you're interacting with different hardware, it might include internal tweets to the Bluetooth stack, the Android Bluetooth stack. So, it might work differently.

GW (00:42:13):

Then also the versions are way more ... They 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, really.

CW (00:42:29):

I'm remembering now. We had many serious issues with that.

GW (00:42:34):

Oh, bringing back memory. Did you block this out?

CW (00:42:37):

Yeah. Well, I didn't work on Android, so I only heard the screaming from other people.

GW (00:42:42):

Well, that's my life, too. I have to sit here at iOS-

CW (00:42:45):

"Why is Samsung killing our app?" It's just because it feels like it.

GW (00:42:49):

Yup. Oh, yeah. God! Samsung is the worst because they're the most prolific that's not Google. They're the most prolific I would say phone that has really just a different stack and a different ... So, they're on fork of Android and different chip set than what Google uses. Since Google, they own Android, they control the API these days and the OS. So, yeah.

EW (00:43:19):

Well, I want to go through the post a little bit. You wrote the ultimate guide to Apple's CoreBluetooth. There's one about unit testing Android BLE code with Rx Android BLE, which I guess is a unit testing system. There is the ultimate guide to the Android, I guess not CoreBluetooth, but whatever that is, and using Rx versus delegates with CoreBluetooth.

CW (00:43:44):

Oh, that just came out.

EW (00:43:46):

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. I just want to make sure that those were mentioned. Then LightBlue, tell us about LightBlue.

GW (00:44:05):

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.

EW (00:44:19):

This is true. I mean, I used LightBlue before I have an app to develop.

GW (00:44:24):

Yeah. That's exactly what it's really, I think, useful for, but it's one of many potential functions for that app. 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. So, yeah, we were already working with that.

GW (00:44:59):

So, you can use LightBlue, and then we realized that we might as well release those 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 for you, 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.

EW (00:45:40):

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. 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, pair and bond or whatever.

EW (00:46:07):

It lets you do over the error former updates for Nordic, if that's what you're using, if you're using their code. LightBlue has a nice interface and is pretty reliable. So, I use it a lot.

GW (00:46:20):

Well, that's great to hear. Yeah. 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 and we have time internally because primarily, we are a contracting company. So, we're working on other external projects, but whenever we do, we 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 out the next big feature for LightBlue. It is available on Android and MacOS as well.

CW (00:47:07):

One of the things I really liked about it was we didn't really have a low level config app. I mean, we had the user facing app, which doesn't say anything about Bluetooth. It communicates with the devices, with Bluetooth, but it doesn't ... You're not interrogating characteristics as a user. It's connecting to your watch and showing you all the important data.

CW (00:47:26):

As a developer, there's 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. 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.

EW (00:47:48):

It's like inspecting your HTML pages, your web pages.

GW (00:47:52):

Yeah. Absolutely. Then, yeah, and you can interact with it, too. It's funny you mentioned Fitbit because that's another ... It's a funny, completely unintended use case for LightBlue, but a lot of people at this point seems like hundreds to thousands of people have turned to LightBlue to find their lost smartwatches. We have Fitbit to thank for that, actually, because I guess the list does on their website as a resource if people lost their device, but you can use LightBlue basically to ... 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 a game of warmer or colder I'll walk around your house and a lot of people have found their Fitbits that way, which makes us happy.

EW (00:48:53):

That should have been your tip.

GW (00:48:56):

Yeah. Actually, that is a good tip. I'd 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.

EW (00:49:08):

I mentioned that we created a custom GATT because we had specific information, but I also mentioned that we use an off-the-shelf standard Bluetooth one, the device information, and I've used the battery one before. A lot of people who use the UART service that makes your device acts 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 GATT? 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, handle it on top and that will be so easy?

GW (00:49:53):

So, again, it's entirely use case-dependent. So, the reason to use a standard GATT characteristic is usually for broader compatibility with 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, and then you'll already know what they are, and how to format them without you having to write any of that mobile side code.

GW (00:50:20):

So, maybe just a more interesting question like how to format your data and turn your GATT table. So, it just really depends again on your use. So, one of the major ways that Bluetooth low energy stands apart from Bluetooth classic is that instead of 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.

GW (00:50:51):

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 amount of data 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.

GW (00:51:17):

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 a complex set of commands in both directions to be able to do more complex things like maybe you're reading high volume logs or resetting a system component or performing a firmware update.

GW (00:51:43):

So, this would require us to define and implement a custom protocol of messages with various kinds of payloads. At that point, it's just easier usually to use a serial type paradigm for communication. So, we'd have at least like 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 to BLE products these days.

EW (00:52:12):

It is. It's efficient. 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 comm port or in Tera Term or whatever you're using for terminal program, but it's usually pretty inefficient and it requires more battery on the device side.

EW (00:52:41):

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 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.

GW (00:53:03):

I think people, first of all, do a little bit overestimate how much power the BLE module draws from their overall device's battery life, but there are some things you can do to optimize that. So, one of the things would be to rather than trying to minimize your payloads, you want to configure your connection parameters, so you can have two modes or two or more maybe modes for transmission.

GW (00:53:36):

So, if you are actively trying to transmit data, especially a large amount of data, you'd probably want to go into a higher throughput mode. So, it's better to maximize your power usage or I guess you'd maybe decrease your connection interval and latency to maximize throughput. It's better to get a whole bunch of data through quickly than to try to space it out and use less power in each transmission or anything like that.

GW (00:54:11):

So, and then when you're done, you can go back into a low power mode where you have higher connection intervals and higher latency, and you can just sleep. So, that's one way that, I guess, we deal with that. Does that answer your question at all or you have any others?

EW (00:54:30):

I mean, I didn't exactly have a question. It was more of a statement that UARTs are fine, but they're not always the best, but they are really useful. You mentioned configuring the parameters, which is a pretty big thing on the device side. There's how often do I advertise, how often do I connect, lots of choices you have about you mentioned interval. 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.

EW (00:55:17):

So, we're fairly low data rate but lots of space between so that we don't collide into other devices of similar nature. When we do firmware update, we're going to assume you're close to us, and we want to go as fast as possible to get this over with because it isn't a big pipe.

EW (00:55:39):

The firmware update of the device is it's going to take a minute or two and you don't want to stop halfway through. So, changing these parameters is important on the device side. Do you have any of the same parameters on the phone side?

GW (00:55:54):

You really don't. It's another thing that iOS completely obscures. I think part of the reason is because you're not the only app using Bluetooth. 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 use the phone as a peripheral, and in that case, you have a GATT table, and you're sharing the GATT table with everything else on the phone that needs Bluetooth.

GW (00:56:21):

So, yeah, I think 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 the requesting and setting of connection parameters, and then the central reject or accept them. Is that what you found in your experience?

EW (00:56:50):

Yes. So, Apple only accepts some of them. So, yeah. You have to guess.

GW (00:56:57):

Yes. Absolutely. Again, Apple has this, I don't know if you've seen it, the Apple design or accessory design guidelines, doc. So, yeah, it lists all of those rules there. So, it has rules for what your connection parameters have to be and some ranges, and then also for advertising intervals, what it suggests using in different situations.

EW (00:57:25):

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.

GW (00:57:38):

Yeah. Absolutely. I know. That's the frustrating thing is because especially if you're trying to target Android and iOS, they might have completely different, sometimes opposing suggestions or best practices. For example, the bonding types or 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 it really, what works best, what's most reliable for the Android device really depends on the manufacturer and the stack. So, for some of them, they seem to prefer insufficient offs. Some of them it's more just on connection. Some of them maybe it's a little inconclusive. So, yeah. It's something you just have to consider.

EW (00:58:36):

This is why we always answer it depends.

GW (00:58:39):

Yeah. That's really the answer to everything in software, isn't it? Tech?

EW (00:58:42):

If anybody out there is wondering about how to set those parameters, Mohammad 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 to figure out what you want, and then you have to figure out the parameters to get it.

GW (00:59:05):

I will say we also have some great blog posts on that stuff on maximizing throughput. We have a whole host actually of embedded resources in our blog repertoire. So, definitely check those out if you want, if you're curious.

EW (00:59:23):

I will check them out, and I might get a few from you to put in the show notes.

GW (00:59:28):

Yeah. Absolutely.

EW (00:59:29):

Are there any things in the iOS app that affects the power of the phone?

GW (00:59:39):

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 just because, 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 the effects of your app's behavior has on the phone versus just other activity that could be going on.

GW (01:00:12):

So, when it comes to maximizing phone battery, it's just what you would think is if you're doing, if you're constantly waking the app up in the background to do lots of high volume transfers, which on its own might have limitations and could get your app killed by the OS if you're doing it too much, but if you're doing that kind of thing, yeah, that could or if you're, I don't know, just, yeah, high throughput maybe for a long time like large, long reads and writes. Yeah. That could affect it. Yeah. Overall, it's not something we have to worry about too much on the iOS side.

EW (01:00:54):

Chris, do you have any questions that you wish you'd known when you started or that you want the answers to now?

CW (01:01:03):

I guess the big takeaway is that you have a way with less control than you do as an embedded developer working on the device side. So, I would just expect to just do what Apple says and accept it.

GW (01:01:19):

Absolutely. Do not try to fight Apple. It won't end well.

CW (01:01:23):

Oh, I guess we didn't really talk about debugging at all.

EW (01:01:27):

Oh, right. Do you have magical debugging methodologies?

GW (01:01:34):

Are you wondering about debugging your, like using XCode in your app to help you debug your Bluetooth device, your embedded device or are you thinking more about just debugging your own app code?

EW (01:01:47):

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 print-off and everything? You don't have a JTAG. I can't connect to the JTAG on this phone.

CW (01:02:11):

It's got more than I know how to deal with. I'm very bad with it because it does a lot of things, and I'm not quite sure what they all are, and then they have lots of things like instruments, which I haven't used very much.

EW (01:02:22):

It can play the keyboard?

CW (01:02:23):

Yes. I mean, there's a lot of visibility into the apps, but it's 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.

GW (01:02:35):

Yeah. So, like you said, I mean, yeah, XCode does have all of your typical debugging tools that you'd expect from I think most IDs. So, you've got, yeah, print statements and a debug console that the print statements will then be able to and you 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 the variables in that environment, in the scope relative to where you set the breakpoint.

GW (01:03:10):

So, you can see, "Hey, why is this value and 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.

GW (01:03:23):

Then, yeah, 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, you can freeze your app at a certain wherever you are in it and it will show you the UI stack in 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 soft screen or it's only at one point wide."

GW (01:04:08):

So, that's cool where there's lots of thing that you can pause and track down memory leaks in your code. So, all of that's available just right from XCode, from the main.

CW (01:04:19):

Where is that one?

GW (01:04:20):

Which one?

CW (01:04:21):

No reason, no reason, the memory leak thing.

GW (01:04:25):

The memory leaks, yeah. That one, I do sometimes 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 three triangles, I think or, sorry, three triangles, three circles connected. That's the little icon for the debug memory graph.

CW (01:04:59):

Okay. I'm using a Swift UI and I think it's just the way Swift UI is that it has memory leaks, but I thought you need to track down, make you know they're coming.

GW (01:05:09):

Why are you using Swift UI?

CW (01:05:10):

It seemed like a good idea at the time.

GW (01:05:17):

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.

CW (01:05:25):

It fools you. It starts out really easy until you try to do something that it's not really well-designed to do.

GW (01:05:31):

That's exactly how I felt about storyboards. So, that doesn't surprise me. Storyboard, for those who don't know, that's XCode's gooey. It's like a drag and drop UI builder gooey, and now they've replaced it with Switch UI.

EW (01:05:47):

We didn't talk about that at all.

CW (01:05:48):

That's fine. That's for other shows.

GW (01:05:51):

Yeah, XCode UI, iOS UI building, just find a tutorial for that. It's probably not great to talk about over without any tools, anyways. That's a lot of like this, "Go to this menu."

CW (01:06:05):

I did have one more question 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.

EW (01:06:23):

Sidekick.

CW (01:06:24):

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 built two apps?

GW (01:06:36):

Yeah. That's our recommendation always is don't try to do cross platform. I'm sure things keep improving. I'm sure there are good tools out there, and we haven't dug into it. Super recently, again, just because it always seemed like it causes more problems than it's worth to try to do one cross platform of code base instead of meeting to native lens. 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.

GW (01:07:30):

For example, iOS handles more of the one thing that we always have to write a Bluetooth, well, we have written for Bluetooth Android apps is this entire dispatcher library, and that handles dispatching, queuing and dispatching messages, so that you don't get buffer overruns. I guess Android just doesn't handle that very well on its own, but iOS does all of that for you.

GW (01:07:56):

So, that's just one example, right? I would imagine it would be a nightmare unless you were able to inject your own layer to handle that on 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 stir them away the second they try to do a cross platform.

EW (01:08:22):

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.

CW (01:08:31):

You may not start out writing two apps, but you'll end up writing two apps.

GW (01:08:34):

That's exactly right.

EW (01:08:34):

Actually, you'd probably end up writing three.

CW (01:08:40):

Right, right.

GW (01:08:40):

That's exactly right.

EW (01:08:40):

Let's see. You are hiring or PunchThrough is hiring. Could you tell us what you're hiring for?

GW (01:08:45):

Yup. We're currently hiring embedded engineers. So, if there are any of you listening who's 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 punchthrough.com. We have a careers page or, yeah, just email us directly, I think, info@punchthrough.com or careers@punchthrough.com. I might actually have to check that. So, I don't know you might want to strike that, and maybe I'll just look that up later.

EW (01:09:22):

There will be a link in the show notes.

GW (01:09:24):

Yeah. Definitely, you can go to our website and go to the careers page.

EW (01:09:28):

Is it remote or you should want to be in Minneapolis?

GW (01:09:35):

Yeah. 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.

EW (01:09:46):

Okay. Gretchen, do you have any thoughts you'd like to leave us with?

GW (01:09:53):

I would say Bluetooth, 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.

EW (01:10:35):

Cool. Thank you so much for being with us.

CW (01:10:39):

Thanks, Gretchen.

GW (01:10:40):

Thank you guys so much.

EW (01:10:42):

Our guest has been Gretchen Walker, mobile software engineer at PunchThrough. Thank you also to Christopher for producing and co-hosting. Thank you to Bailey over at Dojo Five for pointing me toward Gretchen. Thank you to our Patreon listeners Slack group for their questions and for Gretchen's mic. Of course, thank you for listening up. You can always contact us at show@embedded.fm or hit the contact link on embedded.fm.

EW (01:11:09):

Now, a quote to leave you with. Hmm. Carl Sagan or Dr. Seuss?

GW (01:11:15):

I vote Dr. Seuss.

EW (01:11:17):

"From there to here, from here to there, funny things are everywhere."

CW (01:11:23):

Oh, I thought that was from Apple's CoreBluetooth docs.

EW (01:11:26):

Could be.

EW (01:11:29):

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.