LoginSignup
3
1

More than 5 years have passed since last update.

【コードリーディング】SwiftyJSONを読む

Last updated at Posted at 2017-10-14

はじめに

自分がよく利用しているOSSのSwiftyJSONのソースコードを読んでみようと思います。

SwiftyJSON
https://github.com/SwiftyJSON/SwiftyJSON

SwiftyJSONはSwiftでJSONデータを簡単に扱うためのライブラリです。
同様な機能を持つライブラリにはHimotokiObjectMapperなどがあり、幅広く利用されているライブラリの1つです。

基本情報(2017/9月現在)

ソースコード

SwiftyJSONのメインファイルは意外と少なく、以下のSwiftyJSON.swiftの1ファイルのみです。

SwiftyJSON / Source / SwiftyJSON.swift

行数は、1453行でstructが1つとprotocolが1つ、enumが5つです。class定義はありません。各定義の中身の説明は大枠に留め、ファイル構造だけ俯瞰すると以下のようになっています。

SwiftyJSON.swift(要約)
// ライセンス表記(MIT)

// エラードメイン、エラーコードに関する定数定義
// (deprecatedとなっており、下記のenumの利用を推奨している)

// SwiftyJSONに関するエラーの定義
public enum SwiftyJSONError: Int, Swift.Error { }

// CustomNSErrorプロトコルに準拠し、エラードメインやエラーコード、ユーザー向け情報を定義
extension SwiftyJSONError: CustomNSError { }

// http://www.json.orgに基づくJSONに含まれる型の定義
public enum Type: Int { }

// JSONのデータ構造を表現する構造体
// 各種イニシャライザメソッド、マージメソッド、プロパティ定義
public struct JSON { }

// ネストしたJSONをアンラップするための関数
private func unwrap(_ object: Any) -> Any { }

// Comparableプロトコルに準拠したIndexの定義
public enum Index<T: Any>: Comparable { }

// JSON構造体をCollectionプロトコルに準拠
extension JSON: Swift.Collection { }

// JSON構造体をsubscript(添字)でアクセス可能にする
public enum JSONKey { }
public protocol JSONSubscriptType { }
extension Int: JSONSubscriptType { }
extension String: JSONSubscriptType { }
extension JSON { }

// JSON型の変数に各リテラルを代入できるようにする
extension JSON: Swift.ExpressibleByStringLiteral { }
extension JSON: Swift.ExpressibleByIntegerLiteral { }
extension JSON: Swift.ExpressibleByBooleanLiteral { }
extension JSON: Swift.ExpressibleByFloatLiteral { }
extension JSON: Swift.ExpressibleByDictionaryLiteral { }
extension JSON: Swift.ExpressibleByArrayLiteral { }
extension JSON: Swift.ExpressibleByNilLiteral { }

// RawRepresentableプロトコルに準拠し、raw valueとの変換を可能にする
extension JSON: Swift.RawRepresentable { }

// JSON構造体を文字列で表現可能にする
extension JSON: Swift.CustomStringConvertible, Swift.CustomDebugStringConvertible { }

// Arrayに関するプロパティ(array、arrayValue、arrayObject)
extension JSON { }

// Dictionaryに関するプロパティ(dictionary、dictionaryValue、dictionaryObject)
extension JSON { }

// Boolに関するプロパティ(bool、boolValue)
extension JSON { }

// Stringに関するプロパティ(string、stringValue)
extension JSON { }

// Numberに関するプロパティ(number、numberValue)
extension JSON { }

// Nullに関するプロパティ(null)、メソッド(exists() -> Bool)
extension JSON { }

// URLに関するプロパティ(url)
extension JSON { }

// 数値型に関するプロパティ
// Int, Double, Float, Int8, Int16, Int32, Int64
extension JSON { }

// Comparableに準拠し、JSON型を比較できるようにする
extension JSON : Swift.Comparable { }

// raw value変換時のメタ情報キー
public enum writingOptionsKeys { }

これだけみても...という感じですね。
あまり見聞きしないプロトコルも使われているようなので、ざっと調べてみます。

利用プロトコル一覧

SwiftyJSONで利用されているプロトコルをまとめると以下のようになります。

プロトコル 説明
Swift.Error throwされる可能性のあるエラー値であることを表す型
CustomNSError Errorに準拠し、さらにerrorDomain、errorCode、errorUserInfoプロパティを持つ
Swift.Collection 複数の要素を集められ、索引(Index)でアクセスでき、さらにSequenceに準拠し、連続する要素を次々に取り出せる型
Swift.ExpressibleByStringLiteral 文字リテラルで初期化できる型
Swift.ExpressibleByIntegerLiteral 整数リテラルで初期化できる型
Swift.ExpressibleByBooleanLiteral ブールリテラルで初期化できる型
Swift.ExpressibleByFloatLiteral 浮動小数点リテラルで初期化できる型
Swift.ExpressibleByDictionaryLiteral 辞書リテラルで初期化できる型
Swift.ExpressibleByArrayLiteral 配列リテラルで初期化できる型
Swift.ExpressibleByNilLiteral nilリテラルで初期化できる型
Swift.RawRepresentable raw valueとの相互変換が可能な型
Swift.CustomStringConvertible カスタマイズした文字列に変換できる型
Swift.CustomDebugStringConvertible デバッグ用にカスタマイズした文字列に変換できる型
Swift.Comparable 比較演算子(<, <=, >=, >)で比較可能な型

ざっくりまとめると、SwiftyJSONで定義しているJSON構造体にプロトコルで以下の性質を持たせていることが分かります。

  • JSONを扱う時のエラーを区別できる(Error, CustomNSError)
  • JSONをArrayやDictionaryなどのコレクションのように添字アクセスできる(Collection)
  • 各リテラル表現からJSONを初期化できる(ExpressibleBy〜Literal)
  • JSONをraw valueとの相互変換ができる(RawRepresentable)
  • JSONのprint時に整形して出力できる(CustomStringConvertible, CustomDebugStringConvertible)
  • JSONを比較できる(Comparable)
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1