Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS

Mathew Spolin
Mathew Spolin
2,509 Points

How do I properly separate iOS networking code from view controllers?

I'd like to refactor the code for the Stormy app that was part of the "build a weather app in Swift" course, but I'm not sure what the best way would be.

Currently the networking code is in the viewController, so it's handling the JSON request and response in a closure defined there, and then updating the interface components in a dispatch_async closure inside that.

I'd like to move the interface to the Forecast service to it's own ForecastService class that does the JSON request and response, but I still want to do the view updates as part of that completion handler, because that seems slick.

What's the best way to do this? It seems not great to have the network calls inside the view controller, but on the other hand the UI updates definitely belong there. Would the best way be to pass the inner closure to a ForecastService class? How do I do that in Swift?

2 Answers

Nick Jones
Nick Jones
2,086 Points

Hi Matthew

That's a pretty big question in that, well, there are definitely a fair few different approaches you could take to setting up what you're after, but in short what you're suggesting is a great idea so hopefully I can at least help a little.

First off with regards to setting up a new class such as the potential "ForecastService" class you mentioned the best start is to take the S from SOLID and ensure that it only has a single responsibility. When you talked about it not feeling great that network requests were being handled in the view sounds completely right, what you'll want to do is move just that to it's own class from where you can then call it to do all of the dirty work for you, in your case getting the Stormy JSON back from the API, and then returning it to your view where you can then manipulate it. The benefit of this is that your new class and the methods within said class will be completely ignorant of what the data it is returning is going to be used for which is exactly how it should be.

There are an abundance of ways to go about getting the result you're after but the way I've found that works for me is making use of callbacks to ensure data is fully loaded before it being pushed to the UI. Perhaps the easiest way to show what I mean would be to have a look at what I currently have set up for one of my dev apps which is:

CloudKit Handling

Whilst the code is being used for CloudKit the concept of using callbacks in the way they're laid out in there are the same that you could use for your potential ForecastService class.
The code in the above link could do with some more refactoring so apologies if it's a little verbose. If there's anything there that catches your eye that you'd like some more info on then of course just let me know.

KR

Nick

Mathew Spolin
Mathew Spolin
2,509 Points

Thanks, Nick! I will take a crack at improving the Stormy app based on this pattern.