使用Swift从Firebase获取nil值

时间:2018-04-30 13:28:30

标签: json swift database firebase

我已经尝试了五天,但没有运气。

以下是我的Firebase快照:

Snap (Channels) {
    HiruFM =     {
        image = "hiru_fm_logo.png";
        title = "Hiru FM";
    };
    SirasaFM =     {
        image = "sirasa_fm_logo.png";
        title = SirasaFM;
    };
}

以下是我的尝试:

override func viewDidLoad() {
    super.viewDidLoad()

    ref = Database.database().reference().child("Channels")

    ref.observeSingleEvent(of: .value) { (snap) in
        print(snap) // checking if the snap grabs the data (confirmed)
        guard var data = snap.value as? Dictionary<String, Any> else {return}


        let channeTitle = data["title"] as? String ?? "No title"
        print(channeTitle) // prints "No title" (this is the problem)

        let channelImage = data["image"] as? String ?? "No image"
        print(channelImage) // prints "No image"
        let myData = Channels(title: channeTitle, image: channelImage)
        self.channels.append(myData)
    }
}

2 个答案:

答案 0 :(得分:0)

我认为你应该尝试一下

for imageData in data
{
    let item:NSDictionary = imageData as NSDictionary
    let channeTitle = data["title"] as? String ?? "No title"
    print(channeTitle)
    let channelImage = data["image"] as? String ?? "No image"
    print(channelImage) 
    let myData = Channels(title: channeTitle, image: channelImage)
    self.channels.append(myData)
}

这里如果你需要首先获取字典字典的数据,你需要获取每个数据然后循环它们的子节点数据。

答案 1 :(得分:0)

了解通过.value和.childAdded读取节点之间的区别非常重要,另一个考虑因素是将父节点键与其包含的数据分离。

从以下结构开始

channels
  chan_0
    image: "hiru_fm_logo.png"
    name: "HiruFM"
    title "Hiru FM"
  chan_1
    image: "sirasa_fm_logo.png"
    name: "SirasaFM"
    title "Sirasa FM"
使用childbyAutoId创建

chan_0,chan_1等密钥,并允许将密钥与子数据分开。这样,如果其中一个子值发生更改,它将保持父节点与引用它的其他节点之间的完整性。实际上,如果HiruFM成为HiruXM,那么所有需要做的就是改变子节点,而不是父节点。

然后是一个用来保存数据的结构。请注意,结构 init 会分解快照并分配属性

struct ChannelStruct{
    var image = ""
    var title = ""
    var name = ""

    init(aSnap: DataSnapshot) {
        let dict = aSnap.value as! [String: Any]

        if let image = dict["image"] as? String {
            self.image = image
        }

        if let title = dict["title"] as? String {
            self.title = title
        }

        if let name = dict["name"] as? String {
            self.name = name
        }
    }
}

和一个用于保存结构的类数组

var channels = [ChannelStruct]()

然后最后在节点中读取代码并迭代子节点以将它们添加到数组中

ref = Database.database().reference().child("channels")
ref.observeSingleEvent(of: .value) { snapshot in
    if snapshot.exists() {
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let aChannel = ChannelStruct(aSnap: snap)
            self.channels.append(aChannel)
        }
    } else {
        print("no channels found")
    }
}

请注意,当通过.value读取父节点 channels 时,会读入所有子节点,因此需要迭代它们以获取每个子节点 - 这也维护它们的顺序。然而,如果我们使用.childAdded,它会一次呈现一个子节点,因此不需要迭代。