Firestore getDocuments闭包报错:同逻辑代码为何一处正常?
解决Firestore getDocuments闭包错误:“Trailing closure passed to parameter of type 'FirestoreSource' that does not accept a closure”
问题原因
两段代码表现不同的核心原因是Swift编译器的类型推断错误:
- 在
MedicineViewModel的闭包内部,初始化Medicine时直接传递了未做类型转换的Firestore字段值(如d["name"]),这些值的类型是Any?,但Medicine的初始化参数大概率是具体类型(如String、Int等)。编译器无法推断这些参数的类型,进而影响到外层getDocuments方法的重载匹配,错误地将尾随闭包绑定到了需要FirestoreSource类型参数的重载版本上,导致报错。 - 而
UserViewModel中初始化User时,对每个字段都做了明确的类型转换(如d["email"] as? String ?? ""),编译器能清晰推断类型,因此正确匹配了接受闭包作为completion参数的getDocuments重载。
解决方案
有两种可行的解决方式:
方式一:修复Medicine初始化的类型转换
给每个Medicine初始化参数添加明确的类型转换和默认值,和User的初始化逻辑保持一致:
self.medicines.append(Medicine( id: d.id, name: d["name"] as? String ?? "", prescription: d["prescription"] as? String ?? "", number: d["number"] as? Int ?? 0, taken: d["taken"] as? Bool ?? false ))
(注意:需根据Medicine结构体的实际字段类型调整转换逻辑,比如number如果是字符串类型,就换成对应的String类型转换)
方式二:显式指定completion参数标签
在调用getDocuments时,显式标注completion参数,避免编译器匹配错误的重载:
collectionMedicine.getDocuments(completion: { snapshot, error in // 原有闭包逻辑 })
两种方式都能解决问题,推荐方式一,因为它同时修复了类型安全问题,避免后续潜在的运行时错误。
内容的提问来源于stack exchange,提问作者Jude
相关产品推荐
相关产品推荐

