You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发:Firebase数据按用户选择的eventTiming排序问题

Firebase事件数据按时间字符串排序失效的解决方法

问题核心

直接用eventTiming字符串(如"6:00 AM"、"9:00 AM")调用sort(by: {$0.eventTiming > $1.eventTiming})是按字符串字典序排序,而非时间顺序。比如字符串"9:00 AM"会比"6:00 AM"更靠前,因为字符'9'的ASCII码大于'6',导致排序结果不符合 chronological 要求。同时现有代码还存在变量名错误,影响逻辑执行。

现有代码问题点

  • 排序时机错误:循环内部每次添加元素后就排序,重复操作浪费性能,应在所有元素填充完成后统一排序
  • 排序逻辑错误:字符串字典序≠时间顺序,无法实现按时间先后排序
  • 变量名错误:代码中workoutsObject应为eventsObject,eventInDepth.key应为eventsFirebase.key,这些错误会导致数据解析失败或崩溃

优化方案

1. 时间字符串转Date类型排序

通过DateFormatter将eventTiming字符串转换为Date对象,利用Date的时间先后特性实现正确排序。

2. 修正代码错误并调整排序时机

先完成所有数据的解析和数组填充,再统一执行排序操作,同时修复变量名错误。

完整修正代码

// 提前初始化DateFormatter,避免重复创建损耗性能
let timeFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mm a"
    // 设置locale确保AM/PM格式在不同地区设备上都能正确解析
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
}()

func fetchData(for date: String) {
    guard let userId = Auth.auth().currentUser?.uid else { return }

    let journalRef = Database.database().reference().child("\(userId)/Events")
    journalRef.removeAllObservers()
    
    self.databaseRef = journalRef.child(date)
    self.databaseRef.observe(.value, with: { [weak self] snapshot in
        guard let self = self else { return }
        self.events.removeAll()
        
        guard snapshot.childrenCount > 0 else {
            self.eventsList.reloadData()
            return
        }
        
        for eventSnapshot in snapshot.children.allObjects as! [DataSnapshot] {
            guard let eventObject = eventSnapshot.value as? [String: AnyObject],
                  let eventTitle = eventObject["eventTitle"] as? String,
                  let eventDay = eventObject["eventDay"] as? String,
                  let eventTiming = eventObject["eventTiming"] as? String else {
                continue
            }
            
            let event = EventInformation(id: eventSnapshot.key, eventDay: eventDay, eventTiming: eventTiming, eventTitle: eventTitle)
            self.events.append(event)
        }
        
        // 所有元素添加完成后,按时间顺序排序
        self.events.sort { event1, event2 in
            guard let date1 = timeFormatter.date(from: event1.eventTiming),
                  let date2 = timeFormatter.date(from: event2.eventTiming) else {
                // 时间解析失败时,按原字符串兜底排序
                return event1.eventTiming < event2.eventTiming
            }
            return date1 < date2
        }
        
        self.eventsList.reloadData()
    })
}

额外注意事项

  • DateFormatter建议提前初始化,不要在排序闭包内重复创建
  • 如果存在时间格式不规范导致解析失败的情况,可根据需求调整兜底逻辑(如将异常数据放在数组末尾)

内容的提问来源于stack exchange,提问作者codingIOSAndroid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:40:27