2017-12-07 7 views
0

私がやりたい:JSONDecoder()を使用して`RLMArray`がプロトコルに準拠していない 'エンコード可能な'

  • 、私はjsonRealmにオブジェクトを変換します。
  • このオブジェクトをRealmデータベースに保存します。

問題:

  • RLMArray

    Codableプロトコルを適用しません。
  • 私はプロトコルDecodableに準拠することができましたが、Codableできませんでした。

エラーメッセージ:

  • タイプ '人' 'エンコード可能な'

コードプロトコルに準拠していません。

public class Hobby: Object, Codable { 
    @objc dynamic var title: String? 
    @objc dynamic var category: String? 
} 
public class Person: Object, Codable { // Error: Type 'Person' does not conform to protocol 'Encodable' 
    @objc dynamic var name: String? 
    @objc dynamic var hobbies: RLMArray<Hobby>? 

    required convenience public init(from decoder: Decoder) throws { 
     self.init() 
     let container = try decoder.container(keyedBy: CodingKeys.self) 
     name = try container.decode(String.self, forKey: .name) 
     hobbies = try container.decode(RLMArray<Hobby>?.self, forKey: .hobbies) 
    } 
} 
func sample() { 
    let person = try? JSONDecoder().decode(Person.self, from: "{\"name\" : \"aaa\",\"hobbies\" : [{\"title\" : \"fishing\",\"category\" : \"outdoor\"},{\"title\" : \"reading\",\"type\" : \"indoor\"}]}".data(using: .utf8)!) 
    print(person) 
    let realm = try! Realm() 
    try! realm.write { 
     realm.add(person!) 
    } 
} 

あなたはいくつかのアイデアを持っていますか?

Swift4 RealmSwift

+0

コード可能なで動作するようにrealmObjectsと私のリストを得た方法です
let tempHobbyList: [Hobby] = try container.decode([Hobby].self, forKey: .hobbies) self.hobbies.append(objectsIn: tempHobbyList) 

。 – EpicPandaForce

+0

なぜこのコードスニペットで 'RLMArray'を使っているのですか?あなたのクラスは 'Object'から派生しています。これはあなたがRealm Swiftを使っていることを示していますので、' List'を使うべきです。 – bdash

+0

@EpicPandaForce最後に、APIレスポンスが複雑であったため、データベーススキーマ定義とAPIレスポンスに分割することにしました。どうもありがとうございました。 –

答えて

2

コード可能で復号可能な+符号化可能と全く同じです。あなたはコード可能なに準拠するようにしたい場合は、お使いのPersonオブジェクトのためになるのエンコード機能を実装する必要があります。

enum CodingKeys: String, CodingKey { 
     case name 
     case hobbies 
// or: case hobbies = "customHobbiesKey" if you want to encode to a different key 
} 

func encode(to encoder: Encoder) throws { 
    do { 
     var container = encoder.container(keyedBy: CodingKeys.self) 
     try container.encode(name, forKey: .name) 
     try container.encode(hobbies, forKey: .hobbies) 
    } catch { 
     print(error) 
    } 
} 

は、あなたのPersonクラスにこれを追加し、あなたの趣味クラスの同じことを実現します。

エンコードしたいかどうかわからないので:もしJsonからRealm-Objectsを作成するだけであれば、 'Codable'を'Decodable '-Protocolに置き換えるだけです。

編集:RLMArrayに関する問題が発生しました。私はRLMArrayとどのようにコード可能な作品わからないんだけど、それが動作しない場合は、initで

let hobbies = List<Hobby>()

し、その後で宣言を交換してみてください()と「趣味」の行に置き換えます。

を私はちょうど、データベースのスキーマ定義とAPIレスポンスのために同じクラスを使用していないだろう
+0

ご清聴ありがとうございます。 最後に、APIレスポンスが複雑だったので、データベーススキーマ定義とAPIレスポンスに分割することにしました。 しかし、私はこの答えを得ることができて非常に満足しています。 シンプルなAPIを使用する場合は、この方法を使用します。どうもありがとうございました。 –

関連する問題