Ios 如何在Swift上访问其方法之外的词典数据?

Ios 如何在Swift上访问其方法之外的词典数据?,ios,swift,dictionary,Ios,Swift,Dictionary,我正在用Swift创建一个天气应用程序。因此,我检索了JSON数据并将其存储在字典中: import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() ///////getting URL: let mainAddress = NSURL(string: "https://...") //for NY //

我正在用Swift创建一个天气应用程序。因此,我检索了JSON数据并将其存储在字典中:

import UIKit

class ViewController: UIViewController {


override func viewDidLoad() {
    super.viewDidLoad()

    ///////getting URL:

    let mainAddress = NSURL(string: "https://...") //for NY



    //Now, getting the data syncronously by creating a session object::
    let sharedSession = NSURLSession.sharedSession()
    let downloadTask: NSURLSessionDownloadTask =
    sharedSession.downloadTaskWithURL(mainAddress!, completionHandler: {
        (location:NSURL!, response:NSURLResponse!, error: NSError!) -> Void in



        //using the if statement to avoid crashing when the URL is wrong.
        if error == nil {
            //Now, creating a dataObject for the task:
            let dataObject = NSData(contentsOfURL: location)
            //getting a formated dictionary of the data from URL:
            let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary //added '!' to NSdata for now

        }




    })

    downloadTask.resume()
我在一个修改文件中使用了一个Struct来组织和初始化字典的数据:

import Foundation
import UIKit
import WatchKit
//created the struct just to better organize the data. In the future, if the API keys change, it would be easier to ajust the code, rather than if the data was directly read from the API onto the graph.

struct hourlyData {


///declaring only keys that have Integers as value.
var daylyPop0 : Int
var daylyPop1 : Int
var daylyPop2 : Int
var daylyPop3 : Int
var daylyPop4 : Int



var summaryNowDay : String
var summaryNowNight : String
var iconNow : String
var currentTime: String?

//Initializing the values here. With optional properties:
init(weatherDictionary:NSDictionary){

    daylyPop0 = weatherDictionary["daily0_pop"] as Int
    daylyPop1 = weatherDictionary["daily1_pop"] as Int
    daylyPop2 = weatherDictionary["daily4_pop"] as Int
    daylyPop3 = weatherDictionary["daily3_pop"] as Int
    daylyPop4 = weatherDictionary["daily2_pop"] as Int

}
现在,我正在为它实现一个图表。所以我需要访问字典中的值,以便在图表上实现它们。然而,经过多次尝试后,我一直没有成功。 代码允许我访问hourlyData结构,但不能访问weatherDictionary,因为它是在会话声明中声明的

有人知道一个有效的方法吗


任何提示都将不胜感激,谢谢。

如果让解析字典,您需要使用

尝试以下异步请求:

var request = NSURLRequest(URL: url)
var dict = NSDictionary()

var yourSavedData = hourlyData()

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response, data, error) -> Void in

    if data == nil
    {
        println("Error in connection")
        return
    }

    var error = NSErrorPointer()
    dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary

    if error != nil
    {
        println(error.debugDescription)
        return
    }

    NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in


            if let yourDict = dict as? NSDictionary
            {
                yourSavedData = hourlyData(yourDict!)
            }

        }

    })

没有测试,但应该可以使用。

好的,在你们发布答案后,我对代码进行了一些更新。以下是viewDidLoad的外观:

override func viewDidLoad() {
    super.viewDidLoad()

    ///////getting URL:

    let url = NSURL(string: "http://..........") //for NY
    var request = NSURLRequest(URL: url!)
    var dict = NSDictionary()

    var yourSavedData = hourlyData(weatherDictionary: NSDictionary())

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response, data, error) -> Void in

        if data == nil
        {
            println("Error in connection")
            return
        }

        var error = NSErrorPointer()
        dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: error) as! NSDictionary

        if error != nil
        {
            println(error.debugDescription)
            return
        }

        NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in


            if let yourDict = dict as? NSDictionary
            {
                yourSavedData = hourlyData(weatherDictionary: yourDict)
            }

        }

    })
struct hourlyData {


///declaring only keys that have Integers as value.
var daylyPop0 : Int
var daylyPop1 : Int
var daylyPop2 : Int
var daylyPop3 : Int
var daylyPop4 : Int



var summaryNowDay : String
var summaryNowNight : String
var iconNow : String
var currentTime: String?

//Initializing the values here. With optional properties:
init(weatherDictionary:NSDictionary){

    daylyPop0 = weatherDictionary["hourly10_pop"] as! Int
    daylyPop1 = weatherDictionary["hourly11_pop"] as! Int
    daylyPop2 = weatherDictionary["hourly12_pop"] as! Int
    daylyPop3 = weatherDictionary["hourly13_pop"] as! Int
    daylyPop4 = weatherDictionary["hourly14_pop"] as! Int



    summaryNowDay = weatherDictionary["today_day_fcttext_metric"] as! String
    summaryNowNight = weatherDictionary["today_night_fcttext_metric"] as! String

    iconNow = weatherDictionary["current_icon"] as! String

    let currentTimeIntValue = weatherDictionary["forecast_time"] as! Int
    currentTime = dateStringFromUnixTime(currentTimeIntValue)


}

//Converting unixTime to a desired style:::used ShortStyle in this case:
func dateStringFromUnixTime(unixTime: Int) -> String{

    let timeInSeconds = NSTimeInterval(unixTime)

    let weatherDate = NSDate(timeIntervalSince1970: timeInSeconds)

    let dateFormatter = NSDateFormatter()
    dateFormatter.timeStyle = .ShortStyle

    return dateFormatter.stringFromDate(weatherDate)

}
这是另一个带有Struct的swift文件的外观:

override func viewDidLoad() {
    super.viewDidLoad()

    ///////getting URL:

    let url = NSURL(string: "http://..........") //for NY
    var request = NSURLRequest(URL: url!)
    var dict = NSDictionary()

    var yourSavedData = hourlyData(weatherDictionary: NSDictionary())

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response, data, error) -> Void in

        if data == nil
        {
            println("Error in connection")
            return
        }

        var error = NSErrorPointer()
        dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: error) as! NSDictionary

        if error != nil
        {
            println(error.debugDescription)
            return
        }

        NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in


            if let yourDict = dict as? NSDictionary
            {
                yourSavedData = hourlyData(weatherDictionary: yourDict)
            }

        }

    })
struct hourlyData {


///declaring only keys that have Integers as value.
var daylyPop0 : Int
var daylyPop1 : Int
var daylyPop2 : Int
var daylyPop3 : Int
var daylyPop4 : Int



var summaryNowDay : String
var summaryNowNight : String
var iconNow : String
var currentTime: String?

//Initializing the values here. With optional properties:
init(weatherDictionary:NSDictionary){

    daylyPop0 = weatherDictionary["hourly10_pop"] as! Int
    daylyPop1 = weatherDictionary["hourly11_pop"] as! Int
    daylyPop2 = weatherDictionary["hourly12_pop"] as! Int
    daylyPop3 = weatherDictionary["hourly13_pop"] as! Int
    daylyPop4 = weatherDictionary["hourly14_pop"] as! Int



    summaryNowDay = weatherDictionary["today_day_fcttext_metric"] as! String
    summaryNowNight = weatherDictionary["today_night_fcttext_metric"] as! String

    iconNow = weatherDictionary["current_icon"] as! String

    let currentTimeIntValue = weatherDictionary["forecast_time"] as! Int
    currentTime = dateStringFromUnixTime(currentTimeIntValue)


}

//Converting unixTime to a desired style:::used ShortStyle in this case:
func dateStringFromUnixTime(unixTime: Int) -> String{

    let timeInSeconds = NSTimeInterval(unixTime)

    let weatherDate = NSDate(timeIntervalSince1970: timeInSeconds)

    let dateFormatter = NSDateFormatter()
    dateFormatter.timeStyle = .ShortStyle

    return dateFormatter.stringFromDate(weatherDate)

}
}

现在,代码看起来很好,除了“if let”下的警告之外,它没有显示任何错误,警告是:从“NSDictionary”到“NSDictionary”的条件转换总是成功的。
当我运行模拟器时,它崩溃并显示:致命错误:在展开可选值时意外发现nil。以绿色突出显示代码行:daylyPop0=weatherDictionary[“hourly10_pop”]as!Int

你调用过init方法吗?谢谢你的回答,Dejan。但当我尝试运行它时,会出现一条错误消息:“类型'NSURL'不符合协议'StringLiteralConvertible'”。你知道这意味着什么吗?看来之前的问题已经解决了。但是现在,在“if let”语句中,有一个错误是:从NSDictionary到NSDictionary的条件向下转换总是成功的。Sry仍然存在URL的“StringLiteralConvertible”错误。您似乎正在尝试将字符串转换为Int。您的JSON看起来如何?是的,我以前尝试过这样做。因为JSON的数据都是字符串。现在,它是这样的:当然,您正在向构造函数发送一个空字典,这就是为什么您会得到意外的nil。每当我尝试使用“hourlyData()”时,请使用var yourSavedData=hourlyData();有一条错误消息说:调用中缺少参数“weatherDictionary”的参数。然后添加另一个init,没有参数,并且不分配任何内容,只需添加init(){},很可能您仍然需要分配值,因此将它们分配为空字符串=“或0如果需要int,如果需要的话,解决了此问题。你在这里很有耐心。没问题,如果我有帮助,别忘了对评论/答案投赞成票。