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 Build a Weather App with Swift Managing Complexity Callback Methods With Closures

Why doesn't my code work for the challenge task?

I'm not sure why my code doesn't work for the challenge task here. I've provided a closure in the format: (parameters) -> return-type It seems to be okay in other cases not to include the in statements part here, especially since the challenge provides no info about what would go there. It would be included when you call the method, right? What am I missing?

For reference, my code is below, and here's the challenge question:

"We're writing an app to fetch the most recent blog posts from the Treehouse blog. This requires making a network request using asynchronous methods that execute in the background. For that we need a closure. Create a method called fetchTreehouseBlogPosts, that has a single parameter - a completion handler. The closure has three parameters: a data object containing the results of the request as type NSData!, the HTTP response object from our request as type NSURLResponse!, an error object as type NSError!, and a return type of void. Note: If you prefer to use a typealias to make the method signature clear, name it BlogPostCompletion"

Callbacks.swift
import Foundation
typealias BlogPostCompletion = (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void

func fetchTreehouseBlogPosts(completion: BlogPostCompletion) {

}

2 Answers

Holger Liesegang
Holger Liesegang
50,595 Points

Hi Daniel!

You might want to modify your typealias for the method signature like this:

typealias BlogPostCompletion = ((NSData!, NSURLResponse!, NSError!) -> Void)
Callbacks.swift
import Foundation

// Add your code below
typealias BlogPostCompletion = ((NSData!, NSURLResponse!, NSError!) -> Void)

// Add your code below
func fetchTreehouseBlogPosts (completion: BlogPostCompletion) {
}

Thanks, Holger!

I tried your code and it worked. Then, I went back to modify between our two code versions to isolate what it was that made the difference. Ultimately, it does me little good if I solve the challenge with your code but don't understand why it works (and mine doesn't).

My first thought was the difference in parentheses, but I had already tried the parentheses in a variety of different forms, including the way you have it. It was the first thing I had thought might be off, and so I had already messed with it a bunch. In fact, I think the correct way that you have it was how I had started, and I had changed the parentheses in my (unsuccessful) experimentation to fix it before. That was a part of the problem in the version that ultimately got posted, but I had already tried it both ways there and neither worked, so it wasn't the whole issue. I had also tried it without using the typealias at all, probably with 6 different variations on parenthesis placement, to no avail.

What I hadn't tried, which ultimately seems to make the difference, was not naming the parameters within the completion. When I add names, it no longer works. When I remove the names, with otherwise the same code, it does work. Am I correct that you are not able to name the parameters in a completion? Do you know why? A completion is really supposed to be a function within a function, so it seems illogical -- you could name the parameters in any other kind of function, and in fact it would be expected.

Or am I missing something else? Maybe something else is changing here that I'm not noticing, and the names aren't the real issue? I'd just like to understand what's going on here, and why one version works without names, and the other with names does not.

Holger Liesegang
Holger Liesegang
50,595 Points

IMHO

typealias BlogPostCompletion = ((data: NSData!, response: NSURLResponse!, error: NSError!) -> Void)

should work...so it's most likely the Code Challenge...

also: http://blog.teamtreehouse.com/making-network-request-swift

and:https://medium.com/swift-programming/swift-typealias-to-the-rescue-b1027fc571e3

I'll have to try it out somewhere else, then. I tried out your code with names, and the treehouse code challenge did not accept it. If I spent all that time trying to figure out what I had done wrong, and my code (before all the messing with parentheses) was fine to begin with -- in a REAL situation just not according to the algorithms of the code challenge -- I'm going to be pretty frustrated with the waste of time!

Thanks for the other links. I'll check them out.

Removing the space between { and } in your function should fix the problem. your problem should look exactly like this:

func fetchTreehouseBlogPosts (completion: BlogPostCompletion) {
}