iOS Build a Weather App with Swift (Retired) Pulling Data From the Web Making a Network Call

Dana Griffin
Dana Griffin
5,870 Points

NSData dataWithContentsOfURL - Swift

I believe that this method was changed since the making of the video. If anyone is having trouble try this:

<code> class func dataWithContentsOfURL(_ aURL: NSURL, options mask: NSDataReadingOptions, error errorPtr: NSErrorPointer) -> Self! <code>

Roberta Voulon
Roberta Voulon
5,792 Points

Bedankt Jeroen, your code worked for me! I was trying to make it work in Swift 2.0... hope they'll update the course soon... at least at Udacity they are on the ball and have updated all the course notes while they're updating the videos...

        // Data object to fetch weather data
        do {
            let weatherData = try NSData(contentsOfURL: forecastURL!, options: NSDataReadingOptions())
            print(weatherData)
        } catch {
            print(error)
        }

14 Answers

Pasan Premaratne , What is the correct way of using the NSData.dataWithContentsOfURL in the new Xcode version using Swift?

I currently am using Version 6.1 Beta 2 (6A1030) and tried everything without any success.

Did anyone else figure this out?

Cavin Graves
Cavin Graves
Pro Student 1,542 Points

let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil)

Jeroen de Vrind
Jeroen de Vrind
29,519 Points

If you're willing to update... for Xcode 7 and Swift 2.0 I have the following code:

// data object to fetch weather data do { let weatherData = try NSData(contentsOfURL: forecastURL!, options:NSDataReadingOptions()) print(weatherData) } catch { print (error) }

Hi guys,

I've used Dana's code suggestion and the original suggested in the video but neither of them are working for me. With Dana's code suggestion it is asking for separators to which there is no resolution.

Any suggestions?

Thanks

let weatherData = NSData(contentsOfURL: forecastURL!)

This works since the return value of forecastURL is an optional, we need to implicitly unwrapped it

This is my code and it's returning nil:

    let baseURL = NSURL(string: "https:/api.forecast.io/forecast/\(apiKey)/")
    let forecastURL: NSURL? = NSURL(string: "37.8267,-122.423", relativeToURL: baseURL)
    let weatherData = NSData(contentsOfURL: forecastURL!)

    println(weatherData)

The app crashes when it tries to execute println(weatherData)

Sebastian Nitu
Sebastian Nitu
8,616 Points

Jeroen de Vrind could you please help me with the Build a Simple Weather App project in Swift 2 and Xcode 7? Do you have the source somewhere or could you help me with the Xcode project. I am completely stuck and after I use your do-try syntax from your example above my console says "URLCopyResourcePropertyForKey failed because it was passed an URL which has no scheme Error Domain=NSCocoaErrorDomain Code=256 "The file “37.8267,-122.423” couldn’t be opened." UserInfo={NSURL=37.8267,-122.423}"

I have no idea what I am doing wrong

Use let weatherData = NSData(contentsOfURL: forecastURL!) With the ! after forecastURL

thomas bethell
thomas bethell
7,772 Points

This is what I Have...

import UIKit

class ViewController: UIViewController {

    private let apiKey = "67eb5befcd83c08736eabef9d2adb076"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.



        let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")

        let forecastURL = NSURL(string: "40.692837, -73.449052", relativeToURL: baseURL)

        let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil)

        println(weatherData)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

(Sorry, trying to use the markdown cheatsheet to get the formatting right).

Stone Preston
Stone Preston
41,951 Points

to format code using markdown you need to use the backtick character which is underneath esc and above the left tab, not a single quote. I fixed it for you. ill take a look at your code and see if I notice anything

Stone Preston
Stone Preston
41,951 Points

found your issue:

you cannot have spaces in URLs, you have a space between your two coordinates here:

let forecastURL = NSURL(string: "40.692837, -73.449052", relativeToURL: baseURL)

remove the space:

let forecastURL = NSURL(string: "40.692837,-73.449052", relativeToURL: baseURL)
Stone Preston
Stone Preston
41,951 Points

EDIT: this answer was for Xcode 6.0, not 6.1. the code below is correct in 6.0, however not in 6.1

what error did you get? I was able to call the method just fine using:

let weatherData = NSData.dataWithContentsOfURL(forecastURL, options:nil, error: nil)

which is what he used in the video.

you could also use

let weatherData = NSData(contentsOfURL: forecastURL)

which saves you from having to pass in the nil options and error

Dana Griffin
Dana Griffin
5,870 Points

Firstly, it wants me to unwrap forecastURL with a bang.

Then it throws an error : 'dataWithContentsOfURL(_:options:error:)' is unavailable: use object construction 'NSData(contentsOfURL:options:error:)' <--this works for me

The problem my arise because I am using beta 2, and Apple is still tweaking the Swift language.

Stone Preston
Stone Preston
41,951 Points

yeah swift has been updated a lot since Xcode 6 Beta 2. I would download the newest release (6.0.1). you can view it on the app store here

Dana Griffin
Dana Griffin
5,870 Points

Im using Xcode 6.1 beta 2

Stone Preston
Stone Preston
41,951 Points

ah, ok. you didnt declare forecastURL as an optional right? it should just be a regular NSURL.

Dana Griffin
Dana Griffin
5,870 Points

I kinda new to reading documentation, but do you think this has something to do with it?:

New in Xcode 6.1 Beta! Swift Language!

• A large number of Foundation, UIKit, CoreData, SceneKit, SpriteKit, Metal APIs have been audited for optional conformance, removing a significant number of implicitly unwrapped optionals from their interfaces. This clarifies the nullability of their properties and arguments / return values of their methods. This is an ongoing effort.! !These changes replace T! with either T? or T depending on whether the value can be null or not respectively. If you find a case that was changed incorrectly, please file a radar and include the tag “#IUO” in the subject line.!

If you encounter a method for which the return value is incorrectly considered non-nullable, or a property that is incorrectly considered non-nullable, you can work around the problem by immediately wrapping the result in an optional:

var fooOpt: NSFoo? = object.reallyMightReturnNil() if let foo = fooOpt { ... }

Please be sure to file a bug about these cases. Please do not file feature requests about APIs that are still marked as T!. We know about them.

Regardless, I am currently downloading the GM so I can conform to the videos.

Stone Preston
Stone Preston
41,951 Points

yes that probably has something to do with it.

Nick Barnes
Nick Barnes
7,818 Points

Hi all, I too am using Xcode 6.1 Beta 2 and the following NSData functions are broken. The give the same errors mentioned by Dana above:

NSData
    .dataWithContentsOfFile
    .dataWithContentsOfURL
    .dataWithData

The only working function is NSData.dataWithContentsOfMappedFile

I still have Xcode v6.0 installed on my mac and the above functions work as expected so it must be a result of those changes.

Nick

Tom Elders
Tom Elders
1,231 Points

Same issue here. Xcode 6.1 Beta 2. Dana's comment above illustrates the fix

let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil)

I'm assuming Apple has changed the way Swift accesses class methods for NSData, but if anyone has a canonical explanation of what's happening here, I'd love to hear it.

Jake Johnson
Jake Johnson
6,839 Points

I just posted some code that compiles correctly under the Questions section of this video. Given that Swift has changed quite a bit, the code in the video will not work until it gets updated by the Treehouse team. My code compiles and at least will let you move forward with the course until they get a chance to rework the material. Hope it helps!

thomas bethell
thomas bethell
7,772 Points

Did anyone find the answer to this issue? I am having the same problem THis is what I am entering...

'''swift let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil) ''' I get: "fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) "

As a response...I have tried most of what you have mentioned.

Stone Preston
Stone Preston
41,951 Points

post your full code please. there could be an issue with your URL

thomas bethell
thomas bethell
7,772 Points

Your good!!!!

That was it, it is working now.

Thanks Stone! (I appreciate your responsiveness as well!!!)

Stone Preston
Stone Preston
41,951 Points

no problem, glad I could help!

Had the same issue when using the syntax in the video. I am running XCode 6.1.1. I found the following code takes care of all the errors.

let weatherData = NSData(contentsOfURL: forecastURL!)

That said, I'm still confused on the optional. I have no explicit optional declaration anywhere in my code. In playing with NSURL's various methods, I ran into the need to unwrap its absoluteString method. Has something about NSURL changed that it is now returning an optional?

Michael Reining
Michael Reining
10,099 Points

The following syntax is working for me:

        let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil)
        println(weatherData)