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
相关产品推荐
相关产品推荐

