我目前正在研究葡萄酒搜索器应用程序。基本上,我使用食物搭配葡萄酒。用户选择他最喜欢的食物。我有我的火力库数据库,存储标有特定葡萄酒名称和类型的葡萄酒数据。这是我在firebase中的json结构。
Wines:
Wine1:
Name: Catena Zapata Malbec
Type: Bold Red
Wine2:
.......... etc.
我有另一个以前的视图控制器来选择喜欢的食物。例如,如果用户选择红肉,则相关的输入将为“Bold Red”。 所以,我做一个开关盒,例如:1(选择红肉),参考进入“Type”并搜索“Bold Red”,最后打印出该红酒的所有相关结果。
class Wine: NSObject{
var name: String?
var type: String?
var foodChoice: String?
}
class ResultViewController: UITableViewController {
var ref: FIRDatabaseReference!
var refHandle: UInt!
var wineList = [Wine]()
var intPassed: Int!
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Results"
ref = FIRDatabase.database().reference()
fetchWine()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wineList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
cell.textLabel?.text = wineList[indexPath.row].name
return cell
}
func fetchWine(){
switch intPassed {
case 0:
refHandle = ref.child("Wines").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let wine = Wine()
wine.name = dictionary["name"] as! String?
wine.type = dictionary["type"] as! String?
wine.setValuesForKeys(dictionary)
self.wineList.append(wine)
print (wine.name, wine.type)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
case 1:
refHandle = ref.queryOrdered(byChild: "Type").queryEqual(toValue: "Bold Red").observe(.value, with: {(snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let wine = Wine()
wine.name = dictionary["name"] as! String?
wine.setValuesForKeys(dictionary)
self.wineList.append(wine)
print (wine.name)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
default:
print("nothing")
}
}
}
我可以打印案例0的数据。但是如果我想将所选类型的答案与数据库中的类型进行比较,我无法得到我想要的数据。它对refHandle的引用是错误的吗?
以下是针对案例0打印的结果。我只是确保firebase正常工作。其他选项只是我数据库中的其他葡萄酒。
0
Optional("Catena Zapata Malbec") Optional("Bold Red")
Optional("Merlot") Optional("Medium Red")
Optional("Pinot Noir") Optional("Light Red")
请帮忙!非常感谢!!
答案 0 :(得分:1)
我观察到的是refHandle
似乎是正确的。但是你在observe块中访问错误的数据。
案例1中的dictionary
如下:
["Wine1": {
name = "Catena Zapata Malbec";
type = "Bold Red";
}]
这意味着,您需要访问另一个词典,以便在案例1中仅访问您的葡萄酒的名称Catena Zapata Malbec
case 1:
refHandle = ref.queryOrdered(byChild: "Type").queryEqual(toValue: "Bold Red").observe(.value, with: {(snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
// Here access your name of the wine in the node
if let wine1Dictionary = dictionary["Wine1"] as? [String: AnyObject] {
let wine = Wine()
wine.name = wine1Dictionary["name"] as! String?
wine.setValuesForKeys(wine1Dictionary)
self.wineList.append(wine)
print(wine.name)
}
}
})
答案 1 :(得分:0)
让我们用一个结构,代码回答特定类型的葡萄酒和思想。
假设顾客正在吃肉或辛辣的晚餐,并希望有一些葡萄酒选择。他们知道大胆的红色是要走的路
你的葡萄酒结构如下;请记住,应使用childByAutoId()
生成父键wines
wine_id_0
name: "Joseph Phelps Insignia"
type: "Bold Red"
wine_id_1
name: "Heitz Cellers: Martha's Vineyard"
type: "Bold Red"
wine_id_2
name: "Seasmoke Southing"
type: "Fruity Red"
然后我们需要一个类或一个结构在这个案例中,我们可以存储在一个数组中,这个数组是tableView的dataSource,然后是加载葡萄酒时保存葡萄酒的数组。
struct WineStruct {
var key = ""
var name = ""
var type = ""
}
var wineArray = [WineStruct]()
最后,一个详细的代码片段可以读入(在这种情况下)所有的Bold Red葡萄酒。
let wineTypeToQuery = "Bold Red"
let wineRef = ref.child("wines")
let queryRef = wineRef.queryOrdered(byChild: "type")
.queryEqual(toValue: wineTypeToQuery)
queryRef.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! FIRDataSnapshot
let wineDict = snap.value as! [String: Any]
var wine = WineStruct()
wine.name = wineDict["name"] as! String
wine.type = wineDict["type"] as! String
wine.key = snap.key
self.wineArray.append(wine)
}
//here you would call tableView.reloadData()
//do not use DispatchQueue!
for wine in self.wineArray { //print the wines as a test
let aWine = wine as! WineStruct
let name = aWine.name
let type = aWine.type
print("\(name) \(type)")
}
})
和结果输出
Joseph Phelps Insignia Bold Red
Heitz Cellers: Martha's Vineyard Bold Red
此代码将处理加载所有Bold Red葡萄酒以及每个葡萄酒子节点中保存的任何其他相关数据。上面的代码可以大大缩小(约为行数的1/2),但为了便于阅读,我留下了冗长的代码。
一个想法:
您可能想要考虑不同的结构,因为不同的葡萄酒可以搭配不同的食物。
例如:
wines
wine_id_0
name: "Joseph Phelps Insignia"
type: "Bold Red"
pairs_with:
steak: true
ribs: true
wine_id_1
name: "Heitz Cellers: Martha's Vineyard"
type: "Bold Red"
pairs_with:
steak: true
pork: true
wine_id_2
name: "Seasmoke Southing"
type: "Fruity Red"
pairs_with:
cheese: true
fish: true
aromatics:
spicey: true
通过这种结构,我们不会假设顾客知道Bold Red配牛排。他们可以选择牛排'我们以这种方式缩小结果。
当然,您可以进一步完善搜索,因为葡萄酒与肋眼配合得很好(它具有高脂肪含量并且真的需要更高的酒精来切穿它)可能与用Filet配对的葡萄酒不一样
我在最后一款葡萄酒上加入了芳香剂,因为它可以进一步缩小搜索范围 - 如果用户订购的是一种轻便的鱼,那通常可以叫到霞多丽或白苏维浓。然而,如果它以黑色(spicey)风格呈现,那么Pinot通常可以成为赢家。
希望有所帮助!喜欢应用程序概念!