Swift:无法使用类型为“([Idea],来自:Data)”的参数列表调用“解码”

Posted

技术标签:

【中文标题】Swift:无法使用类型为“([Idea],来自:Data)”的参数列表调用“解码”【英文标题】:Swift: Cannot invoke 'decode' with an argument list of type '([Idea], from: Data)' 【发布时间】:2019-07-03 23:28:11 【问题描述】:

我一直在尝试为我正在开发的应用程序找出最佳的数据持久性解决方案,我认为本地存储的 JSON 文件将是简单性和功能性的最佳平衡。

我需要保存的是一组自定义结构,我可以使用下面的代码很好地编写它,但是我无法将其解码回来,我收到了这个错误:

无法使用类型为 '([Idea], 的参数列表来自: 数据)'

知道是什么原因造成的吗?想法数组本身是否应该是可编码的?编码它不应该工作,对吧?我做错了什么吗?

任何建议将不胜感激。

var ideas = [Idea]()

--

struct Idea: Codable 
    var title: String
    var description: String?
    var date: String
    var completed: Bool

--

func writeIdeasToJSON()
    let pathDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    try? FileManager().createDirectory(at: pathDirectory, withIntermediateDirectories: true)
    let filePath = pathDirectory.appendingPathComponent("data.json")

    let json = try? JSONEncoder().encode(ideas)

    do 
        try json!.write(to: filePath)
     catch 
        print("Failed to write JSON data: \(error.localizedDescription)")
    

--

func readIdeasFromJSON()
    do 
        let path = Bundle.main.path(forResource: "data", ofType: "json")
        let jsonData = try Data(contentsOf: URL(fileURLWithPath: path!))

        do 
            let readIdeas = try JSONDecoder().decode(ideas.self, from: jsonData)
            print(readIdeas)
         catch let error
            print(error.localizedDescription)
        
     catch let error 
        print(error.localizedDescription)
    

【问题讨论】:

试试[Idea].self 而不是ideas.self 感谢@rmaddy,但这会导致崩溃,仅显示“在展开可选值时意外发现 nil”而没有其他详细信息。 那是因为它修复了编译器错误,现在你得到一个完全不相关的运行时错误。 jsonData 很可能是 nil,因为您的文件实际上不在应用程序的资源包中。这是有道理的,因为您将文件写入了 Documents 文件夹。两个完全不同的地方。 使用与保存时相同的代码获取路径。 详情见我的回答。 【参考方案1】:

你有两个问题。首先是编译器错误来自:

let readIdeas = try JSONDecoder().decode(ideas.self, from: jsonData)

应该是这样的:

let readIdeas = try JSONDecoder().decode([Idea].self, from: jsonData)

修复此问题后,您会收到运行时错误,因为您将文件写入 Documents 文件夹,但您尝试从应用程序的资源包中读取它。

更新您的加载代码以使用与保存文件相同的路径:

func readIdeasFromJSON()
    do 
        let pathDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let filePath = pathDirectory.appendingPathComponent("data.json")

        let jsonData = try Data(contentsOf: filePath)
        let readIdeas = try JSONDecoder().decode([Idea].self, from: jsonData)
        print(readIdeas)
     catch 
        print(error)
    

【讨论】:

成功了,非常感谢。尽管正如您之前指出的那样,它是 [Idea]。你介意我问为什么吗?我以为我正在解码数组本身。那是我编码的。 解码时完全不使用ideas变量。您必须告诉decode 要解码的类型。您没有将其传递给变量。如果有的话,您可能使用过ideas = try JSONDecoder().decode([Idea].self, from: jsonData) 我明白了。再次感谢您的澄清和帮助。 如果我可以再问一件事:有没有办法让函数也接受其他类型的对象?所以想法,目标等。我尝试传递一个参数对象:[Any],但随后我得到了与之前相同的错误无法调用'解码'.. 谢谢,但是已经有一些重复的问题,其中包含一两个我不理解的答案,我不想再创建另一个。我只会做一个丑陋的 if 语句(我只有 3 种类型),稍后当我更好地理解泛型时再重新审视它。

以上是关于Swift:无法使用类型为“([Idea],来自:Data)”的参数列表调用“解码”的主要内容,如果未能解决你的问题,请参考以下文章

Swift:在使用过滤器函数进行过滤后,调用 indexOf 时无法将类型的值转换为 @noescape

Swift - 无法使用“IndexPath”类型的索引为“[Array<String>]”类型的值下标

SWIFT 4.1 无法使用类型为“(字符串?)”的参数列表调用类型“Double”的初始化程序

无法为类型 Unsafepointer Swift 3.0 转换初始化变量

无法将类型值转换为 UINavigationController swift3

尝试修复 Swift 3 错误;无法使用“String”类型的索引为“[[String:AnyObject]]”类型的值下标[关闭]