その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

Objective-C で書いたアプリを Swift で書き換える5ステップ

iBookでSwiftの解説本出ましたが、言語自体にはそれほど興味がないので、実践的なところとして、手始めに「Objective-Cで書いた既存アプリをSwiftで書き換える」ところからやってみました。


アプリ全体、となると壮大なテーマになってしまうので、まずは AppDelegate だけ書き換えてみます。


なお、NDA 下にある Xcode 6 については書けないので、ビルド設定等については割愛しています。

1. 拡張子を .swift にする

例えば AppDelegate.m なら、AppDeleagate.swift にします。

2. import の書き換え

ヘッダの import も移してきて、

#import <UIKit/UIKit.h>

だったのを

import UIKit

にします。

3. クラス宣言の書き換え

これもヘッダから移してきて *1

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

だったのを、

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
}

にします。


ただし

@UIApplicationMain

は AppDelegate.swift の場合のみ。


また上記のプロパティ宣言部分

var window: UIWindow?

にある `?` は、 nilを許容するかどうか を明示的に指定するものです。

4. メソッド定義の書き換え

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

だったのを、

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    // Override point for customization after application launch.
    return true
}

にします。


どこがどう書き換わっているかは、上記の例で一目瞭然で、説明不要かと思います。

5. main.mを削除

あまりいじる機会の少ない main.m では、

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

と、UIApplicationMain 関数に AppDelegate のクラスを渡していました。


Swift では上述したように AppDelegate.swift に同等のことを書いてしまってるので、main.m は不要となるので削除してしまいます。



以上の手順で(とくに中身のないAppDelegateの場合は)ビルドが通って動作するようになります。

おわりに

冒頭で「言語自体にはあまり興味がない」と書きましたが、Swiftのお試しがてらこれをやってみると、Objective-C と Swift の違いがよくわかり、「なるほど、このあたりのおかげで LLVM がグッと最適化できて高速化につながってるのか」と勉強になりました。

*1:実装ファイルに無名カテゴリで宣言しているメンバ変数やプロパティがあればそれもマージすることになるかと。