从字典键中提取值 - 然后合并到一个对象中

时间:2017-10-26 14:22:32

标签: json swift dictionary

我有一个JSON响应,我已经在Swift中解析为[String:Any]的单个字典集。我正在尝试检查每个键的值,然后将该值添加为传递给SteamFriend对象的变量。

for (key, value) in level3 {
    var avatar:URL!
    var personaname:String = ""
    var personastate:Int = 0
    var steamid:String = ""

    if key == "avatar" {
        if let avatarAsString = value as? String {
            let avatarAsURL = URL(string: avatarAsString)
            avatar = avatarAsURL
        }
    } else if key == "personaname" {
        if let personanameAsString = value as? String {
            personaname = personanameAsString
        }
    } else if key == "personastate" {
        if let personastateAsInt = value as? Int {
            personastate = personastateAsInt
        }
    } else if key == "steamid" {
        if let steamidAsString = value as? String {
            steamid = steamidAsString
        }
    }

    let createSteamFriend = SteamFriend(avatar: avatar, personaname: 
    personaname, personastate: personastate, steamid: steamid)
}

并且SteamFriend的类是

class SteamFriend {
var avatar: URL
var personaname: String
var personastate: Int
var steamid: String

init (avatar:URL, personaname:String, personastate: Int, steamid:String) {
    self.avatar = avatar
    self.personaname = personaname
    self.personastate = personastate
    self.steamid = steamid
}

}

当我运行上面的代码时,我立即在createSteamFriend行上出现错误,指出“在解开对象时意外发现了nil”。我已经针对上面的每个可选演员运行了一个print语句,我知道它们都是返回的值。

我确信我的代码逻辑存在缺陷。我不能为我的生活找出创建SteamFriend对象的正确方法。

3 个答案:

答案 0 :(得分:1)

问题是您重新声明每个循环中的变量,因此除非在上一次迭代中找到键nil,否则URL为avatar

无论如何,这是枚举字典的一种非常麻烦的方法,只需直接获取键的值而不需要循环:

var avatar: URL!

if let avatarAsString = level3["avatar"] as? String {
    let avatarAsURL = URL(string: avatarAsString)
    avatar = avatarAsURL
}
let personaname = level3["personaname"] as? String ?? ""
let personastate = level3["personastate"] as? Int ?? 0
let steamid = level3["steamid"] as? String ? ""

let createSteamFriend = SteamFriend(avatar: avatar, personaname: 
personaname, personastate: personastate, steamid: steamid)

如果初始化程序中的avatar参数是必需的(非可选类型),我甚至会写

guard let avatarAsString = level3["avatar"] as? String else { 
  // show an error message
  return
}
let avatar = URL(string: avatarAsString)!

答案 1 :(得分:0)

您正在循环中为每个元素重置变量。 所以,一旦你找到“头像”,你就设置了你的URL。下一个元素,您将头像重置为URL!。 放置变量,让createSteamFriend在循环之外。

var avatar:URL!
var personaname:String = ""
var personastate:Int = 0
var steamid:String = ""

for (key, value) in level3 {

if key == "avatar" {
    if let avatarAsString = value as? String {
        let avatarAsURL = URL(string: avatarAsString)
        avatar = avatarAsURL
    }
} else if key == "personaname" {
    if let personanameAsString = value as? String {
        personaname = personanameAsString
    }
} else if key == "personastate" {
    if let personastateAsInt = value as? Int {
        personastate = personastateAsInt
    }
} else if key == "steamid" {
    if let steamidAsString = value as? String {
        steamid = steamidAsString
    }
}

}
let createSteamFriend = SteamFriend(avatar: avatar, personaname: 
personaname, personastate: personastate, steamid: steamid)

答案 2 :(得分:0)

基本上,您的avatar为零,因为您正在创建createSteamFriend实例四次,而且值一次只能单独出现。

如果您获得一个字典,为什么要运行循环?尝试直接从字典中获取值不要使用循环和不必要的if else条件。

var avatar = URL()

if let avatarAsString = level3["avatar"] as? String {
    let avatarAsURL = URL(string: avatarAsString)
    avatar = avatarAsURL
}
let personaname = level3["personaname"] as? String
let personastate = level3["personastate"] as? Int 
let steamid = level3["steamid"] as? String 

let createSteamFriend = SteamFriend(avatar: avatar, personaname: 
            personaname, personastate: personastate, steamid: steamid)