SwiftyJSONをSwift3で使う


--> 2016/09/25追記
__本家がSwift3に対応しました🎉__
ご利用の際はぜひこちらを
[Release Swift 3 Xcode 8 Support · SwiftyJSON/SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON/releases/tag/3.0.0)

（この記事よりもっとちゃんと綺麗に丁寧に直されてました:-P）


# 背景
iOSアプリを急遽Swift3化して審査に出さなくてはならなくなったのですが、アプリで使ってるSwiftyJSONがSwift3に対応していなかったのでSwift3化してみたメモ。

SwiftyJSONは現在（2016/9/16）swift3ブランチはあるもののcommitが3ヶ月前と古くてそのままでは使えず。またXcode8に対応したとするPRはあるものの、本当に使えるのかわからなかったので取り急ぎ自分でもSwift3化してみることにしました。

# 修正箇所

## privateをfileprivateに変更

__before__

```swift
private var rawArray: [AnyObject] = []
private var rawDictionary: [String : AnyObject] = [:]
private var rawString: String = ""
private var rawNumber: NSNumber = 0
private var rawNull: NSNull = NSNull()
```

__after__

```swift
fileprivate var rawArray: [Any] = []
fileprivate var rawDictionary: [String : Any] = [:]
fileprivate var rawString: String = ""
fileprivate var rawNumber: NSNumber = 0
fileprivate var rawNull: NSNull = NSNull()
```

初めてSwiftのprivateが同じファイル内からアクセス可能だと知ったときはビビりましたが、extensionとかで使うときは便利なんだよな〜ということで気持ち悪さを感じつつも使っていましたprivate。

それがSwift3からは下記のようになってすっきりしました。

- private: Javaなど他の言語と同様のスコープ
- fileprivate: Swiftの旧privateと同じファイル内で有効なスコープ


***cf.*** [SE-0025 Scoped Access Level](https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md)

今回は動作を変えないよう、旧privateをfileprivateにそのまま書き換えました。
（privateに絞れるものがあればprivateに絞っても良いですね）


## 関数からプロパティになったので()を削除

__before__

```swift
if decimal == NSDecimalNumber.notANumber() {  // indicates parse error
	return NSDecimalNumber.zero()
```

__after__

```swift
if decimal == NSDecimalNumber.notANumber {  // indicates parse error
	return NSDecimalNumber.zero
```

もともと関数で定義されていたのがプロパティーになってたので削除（この変更の原典ってなんだろう）。


## AnyObjectからAnyへ

__before__

```swift
let object: AnyObject = try JSONSerialization.jsonObject(with: data, options: opt)
```
__after__

```swift
let object: Any = try JSONSerialization.jsonObject(with: data, options: opt)
```

これはObjective-Cのid型をSwiftで扱う際に、AnyObjectではなくAnyで扱うようになった影響ですね。
AnyObjectは参照型の型全般を表すもの、Anyは値型、参照型含めた型全般を表するものですが、SwiftではStringやArrayなどが値型になっているのでそれらとの相互運用をしやすくするための変更のようです。

JSONSerialization.jsonObjectでJSONデータからobjectを作る際に返す型がAnyObjectからAnyになったので、その関連部分もすべて型をAnyに差し替えました。

***cf.*** [SE-0116 Import Objective-C id as Swift Any type](https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md)

## whereを,に変更

__before__

```swift
if let errorValue = error where errorValue.code == ErrorNotExist{
```

__after__

```swift
if let errorValue = error, errorValue.code == ErrorNotExist{
```

if文の中などで複数の条件節がある場合の曖昧さをなくすために書き方が変わったようです。

***cf.*** [SE-0099 Restructuring Condition Clauses](https://github.com/apple/swift-evolution/blob/master/proposals/0099-conditionclauses.md)


## Booleanプロトコルへの適合部分を削除

__before__

```
extension JSON: Swift.Boolean {
```

__after__

```
extension JSON {
```

Booleanプロトコルが廃止されたことによる影響です。
歴史的な経緯で他のいろんな型の値をBooleanとして使ってるけど良くないのでBoolだけにしようぜということらしい。

コンパイルを通すためにBooleanプロトコルに適合させる部分だけ削除したけど本当はこのextension自体削除した方がいいのだろうか・・・？

***cf.*** [SE-0109 Remove the Boolean protocol](https://github.com/apple/swift-evolution/blob/master/proposals/0109-remove-boolean.md)


# まとめ

ということで一応使えるようになった＆Swift3の変更点の勉強になってよかった。
問題ありそうなところありましたらご指摘いただけると嬉しいです。

※Testとかまで直して確認してないので動作保証はできませんm(_ _)m

# 作業環境

Xcode: Version 8.0 (8A218a)


Folkした状態のまんまのswift3ブランチ
https://github.com/jollyjoester/SwiftyJSON/tree/swift3

Xcode8.0でビルドできるようにしたブランチ
https://github.com/jollyjoester/SwiftyJSON/tree/swift3-new

上記の差分
https://github.com/SwiftyJSON/SwiftyJSON/compare/swift3...jollyjoester:swift3-new?expand=1