2017-10-04 103 views
1

我想創建類型爲的變量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'有什麼不對? –

回答

2

我創建了相同的情況你:

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

1

你的代碼沒問題,我們唯一需要關注的是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() 
} 
} 
1

我用這種方式,也許它可以幫助你的情況下也是如此。

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)! 
    ... 
} 

在這裏,我創建了一個公共協議,並通過它作爲通用型我的功能。