我是Swift的新手 - 尝试从URL读取JSON文件。我的尝试如下。
JSON看起来有效 - 我用JSONLint测试它但它一直崩溃。
思想?
func getRemoteJsonFile() -> NSDictionary {
//Create a new url
let remoteUrl:NSURL? = NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")
//check if its nil
if let actualRemoteUrl = remoteUrl {
//try to get the data
let filedata:NSData? = NSData(contentsOfURL: actualRemoteUrl)
//check if its nil
if let actualFileData = filedata {
//parse out the dictionaries
let jsonDict = NSJSONSerialization.JSONObjectWithData(actualFileData, options: NSJSONReadingOptions.AllowFragments, error: nil) as NSDictionary
return jsonDict
}
}
return NSDictionary()
}
答案 0 :(得分:5)
我花了一秒钟才弄明白,所以我不会责怪你错过它。
您链接的JSON缩小了,因此很难看到结构。在通过a prettifier进行管道后,让我们看一下(片段):
[
{
"PlayerId":2501863,
"PlayerName":"Peyton Manning",
"PlayerTeam":"DEN",
"PlayerPosition":"QB",
"PlayerPassingYards":4727,
"PlayerPassingTDs":39,
"PlayerInterceptions":15,
"PlayerRushingYards":-24,
"PlayerRushingTDs":0,
"PlayerReceivingYards":0,
"PlayerReceivingTDs":0,
"PlayerReturnYards":0,
"PlayerReturnTDs":0,
"PlayerFumbleTDs":0,
"PlayerTwoPointConversions":2,
"PlayerFumblesLost":2,
"PlayerTeamLogo":"http://i.nflcdn.com/static/site/7.0/img/logos/teams-gloss-81x54/den.png"
}
]
咦。它被括在括号中,这意味着它是一个数组。
它是一个数组,因此您无法将其转换为NSDictionary
。相反,您可以将其转换为NSArray
,但为什么不使用原生的Swift类型?
好吧,如果你不喜欢类型,你就要发现了,但我仍然认为这是一种更好的方法,因为它会迫使你思考你所依赖的数据。解析。
所以我们有这个函数的类型定义的第一部分;它是一个数组([]
)。我们的阵列由哪些组件组成?我们可以使用简单的NSDictionary
,但我们在此处执行完整的原生类型,因此请使用a native Swift dictionary。
为此,我们必须知道字典的类型(本地字典类型的语法是[KeyType: ValueType]
)。检查JSON显示所有键都是String
个,但值的类型各不相同,因此我们可以使用AnyObject
。
这给了我们一个[String: AnyObject]
的字典类型,我们的整个JSON是一个数组,所以最后的类型是[[String: AnyObject]]
(哇)。
现在我们有了正确的类型,我们可以修改你用来解析JSON的函数。
首先,让我们使用我们的新类型作为返回值和强制转换值。然后,让我们在出现问题时生成返回类型optional并添加error
变量来记录该内容。
清理过的功能看起来像这样:
func getData() -> [[String: AnyObject]]? {
let data: NSData? = NSData(contentsOfURL: NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")!)
if let req: NSData = data {
var error: NSError?
if let JSON: [[String: AnyObject]] = NSJSONSerialization.JSONObjectWithData(req, options: NSJSONReadingOptions.AllowFragments, error: &error) as? [[String: AnyObject]] {
return JSON
}
}
return nil
}
那就是它!
我们现在可以调用函数并从[[String: AnyObject]]
(再次,哇)中提取值,如下所示:
if let data: [[String: AnyObject]] = getData() {
println(data[0]["PlayerName"]!) // Peyton Manning
}
答案 1 :(得分:0)
使用以下代码更新您的代码:
func getRemoteJsonFile() -> [NSDictionary] {
// Create a new URL
let remoteUrl:NSURL? = NSURL(string: "http://nfl-api.azurewebsites.net/myplayers.json")
let urlString:String = "\(remoteUrl)"
// Check if it's nil
if let actualRemoteUrl = remoteUrl {
// Try to get the data
let fileData:NSData? = NSData(contentsOfURL: actualRemoteUrl)
// Check if it's nil
if let actualFileData = fileData {
// Parse out the dictionaries
let arrayOfDictionaries:[NSDictionary]? = NSJSONSerialization.JSONObjectWithData(actualFileData, options: NSJSONReadingOptions.MutableContainers, error: nil) as [NSDictionary]?
if let actualArrayOfDictionaries = arrayOfDictionaries {
// Successfully parsed out array of dictionaries
return actualArrayOfDictionaries
}
}
}
return [NSDictionary]()
}
这对我来说很好。