Swift中使用MessageKit与Firebase获取消息日期时遇「Cannot call value of non-function type 'String'」错误的技术咨询
问题分析与解决方案
看起来你遇到的核心问题是对getFormatter的设计和使用完全错位了——你把它定义成了一个返回当前时间字符串的计算属性,但却试图把它当成解析日期字符串的方法来调用,这就导致了「Cannot call value of non-function type 'String'」的错误。
错误根源拆解
- 你定义的
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 } - 但你在
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
相关产品推荐
相关产品推荐

