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

Swift中使用MessageKit与Firebase获取消息日期时遇「Cannot call value of non-function type 'String'」错误的技术咨询

问题分析与解决方案

看起来你遇到的核心问题是对getFormatter的设计和使用完全错位了——你把它定义成了一个返回当前时间字符串的计算属性,但却试图把它当成解析日期字符串的方法来调用,这就导致了「Cannot call value of non-function type 'String'」的错误。

错误根源拆解

  1. 你定义的getFormatter是一个静态计算属性,它的作用是生成当前时间的格式化字符串,而不是接收一个字符串并解析成Date:
    public static var getFormatter: String{
        let dformatter = DateFormatter()
        dformatter.dateFormat = "dd/MM/yyy HH:mm" // 这里还少了一个y,应该是yyyy
        let dateToString = dformatter.string(from: Date())
        return dateToString
    }
    
  2. 但你在Networking类里却用方法调用的方式传参:ChatDashboard.getFormatter(from: dateString),这显然和属性的定义冲突。

修复步骤与代码调整

1. 重构ChatDashboard的日期格式化工具

我们需要把getFormatter改成返回DateFormatter实例的静态属性,这样才能用来解析数据库里的日期字符串:

// 重命名为更语义化的dateFormatter,避免混淆
public static var dateFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd/MM/yyyy HH:mm" // 修正格式,补全yyyy
    formatter.locale = Locale(identifier: "en_US_POSIX") // 强制使用固定本地化,避免解析失败
    return formatter
}

2. 修正Networking类中的消息解析逻辑

现在可以用这个dateFormatter来解析数据库里的dateString,同时修复Message初始化时的参数错误:

func getAllMessagesForConverstion(id: String, completion: @escaping(Result<[Message], Error>) -> Void) {
    checkMessageUSer(id) { (user) in
        guard let users = user else {
            print("not getting the users sorry on getAllMessage")
            return
        }
        let messages: [Message] = users.compactMap({ dic in
            guard let content = dic["content"] as? String,
                  let dateString = dic["date"] as? String,
                  let messageId = dic["id"] as? String,
                  let isRead = dic["is_read"] as? String, // 如果数据库里是布尔值,建议转成Bool
                  let senderEmail = dic["sender_email"] as? String,
                  let typeMessage = dic["type"] as? String,
                  let name = dic["name"] as? String,
                  // 使用dateFormatter解析字符串为Date
                  let sentDate = ChatDashboard.dateFormatter.date(from: dateString) else {
                return nil
            }
            let senderData = Sender(photo: "", senderId: senderEmail, displayName: name)
            // sentDate传入解析后的Date对象,而非空字符串
            return Message(sender: senderData, messageId: messageId, sentDate: sentDate, kind: .text(content))
        })
        // 别忘了调用completion返回结果,原代码遗漏了这一步
        completion(.success(messages))
    }
}

额外注意事项

  • 确保数据库中存储的日期字符串格式,和dateFormatter.dateFormat完全一致,否则解析会返回nil;
  • 如果is_read字段在数据库中是布尔类型,建议把代码里的as? String改成as? Bool,更符合业务逻辑;
  • 复用DateFormatter实例(比如我们定义的静态属性)比每次创建新实例性能更好,尤其是在循环解析大量消息时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:32:28