LoginSignup
25
26

More than 5 years have passed since last update.

SwiftyJSONをSwift3で使う

Last updated at Posted at 2016-09-17

--> 2016/09/25追記
本家がSwift3に対応しました🎉
ご利用の際はぜひこちらを
Release Swift 3 Xcode 8 Support · SwiftyJSON/SwiftyJSON

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

背景

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

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

修正箇所

privateをfileprivateに変更

before

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

after

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

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

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

before

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

after

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

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

AnyObjectからAnyへ

before

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

after

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

whereを,に変更

before

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

after

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

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

cf. SE-0099 Restructuring Condition Clauses

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

before

extension JSON: Swift.Boolean {

after

extension JSON {

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

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

cf. SE-0109 Remove the Boolean protocol

まとめ

ということで一応使えるようになった&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

25
26
6

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
25
26