CocoaPodsを0.39.0にアップデートしたらAFNetworking v2.5.3で下記のようなビルドエラーが出た。
Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m:118:21: 'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.
最初に解決法
CocoaPodsでターゲットごとのライブラリ重複を許可するには、~/.cocoapods/config.yaml
にdeduplicate_targets: false
を記述するようになっているのでこれを設定するとビルドできる。
ただもし、~/.cocoapods/
以下に設定ファイルを置きたくない場合、環境変数CP_HOME_DIR
に設定ファイルのパスを設定する。具体的にはプロジェクトがあるカレントディレクトリ以下に.cocoapodsを設定し./.cocoapods/config.yaml
のファイルを読みこませたい場合
$ env CP_HOME_DIR=./.cocoapods pod install
のようにし、一時的に環境変数をセットした状態でpod installを行う。
その他解決法
「CocoaPods 0.38からのtarget重複排除を無効化する」
http://qiita.com/Branch_Dev/items/74c746d4563c07ffa096
にすでに他の方法が書かれてあるんだけど自分にはピンとこなかった。
どういう時に重複排除を無効化したいのか
CocoaPodsは0.38.0beta1からinstallするライブラリの重複を許さなくなってるっぽい。
これは特にExtensionでAFNetworkingを利用する際に厳しい仕様変更になっている。
Extension側ではAF_APP_EXTENSIONS
をdefineしAFURLConnectionOperation.mで下記のように処理を分岐している。defineしてないとExtension側ではビルドエラーになってしまう。
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
if (_backgroundTaskIdentifier) {
[[UIApplication sharedApplication] endBackgroundTask:_backgroundTaskIdentifier];
_backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}
#endif
そのため、もともと自前のプロジェクトにあるPodfileでは、Pods-ShareExtension-AFNetworking
という名前で生成されたTARGETの時のみAF_APP_EXTENSIONS
を有効にする、という処理を書いていた。
俺はこう思ったっス
そもそも
- CocoaPodsでinstallの設定を変える手段が~/.cocoapods/config.yamlなのが何かおかしい気がするんだけど
- pod install時に都度パラメータで指定するほうが自然じゃないだろうか
- AFNetworkingをExtensionで使うときにdefineしてるかどうかで分岐させるの何かおかしい気がする
追記
AFNetworking v2.6で対応されてた
AFNetworking v2.6で対応されてた。
NS_EXTENSION_UNAVAILABLE_IOSを使うことで、Extensionからはコンパイル時に見えないようになっている。