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 ]