[Xcode]error typeと出て補完が効かなくなった場合の対応方法

More than 1 year has passed since last update.

みなさんは、補完機能があるIDEと補完機能がないIDE、どちらが好きですか?僕は補完機能があるIDEの方が好きです。でも悲しいことに最近、特定のプロジェクトでXcodeの補完機能が失われるという事象に遭遇してしまいました。


起きていた現象

スクリーンショット 2016-11-12 8.44.53.png

具体的には上記のように、変数の型に<<error type>>と表示されてしまい、この<<error type>>と表示された変数については補完やコードジャンプといったIDEの機能が使えなくなる、という現象です。

スクリーンショット 2016-11-12 8.49.16.png

このように、 tableView. と打っても、補完してくれないどころか警告を出してくる。いや、警告を出したいのは俺だ。member nameの候補をお前が早く提示しろ、という気持ちになりますね。型の情報が失われているので、テキストの色も黒ばかりです。

なおこの問題はXcode7.3の頃から発生していて、Xcode8でも同様に発生することを確認しています。


改善のために試したこと

下記のようなことは試してみましたが、効果がありませんでした。


  • Cleanする

  • Xcodeを再起動する

  • Derived Dataを削除する

  • 祈りながらSwift3.0対応してみる

正確にはDerived Dataの削除については、一瞬だけ効果があるように見えましたが数分作業すると結局 <<error type>> が出現します。


解決法

直接的な助けになったのは、Appleのフォーラムの下記の書き込みです。

https://forums.developer.apple.com/thread/46223

要約すると


  • CococaPodsがビルドディレクトリにヘッダファイルをコピーするのが原因であるようだ

  • これにより、SourceKitが正しくコードを解釈できなくなってしまう

  • 解決するためには、ビルド後にビルドディレクトリの余計なヘッダファイルを削除すれば良い

具体的には、プロジェクト設定の Build Phases に下記のようなRun Script を追加する。


sh

function removeHeaders() {  

find $BUILD_ROOT/Debug-iphonesimulator/ -name '*.h' -exec rm -f {} \;
}
removeHeaders

ということが書かれています。最初は半信半疑だったのですが、実際にこのスクリプトを追加してビルドしてみると...

スクリーンショット 2016-11-12 9.22.51.png

なんと! <<error type>> が消滅して型がある世界にもどって来ました!IDEではコードに色がつくということも忘れかけていましたが、しっかりと色が付いてます。

なお、上記のスクリプトではシミュレータだけしか対応できないので、 実機の場合にはスクリプトの Debug-iphonesimulator と記述されている部分を Debug-iphoneos と変更する必要があります。

自分の場合は、下記のようなスクリプトをビルド時に実行してディレクトリが存在すれば両方消すようにしておきました。


remove_header_files.rb

#!/usr/bin/env ruby

def remove_header_files(dir)
return unless File.exists?(dir)
cmd = "find #{dir}"
opt = '-name "*.h" -exec rm -f {} \;'
system("#{cmd} #{opt}")
end

build_dir = ENV['BUILD_ROOT']
exit if build_dir.nil?

simulator_dir = build_dir + "/Debug-iphonesimulator/"
device_dir = build_dir + "/Debug-iphoneos/"

remove_header_files(simulator_dir)
remove_header_files(device_dir)


自動補完もコードジャンプも動作せず、IDEの定義とは...と考えはじめていたのですが、無事直ってよかったです。いやぁ、IDEって最高ですね。