Objc/SwiftでORMはこれまで使ったことがなかったのですが、手始めにObjectMapperというものを使ってみた。
使い方はREADME.md
に書いてある通りなので省略するとして、
"group" {
"id" : 1234,
"name" : "spacemen3",
"color" : 3
"owner" : {
"id" : 99999,
"name" : "ushisantoasobu",
"url" : "xxx.png"
}
}
こんな感じでネスト化されたjsonオブジェクトの、例えばowner
のname
にアクセスしたい場合は、
func mapping(map: Map){
name <- map["owner.name"]
}
のような感じでドットでつなぐことでマッピングできる(これもREADME.md
に書いてある)。
でもこういったデータ構造を扱うときって、
class Group: Mappable {
var identifier = Dynamic<Int>(0)
var name = Dynamic<String>("")
var color = Dynamic<Int>(0)
var ownerId = Dynamic<Int>(0)
var ownerName = Dynamic<String>("")
var ownerUrl = Dynamic<String>("")
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
color.value <- map["color"]
ownerId.value <- map["owner.id"]
ownerName.value <- map["owner.name"]
ownerUrl.value <- map["owner.url"]
}
}
とやることはなくて、
class User: Mappable {
var identifier = Dynamic<Int>(0)
var name = Dynamic<String>("")
var url = Dynamic<String>("")
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
url.value <- map["url"]
}
}
class Group: Mappable {
var identifier = Dynamic<Int>(0)
var name = Dynamic<String>("")
var color = Dynamic<Int>(0)
var owner = User()
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
color.value <- map["color"]
user = Mapper<User>().map(dictionary["owner"]) // ここは雰囲気で書いたので当然エラー
}
}
こんな感じで書くのが、データ構造としてスッキリするので普通だと思う。これはあくまで雰囲気で書いたもので、ここをどうやって正しく・簡潔に書くことができるか迷っていた。
で、自分がいまやっているのは、
class User: Mappable {
var prefix = ""
var identifier = Dynamic<Int>(0)
var name = Dynamic<String>("")
var url = Dynamic<String>("")
required init?(_ map: Map) {
mapping(map)
}
init(_ map: Map, prefix :String) {
self.prefix = prefix + "."
mapping(map)
}
func mapping(map: Map) {
identifier.value <- map[prefix + "id"]
name.value <- map[prefix + "name"]
url.value <- map[prefix + "url"]
}
}
class Group: Mappable {
var prefix = ""
var identifier = Dynamic<Int>(0)
var name = Dynamic<String>("")
var color = Dynamic<Int>(0)
var owner = User()
required init?(_ map: Map) {
mapping(map)
}
init(_ map: Map, prefix :String) {
self.prefix = prefix + "."
mapping(map)
}
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
color.value <- map["color"]
user = User(map, prefix: prefix + "owner")
}
}
こんな感じでやっちゃってる。prefix
だとかinit(_ map: Map, prefix :String) {
は全部共通なので基底クラスがつくれると思うけど、現在思考錯誤中なのでまだやっていない。
でも多分もっといい方法があるのだと思う。ので、ご教授いただけたら幸いです。いや、そもそもObjectMapper
自体そんな使われてないのかな。。
追記(2015/7/26)
@keitaoouchi さんよりご指摘いただいて、シンプルに
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
color.value <- map["color"]
user <- map["owner"]
}
でいけました。。。ありがとうございました!
追記(2015/8/2)
リストのモデルもそういえばやってなかったと思ったのですが、すんなりいけた。
var members = [Member]()
func mapping(map: Map) {
identifier.value <- map["id"]
name.value <- map["name"]
color.value <- map["color"]
user <- map["owner"]
members <- map["members"]
}