PodSearch

Developing Perspective

#30: iOS Networking Stacks

 

00:00:00 ◼   ► Hello and welcome to developing perspective developing perspective is a podcast discussing news of note in iOS Apple and the like

00:00:07 ◼   ► I'm your host David Smith. I'm an independent iOS developer based in Herndon, Virginia. This is show number 30. And today I'm going to be talking about

00:00:14 ◼   ► iOS networking

00:00:18 ◼   ► Specifically kind of how I do it my preferences things that I've learned over kind of doing this for a couple of years

00:00:22 ◼   ► And I'll kind of walk through what I prefer to do some of the place I've been burned in the past and so on

00:00:28 ◼   ► All right

00:00:30 ◼   ► So when I say networking what I mean is essentially how I get data from

00:00:35 ◼   ► Yes, so some networking URL and put that into my app whether I'm downloading a file like I do in my audiobooks application

00:00:44 ◼   ► Which downloads lots of mp3s?

00:00:46 ◼   ► Whether I'm just reading a URL to get some data from a web service

00:00:50 ◼   ► Say like for example in the app called civil gram that downloads

00:00:54 ◼   ► Data from the Instagram API, so making lots of JSON requests and things to kind of manage that

00:00:59 ◼   ► And really however I do it. I'm always sort of opening URL and getting some data and then doing something with it

00:01:05 ◼   ► it's a very common paradigm and it's probably one of the things that almost every

00:01:10 ◼   ► iOS app I've ever worked on had some form of

00:01:13 ◼   ► And so basically that you know you'd think oh, it's free

00:01:18 ◼   ► You know it's surface all solve problem at that point, but the tricky thing with networking is hey

00:01:23 ◼   ► hey, there's a lot of things that can go wrong.

00:01:26 ◼   ► There's a lot of places where,

00:01:27 ◼   ► especially on a mobile device like an iPhone,

00:01:30 ◼   ► where all of a sudden they're on 3G

00:01:31 ◼   ► and the network just disappears for a minute or something,

00:01:34 ◼   ► or they're in a car driving

00:01:36 ◼   ► and they're switching cell towers

00:01:37 ◼   ► and all kinds of weird issues can kind of come up.

00:01:41 ◼   ► And then sort of compounding that

00:01:44 ◼   ► is Apple provides not that great,

00:01:46 ◼   ► it's sort of, or certainly not high level APIs

00:01:52 ◼   ► dealing with networking. Almost all the Apple-provided stuff revolves around NSURLConnection, which

00:01:59 ◼   ► is a fine class that lets you open a URL request, download the contents as you go, reject the

00:02:05 ◼   ► status and so on. But that typically exposes too many details to the developer when they

00:02:12 ◼   ► really just want, "Open this URL and give me the results or tell me it failed. I don't

00:02:18 ◼   ► I don't need to know all the details,

00:02:20 ◼   ► I don't need to know all the memory management

00:02:22 ◼   ► of where is this, how much data have I got,

00:02:24 ◼   ► what's the progress, and so on.

00:02:26 ◼   ► And so typically what developers have done traditionally

00:02:29 ◼   ► is they've built wrappers around that.

00:02:31 ◼   ► For a very long time, the big winner in terms of popularity

00:02:37 ◼   ► was a thing called ASI HTTP request,

00:02:40 ◼   ► which is currently kind of, I wouldn't say defunct

00:02:43 ◼   ► is the wrong word, but is no longer being actively developed.

00:02:46 ◼   ► about the guy who wrote it and kind of, you know, I don't want to get into that for a

00:02:52 ◼   ► while, that was sort of the big thing. And then a variety of others have kind of sprung

00:02:55 ◼   ► up over time. And I think they solve the problem better typically than the way that Apple's

00:03:04 ◼   ► API provides. I would say one thing that's interesting is that on the Mac in 10.7, Apple

00:03:11 ◼   ► some nice block-based updates to nsu-oral connection that hopefully will one day find their way to the iOS

00:03:17 ◼   ► Which solve a lot of these problems and what I would love to be able to drop

00:03:22 ◼   ► You know a third-party dependency like this and just use the Apple stuff. It's not quite ready yet

00:03:28 ◼   ► So anyway, so I'm gonna kind of talk through the way I do this and kind of what I do

00:03:33 ◼   ► Right now my kind of go-to networking stack is AF networking

00:03:38 ◼   ► Which there's a link in the show notes if you're interested in and looking it up

00:03:43 ◼   ► Which is a networking API that was developed by the team at Gowalla

00:03:47 ◼   ► I think it's what they are they developed and internally for their projects and then open-sourced it. It's a MIT licensed

00:03:56 ◼   ► You know products are basically which basically means you can use it however you want and

00:04:03 ◼   ► you

00:04:05 ◼   ► without restrictions. It's not a VSD license or something that you have to do attribution with,

00:04:12 ◼   ► though it's always nice to do attribution. You can basically just do what you want with this.

00:04:16 ◼   ► And so, what I like about AF networking is two things.

00:04:21 ◼   ► One is it provides a really nice block-based API for network operations,

00:04:26 ◼   ► and that's really all I want. Since iOS 4 came along and allowed you to do blocks,

00:04:32 ◼   ► it makes the code you write for networking so much easier,

00:04:36 ◼   ► rather than being delegate-based.

00:04:38 ◼   ► So rather than having to build these kind of complicated

00:04:40 ◼   ► sort of callback delegate structures that you have to keep track of your state and things,

00:04:46 ◼   ► you can do these really nice things where you say,

00:04:48 ◼   ► in this block of code, you build a request, make the request,

00:04:52 ◼   ► and then it's like, if it fails, call this block.

00:04:55 ◼   ► If it succeeds, call this block.

00:04:58 ◼   ► If you have a progress update, call this block.

00:05:01 ◼   ► And that just kind of works.

00:05:03 ◼   ► It keeps your code really straightforward.

00:05:05 ◼   ► It keeps it all in one place,

00:05:07 ◼   ► which I think makes maintainability hugely easier.

00:05:11 ◼   ► Because rather than having this problem of,

00:05:13 ◼   ► "Okay, where does this, what is this delegate callback

00:05:15 ◼   ► getting called from, and what's going on here, here, and here?"

00:05:19 ◼   ► It's all just in one place.

00:05:21 ◼   ► You look at it and it's like, "Okay, they made a request

00:05:23 ◼   ► to get user feed."

00:05:25 ◼   ► And then here, if it fails,

00:05:27 ◼   ► they display an error message, or they do whatever they need.

00:05:29 ◼   ► need. Here's a progress update. So if you're doing some like downloading a file, you can say okay,

00:05:33 ◼   ► you know, I've done 10%, 20%, 30%, and then if it succeeds, okay, now here it goes, and if it goes

00:05:40 ◼   ► and parses it or does whatever. And I found that to be really helpful. Typically, I mean, using a

00:05:45 ◼   ► third-party library is always a little bit risky. You never really know what you're getting yourself

00:05:50 ◼   ► into. And the reason I feel pretty good about AF networking right now is that it's just, it's

00:05:55 ◼   ► promoted and put out by a organization rather than a individual.

00:06:01 ◼   ► So this is, I imagine, used, was developed by Goaala internally, and then they decided to open source it.

00:06:07 ◼   ► Goaala is not like it's a huge company, it's not like it was built by Apple or IBM or something,

00:06:12 ◼   ► but they're a sizable startup that's doing fairly well.

00:06:18 ◼   ► And it seems to have a fairly high activity level on GitHub, which is always a good thing.

00:06:22 ◼   ► There's 1,700 watchers and 211 fork requests, or forks of it.

00:06:30 ◼   ► So people are kind of playing with it and using it.

00:06:33 ◼   ► As a comparison, one that I did look at

00:06:36 ◼   ► is MKNetworkKit, which is written by Munguth Kumar, which

00:06:40 ◼   ► is another pretty good block-based networking

00:06:43 ◼   ► stack that I kind of looked at and played with.

00:06:45 ◼   ► But in the end, the thing that I ended up

00:06:47 ◼   ► going with AF networking is just that stability

00:06:50 ◼   ► and the, I guess maybe the dependability

00:06:55 ◼   ► that AF networking provides,

00:06:57 ◼   ► that I'm fairly confident that it'll be updated

00:06:59 ◼   ► as it goes forward, that it'll be worked on and so on

00:07:03 ◼   ► in a way that, with something that's a smaller project

00:07:06 ◼   ► by an individual, it's not to say that it's bad,

00:07:08 ◼   ► but it just doesn't give me the same warm fuzzies

00:07:11 ◼   ► that a larger project with lots of followers,

00:07:14 ◼   ► lots of activity on it kinda does.

00:07:17 ◼   ► So that's basically what I use in my apps now.

00:07:18 ◼   ► I just throw in AF networking, it's about five or six classes

00:07:23 ◼   ► that you add to your app.

00:07:26 ◼   ► One thing I will say is that it has a bunch of

00:07:28 ◼   ► kind of advanced features, I guess you could say,

00:07:30 ◼   ► where it's like, oh, here's a JSON request,

00:07:32 ◼   ► and give me the, rather than returning a data object,

00:07:34 ◼   ► it returns a dictionary or an array of objects,

00:07:37 ◼   ► or you can do an XML thing.

00:07:41 ◼   ► Those I never really use, and you can also do this thing

00:07:43 ◼   ► where you give it a UI image view,

00:07:45 ◼   ► and it updates the UI image view kind of behind the scenes

00:07:48 ◼   ► and the data's available and so on.

00:07:49 ◼   ► I tend to stay away from those,

00:07:50 ◼   ► and generally I'd recommend kind of avoiding

00:07:53 ◼   ► any kind of magic in the application.

00:07:56 ◼   ► But I want my networking stack to do is say,

00:07:59 ◼   ► here's a URL, give me the data, and that's it.

00:08:02 ◼   ► And then from there, I'm gonna take it

00:08:04 ◼   ► and I'm gonna work with that data.

00:08:05 ◼   ► Because of the fewer things that I'm relying

00:08:08 ◼   ► on this third party to do, I think typically

00:08:11 ◼   ► the more reliable and maintainable my code's gonna be.

00:08:14 ◼   ► So as soon as it, you know, it's like,

00:08:15 ◼   ► If there's some weird JSON parsing bug,

00:08:18 ◼   ► it's going to be harder for me to realize

00:08:19 ◼   ► that's happening inside of AF networking

00:08:23 ◼   ► than if it was just part of my own code,

00:08:25 ◼   ► and I can see, okay, here's the data I got back.

00:08:28 ◼   ► That looks correct.

00:08:29 ◼   ► So then it's my problem,

00:08:31 ◼   ► rather than this kind of two-step problem

00:08:33 ◼   ► of am I getting the right data back,

00:08:34 ◼   ► and then am I parsing it correctly,

00:08:36 ◼   ► and then am I doing something wrong with it?

00:08:38 ◼   ► So I would definitely kind of stay away from most of those.

00:08:41 ◼   ► It's kind of cool in some ways,

00:08:43 ◼   ► like you can kind of simplify your code,

00:08:44 ◼   ► but I think overall, I would rather do my own kind of wrappings around those things.

00:08:48 ◼   ► But that's just kind of the way I roll, I guess.

00:08:51 ◼   ► Let's see, other thoughts about networking stacks.

00:08:54 ◼   ► Things that you should keep in mind is that they're online especially.

00:08:59 ◼   ► There's a great tool called the Network Link Conditioner,

00:09:02 ◼   ► which is a little thing that's installed with the SDK

00:09:06 ◼   ► sender, I think applications, utilities, that lets you configure your regular Macs, you

00:09:15 ◼   ► know, Wi-Fi or wired Ethernet connection to act as though it's a dubious connection, act

00:09:20 ◼   ► as though it's a 3G network, act as though it's an edge network, randomly drop packets,

00:09:25 ◼   ► do all kinds of things like that. That is really helpful for testing and debugging,

00:09:30 ◼   ► because typically if you're in the simulator you can do a much quicker round trips, your

00:09:34 ◼   ► performance of the app so much better, which is not great for performance testing, but

00:09:38 ◼   ► for as you're testing and iterating on something, it's much quicker of a feedback loop that

00:09:43 ◼   ► you can get.

00:09:44 ◼   ► You can use the networking conditioner to play with that.

00:09:47 ◼   ► Of course, that's no substitute for testing on a device, but I found that to be kind of

00:09:52 ◼   ► a helpful thing to just be like, "Hey, let's see what happens."

00:09:55 ◼   ► And also it lets you test in circumstances that are often difficult to recreate on a

00:09:59 ◼   ► device.

00:10:00 ◼   ► it's like if I want to test a really bad edge,

00:10:04 ◼   ► you know, 2G connection on my iPhone,

00:10:06 ◼   ► I'd need to turn off 3G and then drive

00:10:10 ◼   ► to the middle of nowhere, which can be kind of awkward

00:10:13 ◼   ► and kind of annoying to do, you know,

00:10:16 ◼   ► 'cause my office gets great cell phone reception,

00:10:18 ◼   ► I'm really near a cell tower.

00:10:20 ◼   ► So it's kind of nice to be able to test

00:10:21 ◼   ► and do those kinds of extreme tests

00:10:23 ◼   ► without having to physically test it and do it.

00:10:27 ◼   ► I remember back when I was first working on audiobooks

00:10:29 ◼   ► back in the day, I remember doing testing

00:10:32 ◼   ► where I would take my iPhone and wrap it and unwrap it

00:10:36 ◼   ► in aluminum foil, which, if you've never done it,

00:10:40 ◼   ► if you wrap a phone in aluminum foil,

00:10:42 ◼   ► the cell signal disappears 'cause you're building it

00:10:45 ◼   ► inside of a Faraday cage.

00:10:46 ◼   ► And so I would sit there and wrap and unwrap

00:10:49 ◼   ► and wrap and unwrap to simulate packet loss

00:10:51 ◼   ► and to deal with those kinds of things.

00:10:53 ◼   ► I can definitely say using the Network Link Conditioner

00:10:55 ◼   ► is a much better choice than doing something like that.

00:10:59 ◼   ► One of the other things about networking is to just generally be careful with it.

00:11:05 ◼   ► I mean, I think I take a very pragmatic use on it, where some people go kind of crazy

00:11:09 ◼   ► about "oh, what happens if this..." you know, it's like dealing with failure and so on.

00:11:13 ◼   ► And I think in my experience, users are fairly tolerant of, if they're on a bad connection,

00:11:18 ◼   ► they're going to know that and be somewhat tolerant of that failure.

00:11:23 ◼   ► And your goal in that case is to never put the app into an unresponsive or inconsistent

00:11:28 ◼   ► But I don't tend to do too much of like,

00:11:31 ◼   ► "Okay, I'm going to keep trying to retry it,

00:11:33 ◼   ► and retry it, and retry it."

00:11:34 ◼   ► Or, you know, just sort of trying to do two smart things.

00:11:37 ◼   ► If it fails, I'm just going to tell the user,

00:11:39 ◼   ► "Hey, it looks like your network connection's a little spotty right now.

00:11:42 ◼   ► Can you check on that and try again?"

00:11:45 ◼   ► Which may or may or may not be good.

00:11:47 ◼   ► I think that tends to work better, I find,

00:11:50 ◼   ► than to kind of be trying and trying and trying,

00:11:54 ◼   ► and the user doesn't really know what's happening.

00:11:56 ◼   ► It looks like it looks like it's downloading, it looks like it's not.

00:12:00 ◼   ► So just sort of some thoughts.

00:12:02 ◼   ► Alright, that's it for today's show.

00:12:04 ◼   ► As always, if you have any thoughts, questions, comments, feedback, hit me up on Twitter.

00:12:08 ◼   ► I am @_davidsmith.

00:12:09 ◼   ► I blog at david-smith.org.

00:12:13 ◼   ► And otherwise, I hope you have a good day.

00:12:15 ◼   ► Happy coding, and I'll talk to you later.

00:12:16 ◼   ► [BLANK_AUDIO]

00:12:26 ◼   ► [

00:12:34 ◼   ► [ Silence ]