概要
SwiftでKVC(Key-Value Coding)を実現する方法についてです。
SwiftでクラスをNSObject
のサブクラスにすれば実現できるのですが、Swiftだけで実現できる方法はないかと調べていたらSwiftKVCというライブラリを見つけました。
今回はこのライブラリを活用してKVCしてみようと思います。
ライブラリ
実装
実装時はKVCでアクセスしたい対象がstruct
の場合とclass
の場合で対応が分かれます。
対応は以下です。
* 対象がstruct
の場合、Value
プロトコルへの準拠
* 対象がclass
の場合、Object
プロトコルへの準拠
(ライブラリの実装を見るとそれぞれのprotocol extensionに実装が書いてあります。)
実装例
今回はライブラリのサンプルに倣ってPerson
構造体を作成し、この構造体へのアクセスをしてみます。
struct Person: Value {
var name: String
var age: Int
}
サブスクリプトを用いたアクセス
値の設定
値を設定する際は以下のように設定できます。
var person = Person()
person["name"] = "John"
person["age"] = 10
値の取得
値の取得は以下のような感じです。
let person = Person(name: "John", age: 10)
name = person["name"]
age = person["age"]
エラー時の挙動
存在しないキーへのアクセスや、指定と違う型の値を設定しようとした場合は、値の設定の場合はその操作は無視されます。
また値を取得する場合は、nil
が返ります。
setメソッド、getメソッドを用いたアクセス
値の設定
set(value:key:)
メソッドを用いて値を設定できます。
set(value:key:)
メソッドはメソッド定義にthrows
キーワードの記載があるため、エラーハンドリングをする必要があります。
var person = Person()
do {
try person.set(value: "John", key: "name")
try person.set(value: 10, key: "age")
} catch {
print(error)
}
値の取得
get(key:)
メソッドを用いて値を取得できます。
こちらもset(value:key:)
メソッド同様throws
キーワードの記載があるため、エラーハンドリングが必要です。
do {
let name = try person.get(key: "name")
let age = try person.get(key: "age")
} catch {
print(error)
}
エラー時の挙動
存在しないキーへのアクセスや、指定と違う型の値を設定しようとした場合はエラーが発生し、catch
ブロックに入ります。
リポジトリ
以下に上記の設定や取得を試せるソースコードをあげています。
https://github.com/ikezzi/KVCExample
まとめ
SwiftKVCライブラリを用いれば手軽にSwiftでKVCを実現できます。
ドット記法とサブスクリプト等キー文字列を用いたアクセス両方を使いたい場合に活用できるかと思います。
また、今回SwiftKVCのライブラリに触れましたが、このライブラリ自体はかなり軽量で実質裏側で使われているReflectionというライブラリが本体なのでこちらもどこかのタイミングで触れたいと思います。