复杂的firebase读取查询 - String,Float,Int和NSArray

时间:2018-01-20 14:18:27

标签: swift firebase firebase-realtime-database

我试图从Firebase中提取很多变量。并非所有这些都有任何内容。因此,我需要能够处理nil并同时转换为所需的数据类型(例如,Float和Int)

目前我在第一个Float“距离”上遇到错误:

  

“主题1:致命错误:在解开可选值时意外发现nil

几个问题:

  1. 如何使Float转换处理潜在的无案例

  2. 我想将Float存储为Firebase中的字符串,而不是将其包装在NSNumber中。你同意吗?

  3. 如果在应用程序中我只需要例如。以下5个变量,我是否应该对此进行特定查询 - 或者通常不需要花费很多成本来获取所有变量?

  4. 我是否正确制作了数组或地图(字典)元素(例如,like,comments,imageURL)?

  5. 代码:

        // 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)
            }
        }
    

1 个答案:

答案 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] ?? [:]

如果是ArrayDictionary,则必须在未声明之前注释该类型

let imageURLs : [String] = ...

但是我建议使用数据库中已有的默认值声明属性,然后值永远不会为nil,您可以强制解包它们。

您的其他问题的答案:

2)不,始终使用合适的类型。

3)是的,一个特定的查询更有效,总是处理所有值更昂贵。

4)参见1) - 不要在Swift中使用NSArray / NSDictionary