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

Swift实现JSON日期与计数加载至FSCalendar事件数组

解决FSCalendar关联JSON日期与事件计数的问题

我来帮你一步步搞定这个问题,核心是要快速匹配日期对应的count值,同时保证日期格式的一致性,避免因为格式不匹配导致找不到对应数据。

1. 优化数据存储结构

你现在用[Cdata]数组存储数据,每次代理方法调用都遍历数组会影响性能,建议新增一个字典来做映射,把日期字符串作为key,count作为value,这样查找起来是O(1)的速度:

// 全局变量
var calendarsData = [Cdata]()
// 新增:日期字符串到count的映射字典
var dateCountMap = [String: Int]()

2. 统一日期格式化

一定要保证JSON里的日期格式和你把Date转成字符串的格式完全一致!你的JSON日期是"23-09-2019"(日-月-年),所以你的dateFormatter必须和这个格式对应,先定义好全局的日期格式化器:

let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    // 注意和JSON的日期格式完全匹配:日-月-年,两位数的日/月,四位数的年
    formatter.dateFormat = "dd-MM-yyyy"
    formatter.locale = Locale(identifier: "en_US_POSIX") // 避免区域设置影响格式
    return formatter
}()

3. 修正JSON加载逻辑,填充映射字典

在你解析完JSON后,不仅要赋值calendarsData,还要把数据填充到dateCountMap里,同时记得刷新日历:

// MARK: JSON Data Load - Calendar Data
func loadCalendarsJSON(){
    let urlPath = "https://api.myjson.com/bins/9gq0h"
    guard let url = URL(string: urlPath) else {
        print("Invalid URL")
        return
    }
    let session = URLSession.shared
    let task = session.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else {
            print(error?.localizedDescription ?? "Unknown error")
            return
        }
        do {
            let decoder = JSONDecoder()
            let calendarResponse = try decoder.decode(Calendars.self, from: data)
            if calendarResponse.status {
                self.calendarsData = calendarResponse.data
                // 填充映射字典:遍历data数组,把日期作为key,count作为value
                self.dateCountMap = Dictionary(uniqueKeysWithValues: calendarResponse.data.map { ($0.date, $0.count) })
                DispatchQueue.main.async {
                    self.calendar.reloadData() // 必须刷新日历,不然新数据不会生效
                }
            }
        } catch {
            print("JSON解码错误:\(error)")
        }
    }
    task.resume()
}

4. 修改FSCalendar代理方法,返回正确的count值

现在代理方法里就可以直接通过字典快速查找对应的count了,不用再遍历数组:

// MARK Calendar Data Fetch
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
    let dateString = self.dateFormatter.string(from: date)
    // 从字典里取对应count,找不到就返回0
    return dateCountMap[dateString] ?? 0
}

额外注意点

  • 确保你的dateFormatter是全局的,不要在代理方法里每次创建,不然会影响性能。
  • 测试的时候要注意日期格式的一致性,比如JSON里的日期是"23-09-2019",你的格式化器必须用dd-MM-yyyy,如果不小心写成MM-dd-yyyy就会匹配失败。
  • 如果JSON里的日期格式可能有变化,要和后端确认固定的格式,或者处理多种格式的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:06:21