初めまして。

サイバーエージェントの子会社の株式会社マッチングエージェントでエンジニアをしている海川です。

2017年3月1日に開催されたCA.swift #2で発表した内容から少し変えたものを語っていきます。

ca.swift #2

 

当日の資料はこちら

スライドでは合宿の話が多いですが、こちらの記事では省いてSwift化の部分だけにしてあります。

目次

 

 

 

Swift化した理由

swift化した理由は2つあります

 

1つ目は、エンジニアとしての今後の成長のためです。

当たり前の話ですが、今後iOSエンジニアとしてやっていくなら、Objective-CをやるよりSwiftを学んだ方がいいです。

Objective-CからSwiftに変換するのに時間がかかってしまいますが、それ以上の価値があると判断しました。

 

2つ目は、エンジニア採用のためです。

以前、iOSエンジニアを採用しようとした際に、弊社のアプリがObjective-Cでできていると伝えたら、「Objective-Cは読みたくない」と言われてしまったことがありました。

その人は他の部署へ行ってしまいました。優秀なエンジニアだっただけに非常に残念でした。

今後このようなことがないようにしたい、という思いがあります。

 

 

 

Swift化ツールについて

結論から言ってしまうと、objc2swift一択です

 

Swift化ツールについては、調べた結果代表的なものは3つくらいありました

iSwiftSwiftifyobjc2swiftです。 このサイトを参考にしました。

iSwiftはほとんど試していませんが、Swiftifyとobjc2swiftを試してみました。

 

  • Swiftifyは有料で、Swift2.3とSwift3.0に変換できる
  • objc2swiftは無料で、Swift2.3に変換できる

 

という差があり、Swiftifyの方が便利そうなのですが、

 

  • Swift2.3になったコードはXcodeからの警告にしたがって修正すれば、Swift3.0環境に問題なく変換できる
  • 変換自体がほとんどうまくいかないので、結局自分で修正する必要がある

 

という点です

以下のコードをobjc2swiftで変換すると、

@implementation CCTopic
- (id)initWithDictionary:(NSDictionary *)dictionary
{
    if (self = [super initWithDictionary:dictionary]) {
        _topicId = [dictionary[@"_id"] intValue];
        _title = @"特集";
        _color = [CCColorHelper colorWithHex:dictionary[@"color"]];
        
        CCUser *me = [CCAppGlobalModel sharedModel].user;
        
        NSDictionary *numDic = dictionary[@"member"];
        if ([numDic isKindOfClass:[NSDictionary class]]) {
            NSNumber *num = me.isMale ? numDic[@"count"][@"female"] : numDic[@"count"][@"male"];
            _count = num.intValue;
        }
        
        NSDictionary *titleDic = dictionary[@"title"];
        if ([titleDic isKindOfClass:[NSDictionary class]]) {
            _specialTitle = me.isMale ? titleDic[@"female"] : titleDic[@"male"];
        }
        
        NSDictionary *searchDic = dictionary[@"readOnlyCondition"];
        if ([searchDic isKindOfClass:[NSDictionary class]]) {
            _uneditableConditions = [[CCSearchConditions alloc] initWithDictionary:searchDic[@"user"]];
        }
    }
    return self;
}
@end

 

以下のようになります

 

class CCTopic: CCEntity {
    var topicId: Int32
    var count: Int32
    var title: String
    var specialTitle: String
    var color: UIColor
    var uneditableConditions: CCSearchConditions
    
    init(dictionary: [AnyObject: AnyObject]) {
        if self = super(dictionary: dictionary) {
            _topicId = dictionary["_id"].intValue()
            _title = "特集"
            _color = CCColorHelper.colorWithHex(dictionary["color"])
            var me = CCAppGlobalModel.sharedModel().user
            var numDic = dictionary["member"]
            if numDic.isKindOfClass(NSDictionary.class()) {
                var num = me.isMale ? numDic["count"]["female"] : numDic["count"]["male"]
                _count = num.intValue
            }
            var titleDic = dictionary["title"]
            if titleDic.isKindOfClass(NSDictionary.class()) {
                _specialTitle = me.isMale ? titleDic["female"] : titleDic["male"]
            }
            var searchDic = dictionary["readOnlyCondition"]
            if searchDic.isKindOfClass(NSDictionary.class()) {
                _uneditableConditions = CCSearchConditions(dictionary: searchDic["user"])
            }
        }
        return self
    }
}

 

スライドの写真にもある通り、エラーが大量に出ています。これはSwitifyを使ってもエラーが大量に出ます。有料ソフトだからといって、変換が楽になるということはないようです。

 

なので、有料のソフトを使う必要性はあまりないように思われます。objc2swift一択ですね

 

 

 

Swift化するときのポイント

実際やった経験を踏まえて、Swift化する上でのポイントを3つほどあげます

 

1つ目は、Swift化する際の順番は、呼び出される側からやった方がいい、ということです。

Objective-CをSwiftから呼び出す場合、以下のようになってしまいます

 

screenshot

 

 

このように ! ばかりになってしまいますね。

もしnilの変数が紛れていた場合、気づかぬうちにエラーになってしまいます。これは非常に危険なので、呼ばれる側からやりましょう。

 

2つ目は、ある程度エラーを気にせずに一気にやってしまうことも重要だ、ということです。

Objective-CとSwiftの接続部分は面倒なポイントが多いので、そういう接続部分は極力減らした方が懸命です。

例えばmodel部分は一気にやってしまうとか、ViewControllerとそれ以外で分けてやるとか、ViewControllerとViewModelは一緒にSwift化するとか、がっつりやった方が早いこともあると思います。

 

3つ目は、早めにコード規約を決めよう、ということです。

Objective-Cに比べて、SwiftはOptionalができたので、変数一つ取っても3通りの記載方法があります。

新しいものを作るときにstructを使うのか、classを使うのか、enumを使うのか、など選択しないと行けません。

いろいろできて楽しい反面、複数人で開発しているとぐちゃぐちゃになりやすいので、しっかり決めましょう。

 

 

 

最後に

SwiftはObjective-Cより厳格で楽しいです。

ちゃんとしたコード書いてるなーという実感が湧きます。

Swift化は自分のためにも、プロダクトのためにもなるので、迷っているとしたら、絶対にやるべきです。

 

このSwift化の最初のきっかけは開発合宿でした。開発合宿の記事もあるのでぜひ見てみてください。

あと、CASwift.#2の別のスライドの記事もぜひどうぞ。

sealives3333
2013新卒入社のiOSエンジニアです。タップル誕生作ってます