PodSearch

Under the Radar

317: Optimizing for Battery Life

 

00:00:00   Welcome to Under the Radar, a show about independent iOS app development.

00:00:03   I'm Marco Arment.

00:00:05   And I'm David Smith.

00:00:06   Under the Radar is usually not longer than 30 minutes, so let's get started.

00:00:09   So today I want to talk about power, or in the context of the ways we use it, battery life

00:00:15   is probably more specific because we're not particularly – like that is the limiting

00:00:20   factor for a great many of our apps and the way that they get used, especially for things

00:00:25   that we both make, which are long-lived, long-run applications.

00:00:29   So if someone might use Pedometer++ to go out for an all-day hike, or they might open

00:00:35   Overcast and listen to a podcast while going out on an all-day hike.

00:00:39   And so in both of those cases, battery life and power consumption become an important aspect

00:00:45   of the user experience.

00:00:46   And battery life and power consumption are just a very difficult and challenging thing to optimize

00:00:53   and to get right in a way that is sometimes – I personally find very frustrating, but

00:00:58   it's something that I've been working on a lot recently.

00:00:59   Like in the last few months, I've been working on a mode in Pedometer++ that's focused on

00:01:04   sort of long endurance days.

00:01:06   So like being able to go out and track a workout for maybe for 20 hours, that's a very different

00:01:11   thing than if you're going out for a couple of – you know, like a 20, 30-minute run.

00:01:16   And so I've been doing a lot of work on battery life and power management and sort of – it

00:01:21   seemed a good topic to discuss.

00:01:23   I think I have some – it's like some hints, some tips, some pitfalls, some frustrations.

00:01:27   There's just a lot of things that kind of go into this because it's not as straightforward

00:01:31   as some of the other optimizations we might be doing where it's very easy to just open

00:01:36   instruments.

00:01:36   You run it.

00:01:38   You run your app with instruments connected, and you can run the time profiler, and you'll

00:01:41   see where your app is spending the most time.

00:01:45   And obviously that's related to power and battery consumption, but the power and battery

00:01:49   implication of just using a lot of CPU is more nuanced and complicated.

00:01:54   Because fundamentally, I think the thing that's challenging is ultimately power consumption

00:01:59   is going to come from two things.

00:02:02   One, the most obvious, is that it's just the work you're doing on the CPU, the GPU.

00:02:06   Like, your app is, you know, doing something.

00:02:09   That's what it's doing.

00:02:10   And that work will use power.

00:02:13   Just fundamentally, that's the nature of electronics and how these things work.

00:02:17   And the other place you'll use power is if you are ever transmitting or receiving anything,

00:02:22   whether that be sound, you know, photons from the display, Wi-Fi, GPS, any of these kinds

00:02:28   of things that are sending or receiving any kind of data, those things are using power.

00:02:32   And fundamentally, improving and extending the battery life of your app and reducing its

00:02:38   power consumption is fundamentally going to be about doing less of one of those two things.

00:02:42   Like, there is no magic other way to do this.

00:02:45   It's just you have to either do less work, and that will get one side of your power consumption

00:02:51   down, or you need to transmit or receive, you know, less.

00:02:55   Whether that be, you know, the way in which you are gathering, say, like, GPS data.

00:02:59   So that's very relevant for Pedometer Plus Plus.

00:03:01   I've done a lot of work on that.

00:03:03   Or in terms of Pedometer Plus Plus, it's dealing with, like, sending and receiving of light from

00:03:07   the heart, you know, the heart rate sensor on the Apple Watch is a fairly meaningful, you

00:03:13   know, consumer of energy.

00:03:16   And those ones particularly are challenging because they run into sort of physics limits, you know,

00:03:23   in the way that, like, if someone's playing a podcast from a phone speaker, if it's oscillating

00:03:28   air back and forth from the, you know, from the iPhone's speaker, that oscillation is taking

00:03:33   energy.

00:03:33   And there's a certain amount of, there's nothing you can do about that directly.

00:03:37   And so in that case, you're kind of stuck that it's going to use a certain amount of

00:03:40   sound energy to do it.

00:03:42   But there are things we can do on the consumption side.

00:03:45   And I think the process of finding a good fit for this is just, it's a challenging road

00:03:49   because inevitably in this, your job, you know, your app has a job to be done.

00:03:54   And so you need to do that job.

00:03:58   You have to see, like, the easiest way to use no battery is to do nothing.

00:04:01   That's not particularly helpful.

00:04:03   So finding the line between actually doing something useful and not being overly zealous

00:04:07   and, you know, using too much of the user's battery life and then them being frustrated,

00:04:11   you know, because they wanted to listen to a podcast for 10 hours and it ran out of battery

00:04:15   at nine.

00:04:15   Yeah.

00:04:16   I mean, you know, the easiest way to have, you know, impressive battery life for your app

00:04:21   is for people never to launch it.

00:04:22   So, which is great.

00:04:24   Like, you know, yeah, most people who download your app eventually don't launch it anymore

00:04:27   if they ever did.

00:04:28   So, you know, this problem does solve itself, but more seriously, and I think it's important

00:04:33   to recognize too, like, there's a lot of different patterns of usage of apps and, you know, sometimes

00:04:40   and there's also what people expect of, you know, apps and their power consumption.

00:04:46   Those don't always necessarily line up and you have to kind of have reasonable expectations

00:04:51   for what is realistic for your app in terms of power efficiency.

00:04:56   Like, you know, in terms of, you know, if you have, I think some kind of, you know, common

00:05:02   utility app where it doesn't really do anything in the background, there is occasional need

00:05:07   to launch it, interact with it for a relatively brief time, and then close it.

00:05:12   In that kind of scenario, you can do basically whatever you want and it doesn't matter.

00:05:17   Like, it's not, like, unless someone's going to be spending a very long time in your app,

00:05:23   it's probably not going to be possible for it to do meaningful damage to their battery

00:05:27   life, even if you're, like, running all the radios and the GPS and everything.

00:05:31   Like, you know, there's only so much you can do in a minute or two.

00:05:34   But where this becomes more important is, you know, background tasks especially, or if you,

00:05:42   if somebody is in constant interaction with the app.

00:05:45   So, for instance, if, you know, if you have, like, a navigation app, that's probably going

00:05:48   to be on screen for extended times.

00:05:50   Certainly, you're going to be probably using the GPS radio.

00:05:53   And there's all sorts of, you know, in that kind of case, there's all sorts of little, little

00:05:58   tricks you can do to reduce your power consumption.

00:06:01   Like, with GPS, for instance, you can, you can reduce the precision that you need or the update

00:06:05   frequency, core motion and core location.

00:06:08   Like, there's all these different parameters you can set to, to make that, you know, more or

00:06:13   less efficient.

00:06:14   You know, basically, when you're looking at power efficiency, the major areas that matter

00:06:20   a lot are screen brightness, radio and GPS usage, which is a radio technically, but yeah.

00:06:28   So, screen brightness, radio usage, and CPU usage.

00:06:31   Like, that's, and GPU, of course, you know, but so, you know, processor usage.

00:06:34   Those are the major areas that, that matter a lot.

00:06:39   What surprised me about overcast development is that I, I found another area, as you mentioned

00:06:45   a minute ago, that matters a lot, which is speaker usage.

00:06:48   Like, if somebody's using the built-in speaker to push that air, to make that sound, that surprised

00:06:54   me when I learned that that actually was a pretty big power draw.

00:06:56   And the way I learned that was, it was not possible to learn that through any kind of tooling.

00:07:03   There is no instruments simulator or Xcode meter that tells me how much power the speaker

00:07:09   is using.

00:07:10   The way I learned that was, a long time ago, I ran a test.

00:07:13   I was curious to see, like, you know, what, what I was expecting to see was how efficient

00:07:21   or inefficient AirPlay versus Bluetooth would be versus built-in headphones.

00:07:26   Like, that, that was what I expected to find.

00:07:28   And what, and what I expected to find was that using the Wi-Fi radio, which is AirPlay, was

00:07:33   going to be less power efficient or more power hungry than using Bluetooth.

00:07:38   And I expected both of those to be more power hungry than using the built-in headphone jack

00:07:44   to power headphones directly.

00:07:45   And what I found instead was, yeah, those matter.

00:07:48   But if the phone is sitting around beaming stuff wirelessly to something else, that's

00:07:54   actually pretty efficient for audio data.

00:07:57   What I found was that the, the speaker in the phone by far was the largest power drain for

00:08:06   overcast.

00:08:06   Like, if you play out of the built-in speaker, it uses way more battery power than if you are,

00:08:12   you know, sending it to headphones or speakers in any other way.

00:08:16   So that's something that, like, I, there was no way for me to find that other than just

00:08:21   like, all right, set up some tests, like, you know, make a test playlist, you know, play

00:08:26   it from the beginning and just have it just go for hours and hours and hours.

00:08:30   I turned off sync, you know, all that stuff, but like, you know, try to control it as best

00:08:34   as I could.

00:08:35   And it took, you know, like a week or two to run these tests.

00:08:38   And, but eventually, you know, I got my results.

00:08:41   And a lot of times that's just what you have to do.

00:08:43   And like, you know, just like performance testing, a lot of times when you do performance

00:08:50   testing, you know, you're, you're doing the CPU time thing with instruments or whatever.

00:08:53   A lot of times things that you think will be really inefficient are actually fine.

00:09:00   And you're spending a surprising amount of time or something as surprisingly costly that

00:09:05   you wouldn't have guessed would be.

00:09:06   And that exact same pattern holds in my experience for any kind of power and battery testing too.

00:09:13   And there's all sorts of ways that you can, you know, unknowingly waste power.

00:09:18   Like, like one of the common things is if you have some kind of internet connection requiring

00:09:24   operation, say like a background sync.

00:09:27   One of the ways that, one of the common pitfalls for that that I have found is what happens if

00:09:32   the sync fails?

00:09:33   And this can happen, for instance, if the person is like on a, on a subway and they lose their

00:09:38   connection for a few minutes or they're just, you know, they're hiking in the mountains

00:09:41   and they're offline, you know, what happens if the person's offline and some operation

00:09:47   in your app tries to use the connection?

00:09:49   What can happen is that can start going in a loop, just trying to hammer it over and over

00:09:56   and over again, making that request over and over and over again, which can not only make

00:10:01   the radios keep trying to connect, but can also burn CPU power by a lot.

00:10:05   And so there's situations where like you might not even realize like, oh, my app seems really

00:10:11   efficient, but if you're offline, it turns out you like power usage spikes and you might

00:10:16   never know that in your testing unless you're doing offline power testing somehow, which is

00:10:20   not a super common thing.

00:10:21   I don't think people test for, but like there's all sorts of surprises when you do power testing

00:10:26   that you don't realize like, oh, if I, if this weird condition happens, this will infinite

00:10:32   loop or this process will spin forever or it'll, it'll keep trying to do this thing.

00:10:36   So there's all sorts of things like that.

00:10:38   But then you have to contend with, even if you do a really good job of power optimization,

00:10:44   if your app is inherently doing something that requires a lot of power that the user has explicitly

00:10:52   asked you to do, whether that's playing podcasts very loudly out of the built-in speaker or just

00:10:58   using an app constantly with a screen on that happens to use, you know, the network

00:11:02   or GPS, like if, if that's what your app is doing, it's going to use a lot of power and

00:11:07   people, people are going to go into that battery section of their, of their settings and they're

00:11:10   going to see your app on top, even if they were using it that whole time.

00:11:14   So to some degree, this also creates marketing challenges or user support challenges in the

00:11:20   sense that like people, even if people like, you know, spend the energy knowingly with your

00:11:27   app, they will still blame you if it's inefficient, even if there's nothing you can do about it.

00:11:33   So there are, there are a lot of, a lot of, um, you know, sprawling places that, that power

00:11:38   testing and power mindfulness can take you.

00:11:42   Yeah. And I think in that there's this funny aspect of, yeah, like there, there's a fundamental

00:11:48   limit that you run into with power, power efficiency testing. Like at a certain point,

00:11:53   this is at least has been my experience is like, I've done a bunch of things and I think there's

00:11:57   some tools that I've, or strategies I've taken that I think would be useful to discuss, but broadly

00:12:01   it's like there's at a certain, you will inevitably hit this point that this is just like, this is the

00:12:06   floor and you can't go any lower. Um, and that is frustrating insofar as if that number is

00:12:11   too high and you're going to either have to diminish the user experience in terms of do

00:12:16   something different. Like that was ultimately like in the case of Panometer plus plus, what

00:12:20   I found is that if you run, you know, essentially continuous GPS and all of the workout tracking

00:12:26   stuff that you can do on an Apple watch, it is as far as I can tell, not possible to get

00:12:31   the sort of the 20 hour goal that I was trying to get on my Apple watch ultra. Like it was just

00:12:36   not possible that if in the way I determined that is that I built.

00:12:40   A stripped down version of my app that did nothing but those two things using just the

00:12:46   system APIs as basic as I could make it and ran that. And like, so at this point I'm confident

00:12:51   that it's not, you know, Swift UI getting into a funny state and using lots of data or other

00:12:57   background processing or refresh, you know, things. It's like as minimal of an app as I possibly

00:13:02   could. And I ran it. And like, at that point I determined this is the floor. If you do this

00:13:07   and this and this, it is going to take at least this amount of battery to do it. And so like

00:13:11   in my case, I've worked out, well, what if I don't do this? What if I do this? You know,

00:13:15   every, I only get the heart rate every so often rather than, you know, every second, which is

00:13:19   the default. Um, and those kinds of operations are things that you just have to choose because

00:13:23   otherwise that floor is fixed and there's nothing you can do about it in the sense of, you know,

00:13:29   in your case, it's like playing the sound at full volume out of the, out of the speaker.

00:13:32   There is a floor there that is going to be ascribed to you that you can do nothing about.

00:13:37   It doesn't mean there aren't things we can do to still be helpful. And I think that's

00:13:40   the interesting aspect of a lot of this is it's finding the places where there are these pain

00:13:46   points. And particularly it's finding them, yeah, finding the things that will get run,

00:13:49   sort of run away from you. As I think something that very often seemed to be a pattern for what I

00:13:53   was finding, um, in my work and like actually ran into a specific example of what you were,

00:13:57   you were just describing where I had a thing that was loading, you know, loads map tiles.

00:14:02   And typically when the app is set up such that you would download your map tiles ahead of time

00:14:07   so that you have them sort of offline. Um, but if you don't do that and then you go off into the

00:14:12   wilderness, what I would, I discovered is that, um, as soon as you lose connectivity and it tries to

00:14:17   load every time SwiftUI updates the map, it will try load again and try load again and try load again.

00:14:23   And obviously like at some point the system is intelligent about that in terms of if it,

00:14:28   you know, if the, if it has no internet connection, I suspect that those are failing

00:14:33   instantaneously. So it's not like this terrible loop, but it's still a bad loop. And it's in this

00:14:38   exact situation where the user does not want their battery to be running down. And so it's like,

00:14:43   that was something I have to resolve and have to deal with. Um, cause you have to find these situations

00:14:48   where you're going to use lots of battery. And I mean, the reality with this, that is feel,

00:14:52   it feels very like scientific method, but it's this very interesting process you have to do of

00:14:57   designing experiments to isolate particular variables and then running actual like real

00:15:04   world tests. Because there's something about battery testing that is frustrating is that very,

00:15:09   you know, to, to understand your battery consumption over eight hours, you have to do the thing for

00:15:15   eight hours. Um, and this is a situation where I very much envy Overcast being able to just play audio

00:15:21   rather than if you want to test what it's like to track the GPS coordinates of an Apple watch moving

00:15:27   through space, you kind of have to actually move the Apple watch through space for eight hours, which

00:15:32   is, is fine. If you know, you're like me and I'm, I'm training for a long event. And so I very often

00:15:37   have the, you know, the exam, the opportunity to do that, but it is going to be really frustrating

00:15:42   when you're supposed to be going out for like an, you know, an eight hour hike and, you know,

00:15:47   an hour into it, you realize this is a bad build, like something's wrong, something, you know,

00:15:50   something you did isn't right. And just like, well, I guess this test didn't work. And I'm just,

00:15:54   you know, I'm just going to have to try again the next time I go for a long hike. Um, cause you just

00:15:58   have to design these experiments and try things out and be, you know, be experimental, be creative

00:16:03   with it is something too. I think like you were saying is it isn't always going to be the thing that

00:16:07   you think. And so to some degree, you have to isolate different variables, experiment and test

00:16:13   them separately, and then make sure that you're trying to be holistic in that approach of understanding

00:16:18   that it isn't necessarily the obvious thing that is going to be the most power consumptive.

00:16:22   Sometimes it's going to be other things. And so, you know, you'll turn things off, um, incrementally

00:16:28   or, or experimentally and try and isolate like this variable seems to be where things are, you know,

00:16:34   where things are getting stuck or where there's extra power consumption, where maybe there doesn't

00:16:38   need to be, or if it's above what you, you know, what, what it seems to be. And so that's kind of

00:16:43   what we end up having to do, or at least as far as I can tell, that's what you're going to do. And

00:16:47   there's no easy way around it because you can, in order to really know the real life results,

00:16:52   you have to actually go out into the real world. Like I love the simulator for testing my core location

00:16:57   stuff. And I've all, you know, this, there's, we've talked about SimGenie before, which is a great tool

00:17:01   for being able to, you know, reproduce GPS tracks in the simulator. So you can actually test your like

00:17:08   logic for that. And that's useful to some degree in terms of I've done a lot of work, you know,

00:17:12   that improves my battery life by making my algorithms more efficient, which I can do in

00:17:16   the simulator. But ultimately at some point you're going to have to lace up your shoes, get out and

00:17:21   actually test it in the field or try it in the situations where it's going to be used. Because if

00:17:25   you don't, you won't actually know what the battery life will be used in practice.

00:17:29   Yeah, exactly. And that's, that's the answer to so many of these things. Like a lot of times it just

00:17:34   depends because battery life, you know, with, with the big users of it, like the screen brightness,

00:17:39   the speaker, you know, the usage of GPS, like those are, those are big users of it. Those it's kind of

00:17:48   obvious when, you know, like, okay, using the radios is power inefficient. Well, if you can like use them

00:17:56   less frequently, maybe batch your requests, they don't have to like constantly wake up, you know,

00:18:00   connect to whatever, and then go back to sleep. Like that, that, that's kind of more obvious.

00:18:04   Sometimes when you're dealing with optimization of processor usage or, you know, like load on the

00:18:11   processor, sometimes it's less obvious what will matter and what won't because the processors are

00:18:18   really complicated. And this is partially true of the radios too. The radios are also very complicated,

00:18:23   but the processors, I think more than anything, this is where you have to often just try stuff and you

00:18:29   can't rely on the little meter and Xcode that says power use, you know, power impact low, you know,

00:18:34   like that's, that's a very coarse mechanic because the reality is the processors, oftentimes they're

00:18:41   doing such complicated things. They're, they're managing their power. So in such a complex way,

00:18:46   they're, they're splitting tasks between the efficiency cores and the performance cores, you know,

00:18:51   they're, they're ramping up the clock speed and then ramping it back down, like, you know,

00:18:55   many times per second, like, you know, like they're, they're doing these things that sometimes

00:18:59   what you think will be inefficient or efficient won't be. Um, because sometimes they can, you know,

00:19:06   like for instance, if you have a certain amount of computation to, to do, and it doesn't really

00:19:11   matter when you do it, you might think, let me do a little bit at a time. So the CPU is only like,

00:19:15   you know, 5% used for a long time. Well, that actually might be less efficient than using a hundred

00:19:23   percent of a core for five seconds and then stopping or whatever, because that can actually

00:19:28   like the, some core might have to stay awake longer than it would if it's doing a long running small

00:19:35   task, as opposed to being able to do a big burst of work and then go to sleep for a longer time after

00:19:41   that. Um, the, this, this, um, pattern is called race to sleep. And the idea is oftentimes it is more

00:19:47   efficient with modern, uh, processors often is more efficient to just do the work really fast

00:19:53   at maximum power and then stop and then, you know, sleep for as long as you possibly can before you

00:19:58   ask it to do more. Um, and sometimes the opposite is true depending on whether that task, you know,

00:20:04   can run on an efficiency core or not. So, you know, as you were saying, Dave, like there is really no

00:20:08   better answer than you got to just test this stuff and be, you know, be willing to experiment.

00:20:13   And again, to many apps, this won't even be necessary to many apps. You know, if people are just

00:20:19   launching it briefly, no problem, like do whatever you want. But once you have

00:20:22   something long running, if it's some kind of, you know, background thing or, or, you know, long

00:20:27   foreground usage, this is going to start to matter a lot. And people, people are going to notice like,

00:20:33   Hey, does my phone get hot while I use this app? Or does my battery sync dramatically? Like that,

00:20:38   that does matter to people a lot.

00:20:40   Yeah. And if, and if you'll allow me a brief rant, I'm very frustrated by how the tooling we have

00:20:48   for this is because ultimately, like I said, we have to just do these tests. And I feel like it is,

00:20:53   it feels very frustrating in like whatever the 18th year of iOS's existence. That's so often I'm falling

00:21:00   back to like in the console, logging the battery percent as reported by the system as the best tool

00:21:07   I have for a lot of these things. And as a side rant, it is very frustrating that debug builds,

00:21:13   you know, I'm clearly a developer doing this thing. We'll still have the masked battery percentage

00:21:19   reported to it, which is like, where it like rounds to the nearest 5%.

00:21:22   Oh yeah.

00:21:23   Which is like, why are you doing that to me? Like that, that's, that's unnecessary. I understand it

00:21:27   makes sense in, you know, for fingerprinting reasons and things in like production apps, but come on,

00:21:31   I wish that would just give me the actual number so that I don't need to run things for like twice as long

00:21:36   to make sure that I'm averaging out the weird sort of rounding issues and errors there. But

00:21:41   nevertheless, it's something that I was just really surprised by when I went and wanted to do

00:21:45   like power analysis and these kinds of things. Like I expected there to be like a really detailed

00:21:50   instrument in Xcode that would give me a lot of the detail that, that I might want. And as far as I

00:21:56   could tell, there's some very basic things and some of them have sort of come and gone over the years.

00:22:01   Some, like sometimes you, I find these articles about tools which don't seem to exist in Xcode

00:22:05   anymore. But like, ultimately I kind of get a lot of t-shirt sizing with the power consumption

00:22:10   is the best you can do where it's like, you're doing small, medium, or large amounts of battery

00:22:16   use right now, which is like, okay, but if I'm trying to optimize things more specifically, it'd be

00:22:22   really helpful if there was some amount of more like, you're using so many, whatever, like, you know,

00:22:27   milliwatt hours or milliwatts per hour, whatever, like some measurement that I could actually be basing

00:22:32   something on or things like that. And I understand obviously measurement always has overhead. And so

00:22:38   that's, maybe that's why some of these things don't, aren't in there, but like in a lot of circumstances,

00:22:42   I wish I could take on that overhead and understand obviously it's doing a lot of extra work. So the percent,

00:22:47   you know, the battery percent would no longer be representative, but the measurement of what my app

00:22:52   was doing or what the overall system power draw is could be consistent between runs or those kinds of things.

00:22:58   And it was just a very, it was something that really surprised me where I feel like a lot of like instruments is

00:23:03   amazing and continues to get better every year, it seems, but power when battery life particularly just didn't seem like

00:23:10   something that there was nearly as much detail and ability for us to dig into. And particularly if you're doing

00:23:17   anything with watchOS, like it was shocking to me how challenging it was to, because even some of these like t-shirt sized

00:23:25   power usage things don't seem to apply on watchOS. And so on what I ended up doing for a bunch of my apps, like I was

00:23:31   saying, I was like combining, stripping these things down to their smallest parts. And sometimes I would just run the

00:23:37   library that I had written on my iPhone and see how it works there where I could actually get some bit more data there and run and have a

00:23:44   slightly faster sort of testing cycle there. And obviously the iPhone is not an Apple Watch, but it is

00:23:50   close and, you know, things that are bad on the iPhone are likely also going to be bad on watchOS. And so I was able to

00:23:56   catch some issues that way. But it was just one of these things that I was very surprised by. And maybe it is to your

00:24:00   point that a lot of, there's certain kinds of apps that just don't need to worry about power consumption

00:24:07   dramatically that, I mean, in a way that like Widgetsmith, you know, is an app that I don't think I've ever really

00:24:11   paid much attention to its battery consumption. Because it's an app that users tend to open,

00:24:17   do an operation for a short period of time, and then close the app, and that's it. And so it's very

00:24:23   unlikely Widgetsmith's ever going to show up, you know, in a very heavy, heavy way in a user's

00:24:27   battery meter. But in the places that I do use it, boy, do I wish there was some kind of way that I could

00:24:33   have a better insight into it. I mean, it reminds me of those things you'll see in like when you're playing,

00:24:37   you know, people are playing video games, and they have like a little HUD that has the current,

00:24:40   you know, frames per second and details about the rendering. It's like, boy, do I wish I could just

00:24:45   have a little HUD on the top of the screen that was telling me the current pain of power consumption as

00:24:48   it's being drawn from the battery or something. Like that would have made my life so much easier and

00:24:52   saved me so much time in this process.

00:24:54   You know what you should do? You should scale it up to be able to run on a Mac Mini,

00:24:57   spin up like, you know, a hundred of those processes and just put a kilowatt meter between

00:25:01   the Mac Mini and the wall, and you can see how much power it's pulling.

00:25:05   Just take the battery completely out of this, out of the loop, and just do it purely by the amount

00:25:11   of power draw that is happening on the computer. There you go. Problem solved. I don't know why I

00:25:15   didn't think of that.

00:25:18   One other thing I wanted to mention is programmatically adapting to low power mode. So this

00:25:24   is one thing you can do on the process info object. There's an is low power mode enabled property,

00:25:29   and there's some notifications there when it changes to if you want to monitor it that way.

00:25:32   This is one of those things that I thought was a great idea. And so I tried it. And it turns out,

00:25:40   so my thinking was, how about when the device is in low power mode for overcast, maybe I do things

00:25:47   like, you know, reduce the frame rate of animations that I'm generating manually, like those waveform

00:25:52   animations I had, like in the pause button. Maybe I reduce the frame rate of that. Maybe, you know,

00:25:57   more importantly, maybe I will reduce the frequency at which I sync back to the server. Or maybe I would

00:26:04   defer tasks like downloading, you know, like checking for artwork changes for podcasts and downloading new

00:26:09   artwork. Maybe I, you know, defer those until it's not in low power mode. And that was a great,

00:26:13   those were all great ideas. And they all failed. Except for the animation frame or anything. I think

00:26:18   I actually kept that one. But everything else I had to abandon, because the reality is many users out

00:26:26   there basically use low power mode all the time. It's a very, very common usage pattern that people just

00:26:33   like every day they just pick up their phone and flip on low power mode. And so you can't, you shouldn't

00:26:40   change anything in low power mode that would negatively affect your app if that was always the condition under

00:26:47   which it was running. So for instance, I was like, I was deferring artwork updates when I, this was years

00:26:52   ago now. But you know, I had this idea, I'll defer artwork updates. And I was getting complaints from

00:26:57   people saying, I like, but I have the wrong art for this podcast. And I like, I would have, I would

00:27:03   occasionally begin with some of them. And oftentimes it was, I would get to this question, and they were

00:27:07   actually running low power mode all the time. And so it was just never having a chance to update.

00:27:11   And so this is something that you can, you can do, and you know, you can make minor tweaks to what your

00:27:17   app is doing in response to low power mode. But I would not recommend making major tweaks. Because

00:27:23   and even if you tell the user, maybe if you have a banner up saying, you know, sync deferred because

00:27:27   of low power mode or whatever, like, that's not going to solve your problem. Because that's not going to

00:27:30   make people, you know, change their power using their phone. That's just going to make them, you know,

00:27:34   not use your app or complain about it. So be careful what you change in response to that. And make sure

00:27:41   it's something that the ramifications aren't too bad if you are never running in regular mode.

00:27:47   Yeah, and I think, so I ran into a similar sort of pattern then in the end of this update I'm

00:27:52   working on, where I was thinking, oh, if the user's in low power mode on their watch, like I should

00:27:57   do different things. And I think what I ended up settling on is that for the same reasons you're

00:28:01   describing, I think it would be better. And this is sort of where I'm going is there's a mode inside of

00:28:06   the app that does different things. And is the sort of the expedition mode,

00:28:11   the long run, you know, long, long walk kind of mode that the user is specifically opting into,

00:28:18   rather than responding to the system flag, which can be on for a variety of reasons.

00:28:22   It's the something that the user is saying, hey, I want to maximize my battery life,

00:28:29   I want to turn this on. And they're making a positive choice to do that, rather than assuming

00:28:34   that the reason they have low power mode on is because they want those low power features. They

00:28:39   may want all of the capability, but, you know, just are turning that on out of habit or out of sort of

00:28:46   other, other reasons or other needs. And so, or similar, like I think of in watchOS, there's some

00:28:50   switch, you know, some switches that you have to go and turn on if you want to enhance the battery life

00:28:55   in low power mode. Like it takes, can take fewer GPS readings or heart rate readings in the main

00:29:01   workouts app, but you have to go and turn that on rather than the system just assuming, oh, you're in

00:29:05   low power mode. I'm going to do that for you because you just don't want to make assumptions. And you

00:29:09   don't ultimately in all of this battery life is a tension between user experience and capability

00:29:14   and power. And like, you just, there's a certain trade-off that you have to make there and be careful

00:29:19   about making assumptions about that is exactly right. Like you don't want to assume that the situation

00:29:23   is any one state, whether that's low power mode here, whether that's, you know, network

00:29:29   connectivity, whether it's screen brightness, volume on the speaker, all of these things are just these

00:29:33   variables we're trying to balance between. And if we can get the balance right, we can improve the overall

00:29:38   battery, you know, user experience by giving a user more time with our app, which is ultimately

00:29:43   wonderful, but we just have to be thoughtful and careful, you know, to arrive at that place in a way that

00:29:47   makes everybody happy.

00:29:48   Thanks for listening, everybody. And we'll talk to you in two weeks.

00:29:52   Bye.