Skyland Ventures tech ブログ

渋谷のVenture Capital Skyland Venturesのいま一番イケてる投資先、nanameue,IncとKaumoの共同技術ブログ

Objective-CからSwiftに書き換えて1週間レポート

こんにちわ!

nanameue, Inc. iOS エンジニアのバーチーです

3/4 ~ 3/6に行われた世界的Swiftカンファレンス try!Swiftの影響もあり、弊社でも、新プロジェクトをSwiftで書くことになりました

Swift2.0も公開され、また来月頃には、Swift3.0の公開も控えており、まあまあ良いタイミングだったのではないかと思います。

ライブラリもまあまあ充実してきた感じがあります

とはいえ、まだ新しい言語です。ぶっちゃけ、そんな便利なものかと問われると、まだ慣れてないせいもありますが、NOかなと思ってしまいました

不便に思ったこと① header fileがない

Objective-C時代にはクラスを作ると、.h ファイルと .mファイルが生成され、外部からアクセスする変数やメソッドの宣言は.h に、private変数や .hで宣言したものの 実装は、.mでやる と言う仕組みでした

.h .m ファイルが分かれているメリットは、.hファイルを見ると、一瞬でそのクラスが何をしているのかがわかることです。

しかし、Swiftでは、一つのファイルしか生成されません。 どうやるかというと、外部からアクセスできるものはpublicで、外部からはアクセスできないけど継承先からアクセスできるものはinternalで、完全にそのクラスしかアクセスできないものはprivate と宣言する必要があります。

もちろんファイルが少ないというメリットはありますが、コードの可読性という部分でいうとどうなんでしょう?

そのファイルを見ただけで一瞬で何をしているかはわかりづらいですね

ぶっちゃけそこまでメリットを感じられませんでした

不便に思ったこと② プロパティのgetterとsetterが面倒くさい

Objective-C時代には、プロパティを宣言すると、getter,setterメソッドが生成されます。(Swiftもそうですが、少し違います) 例えば、userというプロパティを宣言したとすると、

- (void)setUser:(User *)user {
}

- (User *)user {
}

というメソッドにアクセスすることができます。

しかしSwiftでは

var user: User {
get {
}

set (newValue) {
}

}

という書き方になり、プロパティを宣言と同時に書かなければいけません。 なので、宣言だけ上にしといて、実装はしたでという風にはできません。 こういう書き方って可読性が低くなる気がします

また、

var user: User {

set (newValue) {
}

}

のみができません。

getterがないよと怒られてしまします。

え、setterだけにアクセスしたい時とか山ほどあるのにな...

setterだけ!という場合は

var user: User {

didSet (newValue) {
}

}

とすれば、できます、(正確にはsetとdidSetは違うのですが)

不便に思ったこと③ いちいちImport文を書かなければいけない

Objective-Cでは、継承元の .hにimportされれば、継承先でも自動importされますがSwiftはそうではありません。というか全体てきに違います

Swiftでは,外部のモジュール以外は全てimport文は不要です。 pod install したもののみimport文が必要です。

が、継承先でもimportはしないといけません。

importする量は圧倒的に減りましたが、いちいち同じimportを書くのもな.....

不便に思ったこと④ クラスメソッドが少し使いずらいかも

Objective-Cであった[[self class] medhod]

Swiftでできないんですよね

例えば、クラス名がUserだとしたら [[User class] medhod] だと、そのUserクラスのクラスメソッドとなります

[[self class] medhod] だと、継承先でoverrideしたクラスメソッドがあればそちらが呼ばれます。

しかしSwiftでは、そういうものはありません。

じゃあどうやるかっていうと、 UserAクラスが親UserBクラスが子供だとすると、

 let currentClass: UserA.Type = UserB.self
currentClass.medhod

とやるか, Appleのreferenceには

UserA.dynamicType.medhod

と書いてありましたが、これが動かない、、

Swift2.1からうまく動かない問いうblogをちらほら見ました

不便に思ったこと⑤ nilの扱いがとにかく大変

Swiftでは、静的なので、コンパイルの時点でなるべくnilで落ちる可能性を低くしたい、というのがあります。 もちろんこちらの方が、堅牢で落ちにくいアーキテクチャ設計でアプリを作ることができます。

しかし、全ての変数に対して、nilを考慮しながら書くのは少し骨が折れますね、、

nilが入ると落ちそうなとこだけ、if文で対処の方が、早いというか楽ですね

1年もiOSをやっていると、ブッッチャケあ、ここってnilが入ったら落ちるだろうなという感が磨かれてきて、 そこだけ対処すればよかったです

まあでもいい変化といえば良いへんかなんですけどね、

なれるといいと思うのかもしれません

不便に思ったこと⑥ やっぱりライブラリがまだ少ない

現在Objective-C時代に活躍したライブラリをSwiftで書き換えてます。 Swiftでも使えるっちゃ使えるんですが、継承関係を結局いじれないので、

結局はSwiftに書き換えてます

ただ、これはかなりチャンスだなと思いました。

こういうライブラリあったらなと思うとこがいっぱいあったので、個人的に、作ったコードを汎用的にして、 公開しようと思います

まとめ

Swiftの悪口ばっか言ってすみません。 いろんな変化がありましたが、いい変化ですからね!基本的に まだ慣れてないだけなのかもしれません

しかし、Objective-Cのノウハウがめちゃくちゃある弊社のような会社だと、まだ圧倒的にObjective-Cの方が高速で、コード量も少なくかけます

Swiftの進化に期待ですね!

それでは!