Swift中从Firestore Storage下载JSON文件时NSData初始化报错如何解决?
解决Firestore Storage下载JSON时NSData初始化报错问题
问题场景
编写了从Firestore Storage的urlLink下载JSON文件的函数,但NSData初始化行提示No exact matches in call to initializer错误,原代码如下:
func chargerLObjetDeFirestore(urlLink: String, completion: @escaping (_ menuObject: MenuObjectPartager?) -> Void) { if urlLink != "" { let documentUrl = URL(string: urlLink) let data = NSData(contentof: documentUrl!) //No exact matches in call to initializer if data != nil { // decoding the data loaded let loadedMenu: MenuObjectPartager = try data.decodedObject() completion(loadedMenu) } else { print("@@No document found in urlLink") completion(nil) } } }
问题原因及解决步骤
- 初始化方法拼写错误:NSData的正确初始化方法是
contentsOf:,你写的contentof:少了一个s,且参数名大小写错误,这是直接触发报错的原因。 - 同步方法需处理异常:
contentsOf:是同步方法且会抛出错误,不能直接调用,必须结合do-catch或try?处理异常。 - 避免强制解包风险:
URL(string:)可能返回nil,直接用!强制解包会引发崩溃,应先判断URL有效性。 - 优先用Swift原生类型:现代Swift开发更推荐使用
Data而非NSData,API更简洁且符合Swift风格。
修正后的代码
func chargerLObjetDeFirestore(urlLink: String, completion: @escaping (_ menuObject: MenuObjectPartager?) -> Void) { guard !urlLink.isEmpty, let documentUrl = URL(string: urlLink) else { print("@@Invalid URL or empty link") completion(nil) return } // 放到后台队列执行,避免阻塞主线程 DispatchQueue.global().async { do { let data = try Data(contentsOf: documentUrl) // 若使用自定义decodedObject方法,确保它正确处理错误抛出 let loadedMenu = try data.decodedObject() as MenuObjectPartager DispatchQueue.main.async { completion(loadedMenu) } } catch { DispatchQueue.main.async { print("@@Error loading or decoding data: \(error.localizedDescription)") completion(nil) } } } }
补充说明
如果你的decodedObject()不是自定义方法,而是用系统JSONDecoder解码,可替换为标准逻辑:
let decoder = JSONDecoder() let loadedMenu = try decoder.decode(MenuObjectPartager.self, from: data)
内容的提问来源于stack exchange,提问作者Christine
相关产品推荐
相关产品推荐

