如何用Codable类型定义变量?

问题描述:

我想创建类型为的变量Codable。稍后在JSONEncoder类中使用它。我想从下面的代码应该可以正常工作,但它给我的错误:如何用Codable类型定义变量?

Cannot invoke encode with an argument list of type (Codable) .

如何声明可编码的变量JSONEncoder将采取无错?

struct Me: Codable { 
    let id: Int 
    let name: String 
} 

var codable: Codable? // It must be generic type, but not Me. 

codable = Me(id: 1, name: "Kobra") 

let data = try? JSONEncoder().encode(codable!) 

Here是类似的问题,如何使用功能通过可编码的。但我正在寻找如何使用变量(类变量)设置Codable。

+0

使用'任何'不''Codable' –

+0

@LeoDabus然后另一个问题如何将其传递给JSONEncoder? – Ramis

+1

使用'Me'有什么不对? –

我创建了相同的情况你:

struct Me: Codable 
{ 
    let id: Int 
    let name: String 
} 

struct You: Codable 
{ 
    let id: Int 
    let name: String 
} 

class ViewController: UIViewController 
{ 
    override func viewDidLoad() 
    { 
     var codable: Codable? 

     codable = Me(id: 1, name: "Kobra") 
     let data1 = try? JSONEncoder().encode(codable) 

     codable = You(id: 2, name: "Kobra") 
     let data2 = try? JSONEncoder().encode(codable) 
    } 
} 

上面的代码不给我任何错误。我唯一改变的是:

let data = try? JSONEncoder().encode(codable!) 

我没有拆开包装codable,它是工作的罚款。

+0

编译不提供任何错误,但执行时会给出错误:致命错误:可选不符合Encodable,因为Encodable不符合自身。您必须使用具体类型进行编码或解码。 – Ramis

+1

那就解释一下。你需要使用具体的类型。 – PGDev

你的代码没问题,我们唯一需要关注的是Codable

Codable是一个typealias它不会给你通用类型。

JSONEncoder()。encode(Generic confirming to Encodable)。

所以,我修改了代码如下,它可以帮助你..

protocol Codability: Codable {} 

extension Codability { 
    typealias T = Self 
    func encode() -> Data? { 
     return try? JSONEncoder().encode(self) 
    } 

    static func decode(data: Data) -> T? { 
     return try? JSONDecoder().decode(T.self, from: data) 
    } 
} 

struct Me: Codability 
{ 
    let id: Int 
    let name: String 
} 

struct You: Codability 
{ 
    let id: Int 
    let name: String 
} 

class ViewController: UIViewController 
{ 
    override func viewDidLoad() 
    { 
     var codable: Codability 
     codable = Me(id: 1, name: "Kobra") 
     let data1 = codable.encode() 

    codable = You(id: 2, name: "Kobra") 
    let data2 = codable.encode() 
} 
} 

我用这种方式,也许它可以帮助你的情况下也是如此。

public protocol AbstractMessage: Codable { 
    var id: Int { get } // you might add {set} as well 
    var name: Int { get } 
} 

然后创建的方法,包括:

public func sendMessage<T>(message: T) where T: AbstractMessage { 
    let json = try! String(data: JSONEncoder().encode(message), encoding: .utf8)! 
    ... 
} 

在这里,我创建了一个公共协议,并通过它作为通用型我的功能。