PodSearch

Under the Radar

67: Dealing with Old Code

 

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

00:00:03 ◼   ► I'm Mark Orment.

00:00:04 ◼   ► >> And I'm David Smith.

00:00:06 ◼   ► Under the Radar is never longer than 30 minutes, so let's get started.

00:00:10 ◼   ► So today we are going to be talking about old code.

00:00:15 ◼   ► And the idea for today's discussion got started from some work I've been doing recently,

00:00:20 ◼   ► updating and fixing some issues in one of my apps.

00:00:23 ◼   ► It was actually the first app that I had that ever really was in any reasonable way a success.

00:00:28 ◼   ► It's an app called Audiobooks that lets you listen to public domain audiobook recordings.

00:00:34 ◼   ► And I launched it in spring of 2009.

00:00:39 ◼   ► So it's coming up on its eighth birthday today.

00:00:44 ◼   ► And it's kind of a wild thing to be going through and working -- I'm still actively

00:00:50 ◼   ► working on it for the last eight years.

00:00:52 ◼   ► I've had continuous updates, and it launched at a time when there was one screen size.

00:00:58 ◼   ► And that screen size was non-retina.

00:00:59 ◼   ► We were doing retain and release.

00:01:03 ◼   ► All of the buttons are super shiny.

00:01:05 ◼   ► They have that really round kind of capsule look to them.

00:01:10 ◼   ► And it even has some features that I look at now, and it took me a while to remember

00:01:14 ◼   ► why I added them.

00:01:16 ◼   ► For example, it has a feature where you can automatically resume playback of the audio

00:01:21 ◼   ► when the app starts up.

00:01:23 ◼   ► And that's because the app was created before multitasking was a thing, where when you close

00:01:28 ◼   ► the app, it would stop playing.

00:01:31 ◼   ► And so I made it so that as soon as you start it back up, you could resume to make it a

00:01:37 ◼   ► little bit easier for that.

00:01:38 ◼   ► But the app is so old that it has all of these code paths and these details.

00:01:45 ◼   ► There's sections of the code where it says, "Is multitasking supported?

00:01:49 ◼   ► Do this.

00:01:50 ◼   ► If not, do that."

00:01:51 ◼   ► And multitasking has been available since iOS 4.

00:01:54 ◼   ► >> Enoch: And if I'm doing my timeline correctly, it looks like you launched this when the current

00:01:58 ◼   ► version of iOS was still 2.0.

00:02:00 ◼   ► >>

00:02:23 ◼   ► The thing that's been making me think about, though, is I'm doing this process of doing

00:02:41 ◼   ► this big spring cleaning for this app.

00:02:44 ◼   ► And it creates all these weird questions, though, like how to deal with all this old

00:02:49 ◼   ► code, all this old stuff, and there's all this legacy weight that goes into this app.

00:02:54 ◼   ► And it's theoretically possible that there's a customer out there who has been using the

00:03:00 ◼   ► app since 2009 continuously.

00:03:04 ◼   ► And so there's all these interesting cases and details that I have to manage and deal

00:03:08 ◼   ► with because, for example, they may have had data in their database that is from the original

00:03:16 ◼   ► version, and I have a whole bunch of code in my app to translate old versions of, you

00:03:22 ◼   ► know, I think I've gone through three or four database formats or things.

00:03:25 ◼   ► Like originally I launched and the database was a plist, I think.

00:03:31 ◼   ► >> When you launched, core data was not yet on the phone.

00:03:34 ◼   ► You could do raw SQLite through the C API, but most people just had these weird little

00:03:39 ◼   ► hacks like plists or very, very basic SQLite functionality because it was so cumbersome.

00:03:46 ◼   ► >> Yeah, exactly.

00:03:48 ◼   ► It was a plist to start with, and then I transitioned to core data, and then core data has gone

00:03:53 ◼   ► through several migrations.

00:03:54 ◼   ► And so it's a lot of these weird, complicated issues that I feel like you don't -- when

00:04:01 ◼   ► I'm building things now, I don't really think about this kind of future-proofing and migration

00:04:04 ◼   ► and translation and the things that I may need to do if the app is sitting around.

00:04:09 ◼   ► I don't know if you think about this when you're doing overcast stuff, that like what's

00:04:13 ◼   ► going to happen if someone who's been running the old version for years and years and then

00:04:20 ◼   ► suddenly installs the new version?

00:04:21 ◼   ► It could have a totally different database scheme.

00:04:23 ◼   ► It could have a totally different file format.

00:04:26 ◼   ► All the MP3s could be in a different place.

00:04:29 ◼   ► Time is a weird thing with software, I think.

00:04:32 ◼   ► >> Yeah, I mean, I've avoided many of the -- I mean, first of all, my migrations for

00:04:37 ◼   ► the database are all fairly straightforward.

00:04:40 ◼   ► I do have a lot of that code that can support old versions.

00:04:43 ◼   ► However, in practice, I don't have a lot of people using old versions because from day

00:04:47 ◼   ► one I decided to use SSL certificate pinning on my connection to my API.

00:04:52 ◼   ► And this has caused -- it's a nice thing for security.

00:04:56 ◼   ► However, at various points I've tried pinning two various things.

00:05:00 ◼   ► First I pinned to the certificate itself, which only lasted until that SSL certificate

00:05:05 ◼   ► expired, which was about a year.

00:05:08 ◼   ► And then I realized, well, it's kind of inconvenient to break all the old versions of my app every

00:05:11 ◼   ► time I have to update my SSL certificate on my server.

00:05:15 ◼   ► So I tried pinning to the intermediate certificate through my SSL issuer, figuring, well, that

00:05:19 ◼   ► won't change for a long time until it expires in like five years.

00:05:23 ◼   ► And then all the encryption standards got upgraded to, I think, SHA-256 or somehow they

00:05:29 ◼   ► changed the signature algorithms to be more secure on all certificates.

00:05:32 ◼   ► And so that broke.

00:05:33 ◼   ► And so I had that force an upgrade.

00:05:35 ◼   ► And then on my most recent one, just a few weeks ago, I updated my certificate.

00:05:41 ◼   ► And I'm like, oh, I'll be fine.

00:05:42 ◼   ► I'm pinned to the new SHA-256 intermediate certificate.

00:05:45 ◼   ► I can update and it'll be fine.

00:05:47 ◼   ► But then the new certificate I got just was signed with a different intermediate key.

00:05:52 ◼   ► Like for whatever reason, like, OK, that's not good.

00:05:57 ◼   ► So I had to forcibly break all previous clients who connect.

00:06:01 ◼   ► And I gave like a month notice and I let it go for a while.

00:06:05 ◼   ► But then like the actual expiration date on the old certificate was actually as we record

00:06:11 ◼   ► yesterday.

00:06:12 ◼   ► And so I was forced to break all compatibility with all old versions yesterday, basically.

00:06:21 ◼   ► So I don't really have that problem as much.

00:06:25 ◼   ► And this kind of gives me a lot of advantages.

00:06:27 ◼   ► I mean, one advantage is that I don't have to really worry about supporting old versions

00:06:31 ◼   ► of the OS very much.

00:06:32 ◼   ► It's like, well, even though it's inconvenient that I had to force all these people to update

00:06:36 ◼   ► the latest version, that also means that I literally have zero people using anything

00:06:41 ◼   ► older than it.

00:06:43 ◼   ► So it simplifies a lot of this stuff.

00:06:47 ◼   ► And I've found that usually people who are running very, very, very old versions of things,

00:06:53 ◼   ► they kind of expect things to break if they ever update them.

00:06:56 ◼   ► That's one of the reasons that they aren't updating them, because either they can't or

00:06:59 ◼   ► they won't.

00:07:00 ◼   ► And the reasons why they can't or won't are usually because either their hardware doesn't

00:07:03 ◼   ► support anything new, or in which case you're fine, because any new installation will be

00:07:07 ◼   ► on new hardware.

00:07:08 ◼   ► Or that they refuse to update for whatever reason.

00:07:12 ◼   ► Maybe they just don't like the new OS.

00:07:13 ◼   ► Maybe they think it'll run too slowly on their hardware.

00:07:15 ◼   ► Maybe they have a jailbreak they want to preserve.

00:07:16 ◼   ► Whatever the case is, they refuse to update.

00:07:19 ◼   ► In which case, I feel like if you are refusing to update to something that you could update

00:07:23 ◼   ► to, I kind of feel like you're taking matters into your own hands and accepting the responsibility

00:07:27 ◼   ► of things might be weird for you holding onto old stuff.

00:07:31 ◼   ► And one of the ways things might be weird is you might have some kind of failed migration

00:07:35 ◼   ► in the future when you do decide to upgrade, when you're upgrading way after everyone else

00:07:39 ◼   ► has.

00:07:40 ◼   ► So for the most part, the issue of migrating old data over time and everything is, I think,

00:07:47 ◼   ► not that big of a deal in practice.

00:07:49 ◼   ► You should do it as much as you can.

00:07:51 ◼   ► You should accommodate that, but not to the point where it's going to become a large burden

00:07:55 ◼   ► on you while you should be supporting new customers, basically.

00:07:59 ◼   ► >>

00:07:59 ◼   ► Yeah.

00:08:00 ◼   ► And I think it certainly is complicated, especially for apps that, like Overcast, it requires the

00:08:06 ◼   ► server for it to function, period.

00:08:09 ◼   ► And so it doesn't have the sense of an offline or a standalone kind of feeling.

00:08:15 ◼   ► Where this app, my audiobooks app, it still works.

00:08:19 ◼   ► I actually, out of curiosity yesterday, I exported version one out of my Git repository

00:08:26 ◼   ► and got it to run in the most recent version of Xcode, which surprisingly worked surprisingly

00:08:33 ◼   ► well given how much time has passed between those things.

00:08:37 ◼   ► >> That's kind of impressive.

00:08:38 ◼   ► >> I only had to fix a few bugs and set the root view controller on the window and a few

00:08:43 ◼   ► things that otherwise it just wouldn't launch.

00:08:45 ◼   ► But overall, it ran.

00:08:47 ◼   ► And the app still works because it was built at a time when it needed to be standalone

00:08:55 ◼   ► because network connections were super flaky and everyone was on edge or 3G at the time.

00:09:01 ◼   ► And it was a very different paradigm.

00:09:03 ◼   ► So the app was very standalone.

00:09:05 ◼   ► And I think any app that has that kind of standalone-ness to it is where it really gets

00:09:09 ◼   ► complicated for these kinds of data formats and migration kind of stuff.

00:09:15 ◼   ► What I'm struggling with now as I go through this is the issue you run into is you end

00:09:20 ◼   ► up with this kind of Russian doll data format where I have code in the app that lets me

00:09:29 ◼   ► migrate -- every little migration or thing that I've done over time, I have code to manage

00:09:36 ◼   ► from one to the next to the next to the next.

00:09:38 ◼   ► And so there is a path that if I took something that was running that very first version,

00:09:44 ◼   ► I think there's -- maybe not that very first one, but definitely the core data versions.

00:09:49 ◼   ► Theoretically, if you had a device that was running that and then you reinstall the latest

00:09:53 ◼   ► version, it would go through six different migrations.

00:09:57 ◼   ► It would migrate this format change, then this format change, then this format change.

00:10:02 ◼   ► And it's a really tricky thing, though, for me as I'm going through this code.

00:10:07 ◼   ► I have no idea if this works still.

00:10:10 ◼   ► But it's still there in the code that if you were running database version 2, that

00:10:14 ◼   ► I have this code that says if you're 2, I can get you to 3, and then there's code from

00:10:17 ◼   ► like 3 to 4.

00:10:19 ◼   ► But that sounds horribly error-prone and unlikely to actually work in practice.

00:10:24 ◼   ► And so what I'm trying to go through now is should I just be deleting some of these old

00:10:28 ◼   ► code paths?

00:10:29 ◼   ► Should I just be going through and saying I'm supporting migration from whatever the

00:10:34 ◼   ► last major version to the current version and then cutting it off there?

00:10:39 ◼   ► Because it's a really -- theoretically, if I'm having this code in there that's doing

00:10:43 ◼   ► something, I should probably be able to -- I should probably have a way to reliably ensure

00:10:49 ◼   ► that it works.

00:10:51 ◼   ► And I don't know if that's actually a guarantee that I want to make.

00:10:55 ◼   ► >> Yeah, I mean, like, you know, on one hand, you could just do what you just did and check

00:10:59 ◼   ► out version 1.0 out of Git and build it and put some data in there and then check out

00:11:04 ◼   ► the current head version and run it and see if everything gets migrated over.

00:11:08 ◼   ► But again, I think as indie developers, there's so much stuff where like, well, it would be

00:11:14 ◼   ► nice if we had the time to do X, Y, or Z.

00:11:16 ◼   ► Or it would be nice if we had enough staff and resources to do X, Y, or Z.

00:11:20 ◼   ► But in reality, you have to prioritize.

00:11:22 ◼   ► And it is probably not worth a lot of effort to maintain these code paths that are going

00:11:30 ◼   ► to support somewhere between like 0 and 10 people ever.

00:11:35 ◼   ► You know, like it's not like a huge deal.

00:11:37 ◼   ► So basically, like the way I come down on it is, you know, what I said earlier, it's

00:11:41 ◼   ► like if it's going to be really easy to keep the support in, like if you have a couple

00:11:46 ◼   ► of instructions to migrate databases forward, like I don't see the value in deleting them

00:11:51 ◼   ► necessarily because, you know, that isn't that much code and it's not really hurting

00:11:55 ◼   ► anything to be there.

00:11:56 ◼   ► But I, you know, but if it becomes a burden, if for whatever reason that is causing you

00:12:01 ◼   ► to not be able to upgrade to something else or clean up something else or not be able

00:12:07 ◼   ► to change the app in a way that would benefit all current and new customers, then I think,

00:12:14 ◼   ► you know, then the cost is too great to having those and then you should get rid of them.

00:12:17 ◼   ► But I also don't think it's going to be worth your time to routinely check out version

00:12:23 ◼   ► 1.0 and get some data and then check out the head.

00:12:27 ◼   ► To test these migrations that far back where you might literally be the only person who's

00:12:32 ◼   ► ever doing that, then it's probably not worth the time taken away from doing things

00:12:38 ◼   ► that benefit everybody.

00:12:39 ◼   ► Yeah, and I mean I think in a similar way I've been also working through some of these

00:12:43 ◼   ► thoughts about dealing with like just old device styles and types too.

00:12:49 ◼   ► Like for example, I still have all non-retina assets in the app.

00:12:55 ◼   ► Oh, geez.

00:12:56 ◼   ► Which is a funny thing because on the iPad, does iOS 10 have a non-retina iPad that it

00:13:03 ◼   ► still supports?

00:13:04 ◼   ► No, because even the iPad 3 it got dropped.

00:13:07 ◼   ► But it is, I think 9 still supported iPad 2 and 3 I think.

00:13:12 ◼   ► Yeah, and so it is funny when I have all these resources, especially if they're iPhone only,

00:13:17 ◼   ► like these are resources that can never be seen.

00:13:21 ◼   ► And so I'm going through and being like, "Should I clear this up?

00:13:24 ◼   ► It'll make my bundle a little bit smaller to just have 2x and 3x assets."

00:13:30 ◼   ► And I mean on the iPad it's especially interesting because for me and my use, something like

00:13:36 ◼   ► 45% of the iPad users who use audiobooks are doing it on a device that doesn't support

00:13:42 ◼   ► iOS 10.

00:13:43 ◼   ► Wow.

00:13:44 ◼   ► Like mostly the iPad 2 and the iPad mini.

00:13:47 ◼   ► That's a lot.

00:13:49 ◼   ► Yeah, which makes up, I mean I imagine it's the nature of the, I mean the app's just been

00:13:53 ◼   ► around for a long time and that's active use too.

00:13:56 ◼   ► It's not just like total install.

00:13:58 ◼   ► Because I can imagine it's a lot of people who have an iPad that they just load audiobooks

00:14:02 ◼   ► on and listen to in their kitchen or on their bedside when they're going to bed or something

00:14:10 ◼   ► like that.

00:14:11 ◼   ► It seems like it's that kind of a device.

00:14:12 ◼   ► And so it's tricky when I have these devices that, I think right now I support iOS 8, 9,

00:14:20 ◼   ► and 10, or is my official support, and with this update I'll probably be going to 9 and

00:14:25 ◼   ► 10.

00:14:26 ◼   ► But one thing that I've definitely run into a few times is dealing with these, is the

00:14:30 ◼   ► issue of a device that just can't get the latest version of the app, period.

00:14:35 ◼   ► And I think this is, with the iPads especially, this is going to be more notable than it is

00:14:41 ◼   ► for iPhones.

00:14:42 ◼   ► Because I just think iPhones don't stick around as long.

00:14:45 ◼   ► Like there's very few people using an iPhone 4 or an iPhone 3GS these days.

00:14:51 ◼   ► And so it's something that I worry about less.

00:14:54 ◼   ► Though I will say one little trick that I always do, I've started doing in all my apps

00:14:59 ◼   ► just like for, it's saved me so many times, is I always enable the iTunes file sharing

00:15:08 ◼   ► setting in most of my apps.

00:15:12 ◼   ► And it's mostly because it's like, I came into it most usefully for my recipe app, where

00:15:18 ◼   ► it has people store their recipes and the images and all these associated assets for

00:15:26 ◼   ► the recipe collection.

00:15:27 ◼   ► And it's nice to have a method that if someone emails me and says, I get this a lot, is I

00:15:32 ◼   ► have a first gen iPad, like my recipe book launched day one, or pretty soon after that,

00:15:38 ◼   ► of the original iPad.

00:15:39 ◼   ► And there are people who've been using it just like they take that iPad, they put it

00:15:42 ◼   ► in their kitchen, and they never changed it.

00:15:43 ◼   ► And they've been using it ever since.

00:15:46 ◼   ► And that version of the iPad is so unsupported by iOS versions, by versions of the app, that

00:15:54 ◼   ► it was really awkward to be like, well, there's not much that I can do to help you.

00:16:00 ◼   ► And so what I ended up saying is I enabled that iTunes file sharing.

00:16:03 ◼   ► And then at least what I can say to these people is, hook it up to iTunes, grab these

00:16:07 ◼   ► files, put them on your desktop, drag them back onto your new iPad, because usually that's

00:16:11 ◼   ► the situation they find themselves in.

00:16:13 ◼   ► It's like, I got a new iPad, yay, but what do I do?

00:16:15 ◼   ► And it's like they can then, at the very least, take those database files and move them back

00:16:19 ◼   ► and forth.

00:16:20 ◼   ► And then, like I was just saying, I have all the Russian doll migration scripting so that

00:16:25 ◼   ► it can take those first early versions of the app and make them move forward.

00:16:30 ◼   ► But if I hadn't enabled the iTunes file sharing API back then, they would just be stuck.

00:16:37 ◼   ► There'd be no way to get those files realistically out of the device.

00:16:40 ◼   ► They'd have to use some kind of iPhone Explorer specific tool.

00:16:45 ◼   ► Download Phone View.

00:16:46 ◼   ► Yeah, download Phone View and migrate, which is never going to happen.

00:16:49 ◼   ► But at least iTunes.

00:16:50 ◼   ► I think if step one of your troubleshooting is download Phone View, you're probably not

00:16:55 ◼   ► going to be successful with that.

00:16:58 ◼   ► So at least that is a little hint that I now just do it out of course, because I think

00:17:02 ◼   ► most people don't know it's there, and so it's unlikely to be dangerous.

00:17:07 ◼   ► Somehow people are going to be like, oh, what can I do with these files?

00:17:09 ◼   ► And start randomly deleting their databases.

00:17:12 ◼   ► But every now and then, it really comes in handy for somebody who's like, how do I move

00:17:17 ◼   ► my files from this phone to this phone?

00:17:20 ◼   ► Or it's even the common one that I get now with like, in pedometer, people are like,

00:17:24 ◼   ► I have all my steps on this device, and I don't want to do backup and restore, or it's

00:17:29 ◼   ► too old to do backup and restore because the versions are incompatible.

00:17:32 ◼   ► What can I do?

00:17:33 ◼   ► And it's like, well, go to iTunes.

00:17:35 ◼   ► It's awkward, but you just write out a big customer support guide that says click here,

00:17:41 ◼   ► click here, click here, and then it works well enough.

00:17:44 ◼   ► All right, we are sponsored this week by Linode.

00:17:47 ◼   ► Linode servers offer industry-leading performance with native SSD storage, Intel E5 Xeons, and

00:17:54 ◼   ► access to a 40-gigabit network.

00:17:56 ◼   ► They have nine data centers spread across the world, which give you the ability to serve

00:17:59 ◼   ► your customers quickly.

00:18:01 ◼   ► And Linode's API allows you to easily automate tasks or develop custom applications in the

00:18:05 ◼   ► cloud with super simple scaling.

00:18:08 ◼   ► This allows you to resize your servers in just a couple of clicks.

00:18:10 ◼   ► I've done this myself many times.

00:18:11 ◼   ► It's been awesome.

00:18:12 ◼   ► In fact, I'm actually doing one later today.

00:18:13 ◼   ► I'm running out of disk space on my backup server.

00:18:15 ◼   ► I'm going to just go and resize it later today.

00:18:16 ◼   ► It's going to take about 10 minutes, most of which I'm just waiting for it to complete,

00:18:19 ◼   ► and it's going to be great.

00:18:20 ◼   ► I've done it so many times.

00:18:21 ◼   ► I know exactly how it's going to go, and man, I love Linode.

00:18:24 ◼   ► And all of this is also manageable if you want via the command line through their API

00:18:27 ◼   ► as well, if you don't want to use their interface or if you want to automate large tasks.

00:18:31 ◼   ► All of Linode's pricing tiers feature hourly billing with monthly caps on all plans and

00:18:35 ◼   ► add-on services like backups and node balancers.

00:18:39 ◼   ► So Linode, they also have some awesome new pricing options.

00:18:42 ◼   ► You can now get a server with one gig of RAM for just five bucks a month.

00:18:48 ◼   ► I can't believe how cheap servers are.

00:18:51 ◼   ► This makes me so happy because servers used to be so expensive.

00:18:54 ◼   ► And when I was starting out, the idea of five bucks a month for a server with a gig of RAM,

00:18:59 ◼   ► oh my god, I paid so much more for so much less back then, and you can go all the way

00:19:02 ◼   ► up to 16 gigs of RAM for only 60 bucks a month.

00:19:06 ◼   ► Oh man, their prices are good.

00:19:09 ◼   ► And their two gig plan now includes 30 gigs of storage, and that's just 10 bucks a month

00:19:14 ◼   ► for two gigs of RAM, 30 gigs of SSD storage.

00:19:17 ◼   ► Linode continues to offer more and more awesome options to meet your server needs.

00:19:21 ◼   ► Across the board, they're offering twice the amount of RAM that you get elsewhere.

00:19:25 ◼   ► As listener of this show, if you sign up at linode.com/radar, you'll not only be supporting

00:19:30 ◼   ► us but you'll also get $20 towards any Linode plan, and with a seven-day money-back guarantee,

00:19:35 ◼   ► there's nothing to lose.

00:19:36 ◼   ► So go to linode.com/radar to learn more, sign up and take advantage of that $20 credit or

00:19:41 ◼   ► use the promo code radar2017, that's radar2017, just like the year, I hope, at checkout.

00:19:48 ◼   ► Thank you so much to Linode for supporting this show.

00:19:50 ◼   ► All right, and the next area that I've been recently battling through with the same app

00:19:56 ◼   ► that I think is interesting to talk about is the concept of iOS deprecation.

00:20:03 ◼   ► So the app when I launched it, when I started this project, came up, I think there was something

00:20:08 ◼   ► on the order of 80 deprecation warnings, which is certainly an indication of my, I guess,

00:20:17 ◼   ► ability to keep on top of things.

00:20:21 ◼   ► My favorite was I had one deprecation warning that said, I think it had something to do

00:20:25 ◼   ► with the audio session APIs, and it was the set delegate method, and it said, "This method

00:20:30 ◼   ► was first deprecated in iOS 6."

00:20:34 ◼   ► So I'm a little behind, and it's amazing that Apple has been very kind to me, and they deprecated

00:20:41 ◼   ► it in iOS 6, and it still continues to work just fine in iOS 10, but deprecation is probably

00:20:48 ◼   ► worth just saying briefly what I'm talking about.

00:20:50 ◼   ► So this is the, Apple will take a particular API, a particular method, and say, "We are

00:20:58 ◼   ► deprecating this method," which means we have something new or we have something different

00:21:02 ◼   ► that we want you to use, and usually the deprecation warning will even be nice enough to say, "You

00:21:06 ◼   ► shouldn't be using this method anymore.

00:21:08 ◼   ► You should be using this one," and point to it.

00:21:12 ◼   ► And what they're saying is, at some point, indistinctly in the future, this method is

00:21:17 ◼   ► going to go away, or it'll stop working correctly, or whatever, and this is their polite way

00:21:22 ◼   ► of saying, "You need to change your code to work with the new stuff."

00:21:31 ◼   ► Deprecation I feel like is one of these funny things where it reminds me a lot of the Hemingway

00:21:35 ◼   ► quote about going bankrupt, where you go bankrupt two ways.

00:21:39 ◼   ► You go bankrupt gradually, and then suddenly, because that's essentially what the deprecation

00:21:44 ◼   ► warnings are.

00:21:45 ◼   ► You very gradually have this building up, like I have these deprecation warnings that

00:21:48 ◼   ► have been building up over time, and they're like, "I should be changing things.

00:21:51 ◼   ► I should be improving things," and then one day suddenly, it'll just stop working.

00:21:55 ◼   ► iOS 11 will come out this June, and then suddenly I no longer have the choice and the flexibility

00:22:00 ◼   ► and the ability to just like, "Oh, I'll get to that whenever I want to."

00:22:05 ◼   ► It's like, "No, suddenly I have to do it.

00:22:07 ◼   ► The app will no longer compile."

00:22:11 ◼   ► So it's a really tricky thing, though, because the thing that I always struggle with with

00:22:15 ◼   ► deprecation is it's the issue of when to do it, because the code works as it is right

00:22:23 ◼   ► now.

00:22:24 ◼   ► And that is one of the hardest things, I think, for me to be able to justify and work, is

00:22:29 ◼   ► I'm working on an app.

00:22:30 ◼   ► Here's this function that works correctly, like functionally has been tested, has been

00:22:35 ◼   ► out in customer hands for, in this case, for years and years, and it works, it's reliable,

00:22:41 ◼   ► all the bugs have been worked out.

00:22:42 ◼   ► For me to come along and to change it when it is working now always feels a little bit

00:22:48 ◼   ► precarious.

00:22:50 ◼   ► And while I know that it's a bad thing to not, in theory, or I should probably be doing,

00:22:55 ◼   ► is as soon as I see a deprecation warning, I need to be going in there, changing it right

00:22:59 ◼   ► at that very moment.

00:23:01 ◼   ► But at the same time, APIs are most buggy when they're new, and there's lots of other considerations

00:23:07 ◼   ► that come into that that mean that sometimes I want to wait, but at the same time I don't

00:23:12 ◼   ► want to end up completely bankrupt at the end, where suddenly I'd have no choice and

00:23:15 ◼   ► I have to change everything at once, and then I'm changing, it's even more dangerous than

00:23:19 ◼   ► changing little things along the way as probably changing 80 warnings as I am right now.

00:23:25 ◼   ► That's a bit more problematic.

00:23:26 ◼   ► But that balance and that tension, I find, is really awkward and complicated to deal

00:23:30 ◼   ► with.

00:23:31 ◼   ► - I mean, the way I deal with deprecation is kind of like what I was saying last week

00:23:35 ◼   ► about Swift adoption, which is like, it's the kind of thing where a deprecation is basically

00:23:42 ◼   ► a note, it's adding something to your to-do list, that you're going to need to deal with

00:23:46 ◼   ► this.

00:23:47 ◼   ► And like most to-do items, I think practitioners of GCD and similar systems, there's almost

00:23:53 ◼   ► always a rule in those systems that says something along the lines of, if you can do something

00:23:58 ◼   ► really quickly, just do it right now and just get it done.

00:24:01 ◼   ► And if not, then you schedule it and prioritize whatever else.

00:24:04 ◼   ► Sorry, I'm not an expert in those systems, but I know there's usually the rule that says

00:24:08 ◼   ► if it's easy, just do it now.

00:24:10 ◼   ► And that's kind of how I look at deprecations and things like new languages, new APIs, new

00:24:17 ◼   ► frameworks, that the easy stuff, deprecations are usually really easy to get around.

00:24:22 ◼   ► Usually it's like, oh, there's now a new method that has an options parameter or a callback

00:24:26 ◼   ► or something else, it's like, usually the way to deal with it is very quick, you can

00:24:31 ◼   ► do it in a couple minutes at most and you're done and then that's it.

00:24:35 ◼   ► And the problem, as you said, it's like, similar to what I was saying last week about Swift,

00:24:38 ◼   ► about like, you know, at some point in the future there's going to be some API or some

00:24:42 ◼   ► policy or something that requires Swift and then like I'll be forced to learn it right

00:24:47 ◼   ► then, which is kind of not on my own time, not on my own schedule.

00:24:51 ◼   ► And it's similar with deprecations, like at some point you're going to be forced to do

00:24:55 ◼   ► this and so you're better off doing it when you have time on your own terms, on your own

00:25:01 ◼   ► schedule as opposed to in the future being forced suddenly, you know, oh, now I need

00:25:06 ◼   ► to do this instead of what I was supposed to be doing today.

00:25:09 ◼   ► It can also happen with app review, like there could be a time where you need to submit a

00:25:13 ◼   ► critical bug fix to your app and that happened to be the day that they started enforcing

00:25:22 ◼   ► this particular deprecation warning that you're hitting in app review and all of a sudden

00:25:25 ◼   ► now you can't even submit this bug fix that you need to submit because you can't submit

00:25:29 ◼   ► anything until you fix this deprecation.

00:25:31 ◼   ► And so it's a kind of thing where like most deprecations are easy to fix.

00:25:35 ◼   ► If you can fix it, just do it now because there will never be a good time later to do

00:25:39 ◼   ► it.

00:25:40 ◼   ► >> Yeah, and I think the only thing that's also complicating into this is the broader

00:25:45 ◼   ► the range of iOS versions that you support, the more complicated this becomes, I think.

00:25:51 ◼   ► >> That's true, yeah, that's true.

00:25:52 ◼   ► >> Because one of the things, like part of the reason why this app has such a wide range

00:25:57 ◼   ► of deprecation warnings is, you know, a lot of them were when I changed the minimum supported

00:26:02 ◼   ► version from iOS 8 to iOS 9, you know, then suddenly all the things that were deprecated

00:26:07 ◼   ► in iOS 8 become deprecated because before that they weren't deprecated.

00:26:11 ◼   ► In fact, they were essential because if I installed the app on a device that runs iOS

00:26:17 ◼   ► 8 and used the new API, it won't know anything about it and it won't work.

00:26:22 ◼   ► And so like this is something too that it's probably worth keeping in mind.

00:26:27 ◼   ► Like I think something that I've learned from this experience is that even if I'm not dropping

00:26:31 ◼   ► support for the older version right away, like when iOS 11 comes out this June presumably,

00:26:39 ◼   ► I'm unlikely to drop support for it right away for this particular app.

00:26:42 ◼   ► For some of them I might, but for this one I probably won't.

00:26:45 ◼   ► What I probably should do though is set the minimum version to iOS 11 and see what is

00:26:52 ◼   ► deprecated as a result, to get a sense of how big this hole I'm digging myself into

00:26:59 ◼   ► by keeping these things around.

00:27:01 ◼   ► And I mean, I will say to Apple's credit, like they are very good about this.

00:27:04 ◼   ► Like it is kind of crazy to me that how much work they seem to put into backwards support

00:27:11 ◼   ► and backwards compatibility, the fact that I can run a really old version using modern

00:27:17 ◼   ► Xcode is quite a testament to them.

00:27:19 ◼   ► And similarly, the fact that I can build, I don't know how far back I can go with the

00:27:24 ◼   ► modern version of Xcode, like if I could support iOS 4 or iOS 3.

00:27:28 ◼   ► I'm sure at some point Apple cuts it off, but the fact that they go back a couple versions

00:27:35 ◼   ► at least and cover the vast majority of users as a result is certainly a testament to the

00:27:41 ◼   ► engineering priorities and making sure that their devices, that you don't have these very

00:27:46 ◼   ► abrupt and very unexpected cutoffs, which I'm sure it takes effort and time on their part,

00:27:53 ◼   ► so they don't have to do that, but I'm glad that they do.

00:27:57 ◼   ► And I think the last thing that I've also just been thinking about as I've been going

00:28:01 ◼   ► through this is something that I notice when I'm going through these kind of cleaning passes,

00:28:06 ◼   ► and going through and cleaning up something, is it's always funny when you're going through

00:28:11 ◼   ► an old code base and you find methods that, like I've been noticing this when I'm, mostly

00:28:16 ◼   ► when I've been fixing deprecation warnings, like I find this method that has a deprecation

00:28:19 ◼   ► warning in it, I go into that method and I'm like, "Huh, I wonder where this is used."

00:28:22 ◼   ► And I do like, you know, a search all for the method signature, and it's not used anywhere.

00:28:28 ◼   ► Like it's kind of a funny thing where it's like there's this method that, you know, there's

00:28:33 ◼   ► all this code in the app that has no references to it anywhere because it existed at some

00:28:39 ◼   ► point, and then I rewrote the thing that was referencing it, and then it just sort of accumulates

00:28:44 ◼   ► over time.

00:28:45 ◼   ► And I went into AppCode, which is the IDE that JetBrains put out, which is like, I don't

00:28:51 ◼   ► use it for, I wouldn't ever use it for development, like I really like the way Xcode works, but

00:28:55 ◼   ► it has a bunch of these kind of refactoring tools, and like I found that it said, I think

00:28:59 ◼   ► there was 426 methods that were unused in the application, but it's just like, it's

00:29:04 ◼   ► the nature of, it's existed since, you know, spring of 2009.

00:29:09 ◼   ► And so I'm going through and cleaning this up, and I think it's, again, it's just one

00:29:12 ◼   ► of these things that's reminded me of like, it's probably good as I'm going to be a bit

00:29:16 ◼   ► more thoughtful about this, that when I'm removing, you know, as I'm making changes,

00:29:20 ◼   ► if I'm removing the use of a function for the last time, I should probably, you know,

00:29:25 ◼   ► clear it out there and remove the amount of code in my project because it's just increasing

00:29:30 ◼   ► the odds that, you know, there's going to be these lingering and weird bugs.

00:29:34 ◼   ► Like the less code in my app, the less bugs there are, almost certainly, so it's just

00:29:37 ◼   ► like a good reminder to me that I should be cleaning things up a little bit more.

00:29:40 ◼   ► All right, we're out of time this week.

00:29:42 ◼   ► Thank you everybody for listening, and we'll talk to you next week.

00:29:45 ◼   ► Bye.

00:29:45 ◼   ► [