Welcome to the Treehouse Community
Looking to learn something new?
Mathew Spolin2,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?
Nick Jones2,086 Points
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:
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.
Mathew Spolin2,509 Points
Thanks, Nick! I will take a crack at improving the Stormy app based on this pattern.