我试图从Firebase
中提取很多变量。并非所有这些都有任何内容。因此,我需要能够处理nil并同时转换为所需的数据类型(例如,Float和Int)
目前我在第一个Float“距离”上遇到错误:
“主题1:致命错误:在解开可选值时意外发现nil
几个问题:
如何使Float转换处理潜在的无案例
我想将Float存储为Firebase中的字符串,而不是将其包装在NSNumber中。你同意吗?
如果在应用程序中我只需要例如。以下5个变量,我是否应该对此进行特定查询 - 或者通常不需要花费很多成本来获取所有变量?
我是否正确制作了数组或地图(字典)元素(例如,like,comments,imageURL)?
代码:
// Get data on all activities
func getAllFeedActivities(handler: @escaping (_ activities: [Activity]) -> (Void)) {
var activityArray = [Activity]()
REF_ACTIVITY.observeSingleEvent(of: .value) { (feedActivitySnapshot) in
guard let feedActivitySnapshot = feedActivitySnapshot.children.allObjects as? [DataSnapshot] else { return }
for activity in feedActivitySnapshot {
let activityId = activity.key as String
let name = activity.childSnapshot(forPath: "name").value as? String ?? ""
let description = activity.childSnapshot(forPath: "description").value as? String ?? ""
let userId = activity.childSnapshot(forPath: "userId").value as? String ?? ""
let type = activity.childSnapshot(forPath: "type").value as? String ?? ""
let gearId = activity.childSnapshot(forPath: "gearId").value as? String ?? ""
let distance = Float(activity.childSnapshot(forPath: "distance").value as? String ?? "") as! Float // In meters
let totalElevationGain = Float(activity.childSnapshot(forPath: "totalElevationGain").value as? String ?? "") as! Float // In meters
let elevationHigh = Float(activity.childSnapshot(forPath: "elevationHigh").value as? String ?? "") as! Float // In meters
let elevationLow = Float(activity.childSnapshot(forPath: "elevationLow").value as? String ?? "") as! Float // In meters
let startTime = activity.childSnapshot(forPath: "startTime").value as? String ?? "" // Unix time - seconds
let timeZone = activity.childSnapshot(forPath: "timeZone").value as? String ?? ""
let movingTime = Int(activity.childSnapshot(forPath: "movingTime").value as? String ?? "") as! Int // In seconds
let elapsedTime = Int(activity.childSnapshot(forPath: "elapsedTime").value as? String ?? "") as! Int // In seconds
let likeCount = Int(activity.childSnapshot(forPath: "likeCount").value as? String ?? "") as! Int
let likes = activity.childSnapshot(forPath: "likes").value as? NSArray ?? [""]
let commentCount = Int(activity.childSnapshot(forPath: "commentCount").value as? String ?? "") as! Int
let comments = activity.childSnapshot(forPath: "comments").value as? NSArray ?? [""]
let imageCount = Int(activity.childSnapshot(forPath: "imageCount").value as? String ?? "") as! Int
let imageURLs = activity.childSnapshot(forPath: "imageURLs").value as? NSArray ?? [""]
let defaultImageURL = activity.childSnapshot(forPath: "defaultImageURL").value as? String ?? ""
let activity = Activity(activityId: activityId, name: name, description: description, userId: userId, type: type, gearId: gearId, distance: distance, totalElevationGain: totalElevationGain, elevationHigh: elevationHigh, elevationLow: elevationLow, startTime: startTime, timeZone: timeZone, movingTime: movingTime, elapsedTime: elapsedTime, likeCount: likeCount, likes: likes as! Array<String>, commentCount: commentCount, comments: comments as! Array<String>, imageCount: imageCount, imageURLs: imageURLs as! [String], defaultImageURL: defaultImageURL)
activityArray.append(activity)
}
handler(activityArray)
}
}
答案 0 :(得分:2)
1)如果要分配默认值,则该值应为
String
使用.value as? String ?? ""
Int
使用.value as? Int ?? 0
Float
使用.value as? Float ?? 0.0
Double
使用.value as? Double ?? 0.0
Bool
使用.value as? Bool ?? false
Array
使用.value as? [String] ?? []
//其中String
必须是预期的数据类型Dictionary
使用.value as? [String:Any] ?? [:]
如果是Array
和Dictionary
,则必须在未声明之前注释该类型
let imageURLs : [String] = ...
但是我建议使用数据库中已有的默认值声明属性,然后值永远不会为nil,您可以强制解包它们。
您的其他问题的答案:
2)不,始终使用合适的类型。
3)是的,一个特定的查询更有效,总是处理所有值更昂贵。
4)参见1) - 不要在Swift中使用NSArray / NSDictionary
。