如何在 Swift 的方法之外访问字典数据?
How to access dictionary data outside its method on Swift?
我正在使用 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()
我在一个不同的文件中使用了一个结构来组织和初始化字典的数据:
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,因为它是在会话声明中声明的。
有人知道有效的方法吗?
如有任何提示,我们将不胜感激。
你需要使用if let来解析字典。
试试这个异步请求:
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)
}
}
})
这就是另一个 swift 结构文件的样子:
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!整数
我正在使用 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()
我在一个不同的文件中使用了一个结构来组织和初始化字典的数据:
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,因为它是在会话声明中声明的。
有人知道有效的方法吗?
如有任何提示,我们将不胜感激。
你需要使用if let来解析字典。
试试这个异步请求:
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)
}
}
})
这就是另一个 swift 结构文件的样子:
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!整数