2016/05/13更新

[Swift] Objective-Cプロジェクトを、少しずつSwift実装に変えていく方法

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
Objective-C時代に作ったアプリケーションのバージョンアップをしようとした場合に、Swiftにするか悩むところですが、調べてみるとObjective-CとSwiftは共存できるし、一部だけSwiftで新規に実装することもできるし、既存のObjective-Cコードを一部だけSwiftに書き直しもできるし、と色々と柔軟だったので、それについてブログに書きたいと思います。

画像

目次




Objective-CコードをSwiftに書き直す

今回は以前にリリースしたEasyPost to Zaimという便利ツールを、Swiftに書き直してみようと思いました。手順を忘れないように、細かめに書いていきたいと思います。


Swiftファイルを新規で作成する

まずはObjective-Cから書き直したいコードを書くためのSwiftファイルを新規作成します。ファイル名は特にコンパイルには影響しませんが、合わせておいたほうが分かりやすいです(例:Objective-CでItemKey.hItemKey.mの場合、ItemKey.swift)。

その時に、Bridgeファイル(=SwiftからObjective-Cを使う場合に使うファイル)を作成するかを聞かれるので、これも一緒に作成します。
これで、移行する先のファイルの準備が整いました。


Objective-CからSwiftに書き直す

今回は以下のコードを書き直してみます。
// ItemKey.h
#import <Foundation/Foundation.h>
@interface ItemKey : NSObject {
    int page;
    int wIndex;
    int hIndex;
}
@property int page;
@property int wIndex;
@property int hIndex;

(id)initWith:(int)aPage wIndex:(int)aWIndex hIndex:(int)aHIndex;
(id)initWithNumberString:(NSString *)numberString;
(BOOL)isEqual:(ItemKey *)other;
(NSString *)toString;
@end
// ItemKey.m
#import "ItemKey.h"

@implementation ItemKey
@synthesize page;
@synthesize hIndex;
@synthesize wIndex;

(id)initWith:(int)aPage wIndex:(int)aWIndex hIndex:(int)aHIndex {
    self = [self init];
    if (self) {
        self.page = aPage;
        self.wIndex = aWIndex;
        self.hIndex = aHIndex;
    }
    return self;
}
(id)initWithNumberString:(NSString *)numberString {
    self = [self init];
    if (self) {
        int number = numberString.intValue;
        page = number / 100;
        wIndex = (number  page*100) / 10;
        hIndex = (number  page*100  wIndex*10);
    }
    return self;
}
(BOOL)isEqual:(ItemKey *)other {
    return page == other.page && hIndex == other.hIndex && wIndex == other.wIndex;
}
(NSString *)toString {
    int number = page * 100 + wIndex * 10 + hIndex;
    return  [NSString stringWithFormat:@"%d", number];
}
@end
このコードをSwiftに書き直すと、以下のようになりました。
// ① importの書き方が変わります
import Foundation

// ② インターフェース定義などなく、クラス定義を書きます
class ItemKey: NSObject {
    
    // ③ プロパティを定義します
    var page = 0
    var wIndex = 0
    var hIndex = 0
    
    // ④ 実装を書き直します(メソッドシグニチャを少し変えました)
    // (id)initWith:(int)aPage wIndex:(int)aWIndex hIndex:(int)aHIndex;
    init (aPage:Int, aWIndex:Int, aHIndex:Int) {
        self.page = aPage
        self.wIndex = aWIndex
        self.hIndex = aHIndex
    }

    // ⑤ オーバーロード的なこともできます
    init (numberString:String) {
        let number = Int(numberString)
        self.page = number! / 100
        self.wIndex = (number! - page * 100) / 10
        self.hIndex = (number! - page * 100 - wIndex * 10)
    }

    // ⑥ isEqualはObjective-Cのメソッドで、通常はオーバーライドできず、
    // 「@nonobjc」を付けてオーバーライドします。
    @nonobjc
    func isEqual (other:ItemKey) -> Bool {
        let judge = self.page == other.page
                        && self.hIndex == other.hIndex
                        && self.wIndex == other.wIndex
        return judge
    }
    
    func toString () -> String {
        let number = self.page * 100 + self.wIndex * 10 + self.hIndex;
        return String(number)
    }
}
と、こんな感じでObjective-CコードをSwift化します。

その後、不要になったItemKey.hItemKey.mファイルを削除します(削除しないと、ItemKeyが重複定義だとコンパイルエラーになります)。


Objective-CからSwiftコードを使う

上で定義したItemKey.swiftをObjective-Cから利用するように、既存の利用箇所を修正します。

まずは、ItemKeyクラスを使いたいObjective-Cファイルで、以下のインポートします。
// 形式は、「import [プロジェクト名]-Swift.h」でSwiftファイルをすべてインポートできます。
// 以下は、プロジェクト名が「toZaim」という場合の例です。
#import "toZaim-Swift.h"
その後に、以下のように書き直します(今回はinit系の処理のメソッドシグニチャを変えたので書き換えますが、それが無ければこの作業は不要です)。
// 旧:ItemKeyがObjective-C版のところ
ItemKey *key = [[ItemKey alloc] initWith:page wIndex:wIndex hIndex:hIndex];

// 新:Swift版で定義したものに変える
ItemKey *key = [[ItemKey alloc] initWithAPage:page aWIndex:wIndex aHIndex:hIndex];
これで動くようになります。iOSの開発では、SwiftとObjective-Cが共存できるところは柔軟でいいですね。


対象バージョンの変更

Swiftを使う場合には、iOS7以上である必要があるとのことで(コンパイルエラーになりました)、プロジェクトのサポート対象をiOS7以上にします。



最後に

今日は、Objective-Cプロジェクトの一部をSwift化するための方法をブログに書きました。ちょっとずつでもSwift移行できるところは、開発リソースを柔軟に使えるので便利でいいですね!

最後になりますが本ブログでは、Swift・Python・Java・フロントエンド・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。