Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Weather App with Swift Managing Complexity Callback Methods With Closures

Bradley Isenbek
Bradley Isenbek
2,629 Points

I am at a loss with this quiz. I create typealias BlogPostCompletion = (NSData!, NSURLResponse!, NSError!) -> Void

What am I doing wrong?

import Foundation

typealias BlogPostCompletion = (NSData!, NSURLResponse!, NSError!) -> Void

// Add your code below
func fetchTreehouseBlogPosts (completion: BlogPostCompletion) {
}
Callbacks.swift
import Foundation

typealias BlogPostCompletion = (NSData!, NSURLResponse!, NSError!) -> Void

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

Just want to provide a link to the objective:

http://teamtreehouse.com/library/build-a-weather-app-with-swift-2/managing-complexity/callback-methods-with-closures

Here's the objective:

Challenge Task 1 of 2

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

There is another forum post about this (which doesn't have many responses): https://teamtreehouse.com/forum/whats-wrong-on-this-syntax-in-swift

Notice though it says:

This requires making a network request using asynchronous methods that execute in the background

I don't think this code has anything asynchronous about it.

I found this swift code:

var url : String = "http://google.com?test=toto&test2=titi"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(),

    completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in

})

..on this StackOverFlow page:

http://stackoverflow.com/questions/27720021/swift-cant-send-urlrequest-at-all

maybe there should be some code like that?

It's similar to code on this page:

https://gist.github.com/cmoulton/01fdd4fe2c2e9c8195e1

However, this code would have to be adapted to use the fetchTreehouseBlogPosts method somehow..


I would also note there is a TeamTreehouse blog post about making asynchronous network requests in Swift:

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

However, none of the code in that blog post seems to pass.


Looking at the NetworkOperations code in the course Downloads "Stormy3V2" zip file for the course,

I found a typealias line so I modified that code to conform with the questions and got:

class NetworkOperation {

    lazy var config: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    lazy var session: NSURLSession = NSURLSession(configuration: self.config)
    let queryURL: NSURL

    typealias BlogPostCompletion = ([String: AnyObject]? -> Void)

    init(url: NSURL) {
        self.queryURL = url
    }

    func fetchTreehouseBlogPosts(completion: BlogPostCompletion) {

        let request = NSURLRequest(URL: queryURL)
        let dataTask = session.dataTaskWithRequest(request) {
            (let data, let response, let error) in

            // 1. Check HTTP response for successful GET request
            if let httpResponse = response as? NSHTTPURLResponse {
                switch httpResponse.statusCode {
                case 200:
                    // 2. Create JSON object with data
                    let jsonDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [String: AnyObject]
                    completion(jsonDictionary)
                default:
                    println("GET request not successful. HTTP status code: \(httpResponse.statusCode)")
                }
            } else {
                println("Error: Not a valid HTTP response")
            }
        }

        dataTask.resume()
    }
}

However it didn't like that code either (although the output.html showed no errors), it still gave:

Bummer! Make sure the method is named fetchTreehouseBlogPosts and has the correct syntax!

3 Answers

Joshua C
Joshua C
51,696 Points

You're really close!

You forgot to enclose the typealias result in parentheses (including the "Void" at the end):

typealias BlogPostCompletion = ((NSData!, NSURLResponse!, NSError!) -> Void)

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

Hi Brian,

In the video, Pasan didn't enclose the typealias result in parentheses but it seems to be working just fine. Can you think of a reason for this?

Thanks.

I'd like to know the same thing as Alp Eren Can... or is this just an instance of another Treehouse objective that is being more strict that it should be? Because I run into those a lot.

Bradley Isenbek
Bradley Isenbek
2,629 Points

Brian,

Thank you my friend! You are a martial artist and an iOS Ninja ...

-Brad

Yes, thanks Brian. I was over thinking the code.

For those who find Brian's code helpful towards getting past task 1 of 2 for the objective, I would recommend this helpful thread if you get stuck on task 2 of 2 for the same objective:

https://teamtreehouse.com/forum/cant-return-results-to-method-via-completion-handler