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

Yupin Hu
Yupin Hu
3,702 Points

Your job is to create a data task (not a download task), named dataTask, with a completion handler that returns the resu

Spent way too much time on it and still can't get the correct solution, please help~ Thanks in advance!

Your job is to create a data task (not a download task), named dataTask, with a completion handler that returns the results of the data task. Add this data task between the commented section. Once that's done, within the body of the data task, return the results to the fetchTreehouseBlogPosts method's completion handler.

Callbacks.swift
import Foundation

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

func fetchTreehouseBlogPosts(completion: BlogPostCompletion){
let blogURL = NSURL(string: "http://blog.teamtreehouse.com/api/")
  let requestURL = NSURL(string: "get_recent_summary/?count=20", relativeToURL: blogURL)

  let request = NSURLRequest(URL: requestURL!)

  let config = NSURLSessionConfiguration.defaultSessionConfiguration()
  let session = NSURLSession(configuration: config)

  // Add your code between the comments

  var dataTask: NSURLSessionDataTask
  let dataTask = session.dataTaskWithRequest(request){
    (let data, let response, let error) in
    completion(NSJSONSerialization.JSONObjectWithData(BlogPostComplication))
  }
  // Add code above

  dataTask.resume()
}

6 Answers

Nick Kohrn
Nick Kohrn
38,025 Points

Yupin,

I was able to get it working by changing the completion handler from this:

let dataTask = session.dataTaskWithRequest(request){
    (let data, let response, let error) in
    completion(NSJSONSerialization.JSONObjectWithData(BlogPostComplication))
  }

to this:

let dataTask = session.dataTaskWithRequest(request) {
  (let data, let response, let error) in    
      completion(data, response, error)
  }

Also, just for future reference, when you are creating your data task, you have an extra variable with an assigned value of NSURLSessionDataTask. Since you are creating a data task and assigning it to a constant named dataTask, you do not need the line above it, which is var dataTask: NSURLSessionDataTask.

By having these two assignments, your var dataTask: NSURLSessionDataTask is unnecessary and unused. Also, the challenge tells you to assign to a constant, which means that you don't want to use any variables (var) anyway.

var dataTask: NSURLSessionDataTask
// The line above is unnecessary because you are assigning dataTask below. 

let dataTask = session.dataTaskWithRequest(request) {
    // Code for handling data task...
}

Hope this helps!!

Yupin Hu
Yupin Hu
3,702 Points

Thanks Nick for your help! and yes you are right, I don't know what I was thinking when creating the var. however if I don't it will complain that I need to create NSURLSessionDataTask. Finally, it worked for me with the following code:

let dataTask:NSURLSessionDataTask = session.dataTaskWithRequest(request) { (let data, let response, let error) in
completion(data, response, error)

Nick Kohrn
Nick Kohrn
38,025 Points

Yupin,

You are very much welcome! I'm glad that I could assist you!

Also, I too, sometimes have to declare a variable or constant as a certain type before I assign it a value. I'm still trying to figure that one out myself.

If you don't mind, would you mark my answer as the best answer if it helped you solve your problem properly?

Let me know if there is anything else that I can help you with, Yupin.

Nick Kohrn
Nick Kohrn
38,025 Points

Yupin,

When you are calling your completion handler, you have BlogPostCompletion misspelled; you currently have BlogPostComplication.

Change that to BlogPostCompletion and that should fix it.

Hope this helps!

Yupin Hu
Yupin Hu
3,702 Points

Thanks Nick for catching that error! now it still gives me error saying: "Make sure you pass the correct order and type of parameters to the completion handler of the fetchTreehouseBlogPosts method."

any idea? Thanks!

Yupin Hu
Yupin Hu
3,702 Points

You bet! Thanks again Nick! I am very new to iOS, do you find learning Objective-C necessary for an new iOS developer or stick with one language. Thanks in advance!

Nick Kohrn
Nick Kohrn
38,025 Points

Yupin,

I have been learning iOS development for almost two years now. I started off very casually with Objective-C but Apple introduced Swift only a few months after the beginning of my journey. I did finish the iOS track that was written in Objective-C on Treehouse, but I immediately went straight into learning Swift when I was finished with the track. It was and still is very clear that Apple is pushing Swift and making it a priority.

With that said, I was very glad that I learned some Objective-C because it has helped me tremendously when learning form tutorials that are written in it. I am able to translate the code into Swift much easier. However, I have not written any Objective-C for over a year as I have been writing a personal app in Swift, which I aim to release in the coming months.

If I could go back and start over, I would like to get more comfortable with Objective-C because I look to get a job as a developer in the near future and I am sure that I will see and/or have to maintain some legacy code that is written in Objective-C.

With that said, I am still very happy with my decision to focus on Swift because as I learn from online tutorials and other resources, I am picking up more and more Objective-C since there is still a lot written in it. Also, you can always go back and take the courses here at Treehouse that are written in Objective-C when you have some free time. As an aspiring developer in a very competitive market, knowing multiple languages seems to always be a positive!

Hope this helps you!

Yupin Hu
Yupin Hu
3,702 Points

Got chu! Thanks Nick for sharing your experience with me!! Best of the luck with your new app! Let me know when you app is published! I will sure check it out!!

Bruna Aleixo
Bruna Aleixo
2,693 Points
import Foundation

// Add your code below
typealias BlogPostCompletion = ((NSData!, NSURLResponse!, NSError!) -> Void)
func fetchTreehouseBlogPosts(completion: BlogPostCompletion) {
let blogURL = NSURL(string: "http://blog.teamtreehouse.com/api/")
  let requestURL = NSURL(string: "get_recent_summary/?count=20", relativeToURL: blogURL)

  let request = NSURLRequest(URL: requestURL!)

  let config = NSURLSessionConfiguration.defaultSessionConfiguration()
  let session = NSURLSession(configuration: config)

  let dataTask: NSURLSessionDataTask  = session.dataTaskWithURL(request) {
      (let data, let response, let error) in
      completion(data, response, error)
  }

  dataTask.resume()
}

Why isnt my code working?

Whenever I hit submit the following message appears: Make sure you pass the correct order and type of parameters to the completion handler of the fetchTreehouseBlogPosts method.

Bruna, use the following code:

import Foundation

// Add your code below
typealias BlogPostCompletion = ((NSData!, NSURLResponse!, NSError!) -> Void)
func fetchTreehouseBlogPosts(completion: BlogPostCompletion) {
let blogURL = NSURL(string: "http://blog.teamtreehouse.com/api/")
  let requestURL = NSURL(string: "get_recent_summary/?count=20", relativeToURL: blogURL)

  let request = NSURLRequest(URL: requestURL!)

  let config = NSURLSessionConfiguration.defaultSessionConfiguration()
  let session = NSURLSession(configuration: config)

// Change session.dataTaskWithURL to session.dataTaskWithRequest

  let dataTask: NSURLSessionDataTask  = session.dataTaskWithRequest(request) {
      (let data, let response, let error) in
      completion(data, response, error)
  }

  dataTask.resume()
}