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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:15:47