Jun
Jun

Reputation: 570

Get Nil When Trying to Reuse NSURL

I'm trying to get the weather of some locations using https://developer.forecast.io/ api. The format of API call is https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE

I can get response from one position, but when I tried to change the location and get the weather again use NSURL, the NSURL returns Nil. Why is that and how to handle this?

Can anyone helps me out? Thanks.

func getCurrentWeatherData() -> Void {
        let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
        var forecastURL = NSURL(string: "36.107728,-112.113040", relativeToURL: baseURL)
        let sharedSession = NSURLSession.sharedSession()
        let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: {
            (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in

            //var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
            if (error == nil) {
                let dataObject = NSData(contentsOfURL: location)
                let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary
                let currentWeather = Current(weatherDictionary: weatherDictionary)

                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.iconView.image = currentWeather.icon!
                    self.currentTimeLabel.text = "At \(currentWeather.currentTime!) it is"
                    self.temperatureLabel.text = "\(Double(currentWeather.temperature-32) * 0.56)"
                    self.summaryLabel.text = "\(currentWeather.summary)"
                    self.refreshActivityIndicator.stopAnimating()
                    self.refreshActivityIndicator.hidden = true
                    self.refreshButton.hidden = false
                })
            } else {
                let networkIssueController = UIAlertController(title: "Error", message:"Unable to load data. Connectivity error!", preferredStyle: .Alert)
                let okButton = UIAlertAction(title: "OK", style: .Default, handler:nil)
                networkIssueController.addAction(okButton)
                let cancelButton = UIAlertAction(title:"Cancel", style: .Cancel, handler:nil)
                networkIssueController.addAction(cancelButton)
                self.presentViewController(networkIssueController, animated: true, completion: nil)
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.refreshActivityIndicator.stopAnimating()
                    self.refreshActivityIndicator.hidden = true
                    self.refreshButton.hidden = false
                })
            }
        })
        downloadTask.resume()

        var forecastURL2 = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/36.861941, -111.374420")
        let sharedSession2 = NSURLSession.sharedSession()
        **//forcastURL2 returns Nil**
        let downloadTask2: NSURLSessionDownloadTask = sharedSession2.downloadTaskWithURL(forecastURL2!, completionHandler: {
            (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in

            //var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
            if (error == nil) {
                let dataObject = NSData(contentsOfURL: location)
                let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary
                let currentWeather = Current(weatherDictionary: weatherDictionary)

                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.iconView2.image = currentWeather.icon!
                    self.temperatureLabel2.text = "\(Double(currentWeather.temperature-32) * 0.56)"
                    self.summaryLabel.text = "\(currentWeather.summary)"
                    self.refreshActivityIndicator.stopAnimating()
                    self.refreshActivityIndicator.hidden = true
                    self.refreshButton.hidden = false
                })
            } else {
                let networkIssueController = UIAlertController(title: "Error", message:"Unable to load data. Connectivity error!", preferredStyle: .Alert)
                let okButton = UIAlertAction(title: "OK", style: .Default, handler:nil)
                networkIssueController.addAction(okButton)
                let cancelButton = UIAlertAction(title:"Cancel", style: .Cancel, handler:nil)
                networkIssueController.addAction(cancelButton)
                self.presentViewController(networkIssueController, animated: true, completion: nil)
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.refreshActivityIndicator.stopAnimating()
                    self.refreshActivityIndicator.hidden = true
                    self.refreshButton.hidden = false
                })
            }
        })
        downloadTask2.resume()

    }

Upvotes: 0

Views: 97

Answers (2)

Aaron Brager
Aaron Brager

Reputation: 66244

Delete the space:

var forecastURL2 = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/36.861941,-111.374420")

Also, for future questions, it would be helpful if you didn't post all of the code in your method, but rather just the code necessary to reproduce the issue (in this case, just this one line was necessary.)

Upvotes: -1

Jérôme
Jérôme

Reputation: 8066

The URL that you use ("https://api.forecast.io/forecast/\(apiKey)/36.861941, -111.374420") should be well formatted and, according to Apple, comply with RFC2396. If not NSURL will return nil.

The url that you use is not correct. For example space should be escape using "%20". In your case, I think you can just remove the space.

Upvotes: 3

Related Questions