2017-10-04 12 views
1

コーディング可能タイプの変数を作成したいと思います。そして、後で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'以外の' Any'を使用してください –

+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

コンパイルでエラーは発生しませんが、実行するとエラーが発生します。致命的なエラー:オプションはエンコーディングがそれ自体に準拠していないためエンコーディングに準拠しません。エンコードまたはデコードには具体的なタイプを使用する必要があります。 – 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 func sendMessage<T>(message: T) where T: AbstractMessage { 
    let json = try! String(data: JSONEncoder().encode(message), encoding: .utf8)! 
    ... 
} 

:その後、

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

は、メソッドを作成しました。

関連する問題