先週発生してマジで会社辞めようかと思いましたが、なんとか解決しました。
とにかく情報なくて辛かったので、書いておきます。
作業内容
Objective-CのClassをSwiftに書き換えるリファクタリングをしていました。
下記の作業内容をしました。
- 移行先のSwiftのStructを一旦別名で作成
- 移行先のClassと同名のStructを作成して、1)の記述内容をコピー
- 1)と移行先のClassを消す
- ブリッジヘッダーやその他Objective-Cヘッダから消したクラスに関する記述を削除
- 必要に応じてObjective-C側に記述を追加
エラー内容
ビルドしようとしたところ、下記のコンパイルエラーで先に進めなくなりました。
Clean BuildやXcodeの再起動、なんならMacBookの再起動までしましたが、ダメ。
failed to emit precompiled header '/Library/Developer/Xcode/DerivedData/MyprojectName-lajanjvhqjnfjksdsndsfkads/Build/Intermediates.noindex/PrecompiledHeaders/MyprojectName-Bridging-Header-swift_44AHJm3Z96qu-clang_2BIMGQVXGEZ09.pch' for bridging header '/Documents/MyProjectLocaiton/FoneApp-Bridging-Header.h'
※エラ〜メッセージは下記のStackOverflowから借りています。
Xcode 9 - failed to emit precompiled header [duplicate]
原因
途方に暮れていたところ、Swift実践入門を読んだら、こんなことが書いてありました。
ただし、SwiftはObjectiveCを内包している一方、ObjectiveCはSwiftのすべての概念を表現できません。たとえばSwiftの構造体や列挙型はObjectiveCには対応する概念がなく、ObjectiveC側から参照できません。また、Swiftのクラスに関してもObjectiveCから利用するにはさまざまな制限があります。
今回作ったSwiftの構造体は、ガッツリObjective-Cから参照されます。
そこで、Structで作っちゃダメなのでは? と思って、Classに書き換えたら発生しなくなりました。
その他細かいこと
- Class名に
@objcMembers
を指定すると、全体がObjective-Cから参照可能になる - Objective-C → Swiftの参照(そもそもあまり良くないが)する際は、ライブラリ指定に
#import "module-Swift.h"
@class NewClassName;
を入れると参照可能。
エラ〜メッセージを真面目に読むと、module-Swift.h
の.pchファイル(これ何なんだ?)が読めなくなって、ブリッジできなくなりました、
みたいな意味なんだと思いますが、ちょっと絶望感ありました。
- あと@objcMembersつけても、別のSwiftファイルの@objcメソッドの引数から呼ぼうとしたらエラーになりました。
- NSObjectを継承しなきゃダメみたいですNE
誰かの助けになれば幸いです。