LoginSignup
15
15

More than 5 years have passed since last update.

Objective-CプロジェクトにSwift mix してハマったこと(随時更新)

Last updated at Posted at 2015-06-18

最近Objective-Cで書かれたプロジェクトにSwift (1.2)を突っ込んでいっています。
知見が溜まってきたので、共有しようと思います。

なおSwiftとObjective-Cの互換性については下記などに情報があります。

Objc側で.hで宣言した定数が見えない

下記のようにヘッダで宣言しても、ビルドのlinkerでコケます。

// Foo.h
static NSString * kSomeConstant = @"hello";
@interface Foo : NSObject
@end

下記のようにしましょう。

// Foo.h
extern NSString * const kSomeConstant
@interface Foo : NSObject
@end

// Foo.m
NSString * const kSomeConstant = @"hello";
@implementation Foo : NSObject
@end

objc側のdefineマクロが見えない

これはまあ、そうですよね、という。

objcからCommand + Clickで宣言部にジャンプすると、{Product}-Swift.h に飛んで、実装が見えない。

これは元の.swiftに飛んでくれてもいいんじゃないかな!と思ったり。

#if DEBUG が効かない?

#if DEBUG
    NSLog(s)
#endif 

という感じのコードを移植して

#if DEBUG
    println(s)
#endif 

のようにしたのですが、ログが出力されませんでした。
よく考えたらOther Swift Flagに何も値を入れてないだけでした。

インラインdefine関数定義が移植できない

結構みなさんロガーにこういうのを使ってることもあるかと思いますが、

#ifdef DEBUG
#define DEBUGLOG(...) NSLog(__VA_ARGS__)
#else
#define DEBUGLOG(...)
#endif

これはSwiftから全く見えません。
でも、例えばprintlnとかはインライン定義で使われていますよね。

swift1.2
@inline(never) func println<T>(value: T)

もしやこれを真似して定義すればそのまま置き換えられる?と思って試してみました。

@inline(never) func DEBUGLOG(s:String) {
    #if DEBUG
        println(s)
    #endif
}

Swift側はこれでよかったんですが、Objective-Cから使う時にC99のエラーが出ました。
c99.png

よくわからんですが、ひとまずインラインで同じものを作るのは諦めて、こんな感じで対応しました。

struct Logger {
    static func debug(s:String) {
        // このDEBUGはマクロではなく、Other Swift Flagの設定値であることに注意!
        #if DEBUG
            println(s)
        #endif
    }
    static func info(s:String) {
        println(s)
    }
}

ロガーについてはいろいろオープンソースのライブラリも出ているので、導入を検討してもいいかもしれません。
この辺りはSwiftで書かれています。

いずれにしてもマクロが使えないため、info,debug,error,warningなど出し分けるにはplist等で設定してね、ということになっているようです。

ちなみに、NSLogよりprintlnの方が高速なようです。

メソッドチェーン

Objective-Cはnilに対して寛容な仕様なので、例えばメソッドチェーンの途中でオプショナルが返っているところがある場合、if let でオプショナルを展開してあげないとダメです。
例えば、こんな感じですね。

if let url = NSBundle.mainBundle().appStoreReceiptURL?.path {}

以上です!

15
15
1

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
15
15