質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2907閲覧

RLMArray に Object をappendしたい

marcurrys

総合スコア16

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2016/06/04 07:10

PersonクラスとしてRealmオブジェクトとして以下のようなものを定義していて、APIサーバーからPersonにデータをmappingさせて利用しています。

Swift

1class Person: Object { 2 dynamic var id: Int = 0 3 dynamic var email: String? = "" 4 dynamic var name: String = "" 5 6 override class func primaryKey() -> String? { 7 return "id" 8 } 9 10 init(_id: Int, _email: String?, _name: String) { 11 id = _id 12 email = _email 13 name = _name 14 super.init() 15 } 16 17 required init() { 18 super.init() 19 } 20 required init(realm: RLMRealm, schema: RLMObjectSchema) { 21 super.init(realm: realm, schema: schema) 22 } 23 24 required init(value: AnyObject, schema: RLMSchema) { 25 super.init(value: value, schema: schema) 26 } 27}

一方で、Personクラスの配列を返すAPIのエンドポイントを用意して、PersonsというRealmオブジェクトを作りたいと思っています。

Swift

1class Persons: Object { 2 var persons: RLMArray = RLMArray(objectClassName: "Person") 3 4 init(_persons: [Person]?) { 5 let personsRLMArray = RLMArray(objectClassName: "Person") 6 if _persons != nil { 7 for person in _persons! { 8 personsRLMArray.addObject(person) 9 } 10 } 11 persons = personsRLMArray 12 super.init() 13 } 14 15 required init() { 16 super.init() 17 } 18 required init(realm: RLMRealm, schema: RLMObjectSchema) { 19 super.init(realm: realm, schema: schema) 20 } 21 22 required init(value: AnyObject, schema: RLMSchema) { 23 super.init(value: value, schema: schema) 24 } 25}

APIの返り値はRLMArrayではなくNSArrayなので、initの中で新しくRLMArrayを宣言して、for文でaddObjectさせています。

すると、Cannot convert value of type 'Person' to expected argument type 'RLMObject' というエラーが出ます。

PersonをObjectの継承ではなく RLMObjectの継承として定義すれば上記はエラーが消えるのですが、それで問題ないのでしょうか。RealmSwiftでRLMObjectを使わない方がいいというのを聞いたこともあるため、できれば避けておきたいと思っています。
RLMObjectを使う方法以外で、回避策はありませんでしょうか。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Realmのモデルクラスでは特に必要がなければrequired init()はオーバーライドしないでください。動きますが、Realm SwiftなのにRealm Objective-Cのクラス(RLMSchemaなど)が露出してしまいます。import Realmを書かなければいけないのもよくありません。

その代わりにconvenience init()を定義する方がコードが簡単になります。

そうするとPersonクラスは下記のようになります。

swift

1class Person: Object { 2 dynamic var id: Int = 0 3 dynamic var email: String? = "" 4 dynamic var name: String = "" 5 6 convenience init(id: Int, email: String?, name: String) { 7 self.init() 8 self.id = id 9 self.email = email 10 self.name = name 11 } 12 13 override class func primaryKey() -> String? { 14 return "id" 15 } 16}

引数をアンダースコア(_)で区別するのも一般的ではないので、より一般的なスタイルに直しました。引数は対応するプロパティと同じ名前に、引数とプロパティの区別はself.を付加することで行います。

問題のRLMArrayのエラーについてですが、Realm SwiftではRLMArrayなど、RLM*で始まる名前のクラスは使用しません。
それはRealm Objective-Cのクラスです。

RLMArrayに相当するRealm SwiftのクラスはList<T>です。List<T>を使ってPersonsクラスを書き直すと次のようになります。

swift

1class Persons: Object { 2 let persons = List<Person>() 3 4 convenience init(persons: [Person]?) { 5 self.init() 6 if let persons = persons { 7 self.persons.appendContentsOf(persons) 8 } 9 } 10}

ただし、おそらくRealmの使い方を間違っているのではないかと思います。普通はこのようなモデリングが必要になることはないと思いますので、よかったらどのようなことがしたいのか、もう少し詳しく教えていただけませんか?

投稿2016/06/06 10:27

編集2016/06/06 10:28
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marcurrys

2016/06/06 11:14

kkatsumiさん 詳細に回答をいただきありがとうございます。コードが非常に簡潔で綺麗になりました。 PersonsをRealmでモデリングすることについてですが、Personの配列を受けるAPI エンドポイントがあり(Facebookでいう友達リストのようなものです)、その保有するデータをまるごとRealmに書き込むことができたら便利だと思い、上記のようなクラスを作りました。 まだその実装段階に進めていないため自信がないですが、ご指摘を頂いて考えてみたところ、List<Person>をそのままRealmDBに書き込めばよくて、FriendsクラスをRealmでモデリングする必要はないのかもしれないと思い始めました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問