酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

App Extension(Widget)を含んだiOSアプリをCocoaPods 1.0にバージョンアップさせる

記事自体は2ヶ月前に書いていたのですがちょうどiTunes Connectがトラブっていた時期だったので公開できずじまいでした。そのため一部記載しているバージョンが古い部分があります。


大半のプロジェクトでCocoaPods 1.0.0へ移行し終えてノウハウも溜まってきました。

ビルドサーバーを含め環境要因のトラブルが多く、CocoaPods 1.0.0への移行は一筋縄でいきませんでした。原因が環境要因なので一度わかってしまえば対策は簡単なのですが……

本記事では、CocoaPods 0.39.0で使用していたPodfileをCocoaPods 1.0.0で使えるようにどのようにマイグレーションさせたかを紹介したいと思います。

マイグレーション対象のアプリについて

仕事で関わっているプロジェクトで使用しているPodfileを晒すのは問題がありそうなので、「ikatomo」のケースを例にとって説明していきます。

https://itunes.apple.com/jp/app/ikatomo-for-splatoon/id1066729147?mt=8&uo=4&at=10l8JW&ct=hatenablog

ikatomoの売りのひとつは通知センターに表示されるステージ情報とフレンドのオンライン状態を閲覧できるWidget(App Extension)です。

ひょっとしたら僕のPodfileの書き方が悪いだけなのかもしれませんが…と前書きしておきますが、App Extensionを含んだプロジェクトの場合CocoaPodsとは少し相性がよくありません

解決方法については後ほど紹介します。

CocoaPods 0.39.0までのPodfile

CocoaPods 0.39.0までのPodfileです。

App ExtensionとCocoaPodsとの相性の悪さに四苦八苦していた時期に書いてそのままにしています。若干複雑になってしまっているところがあるかもしれません。

platform :ios, '9.0'
use_frameworks!

link_with 'TodayExtension'

pod 'RealmSwift'
pod 'SDWebImage'
pod 'Alamofire', '~> 3.0'
pod 'SwiftyJSON'
pod 'BrightFutures'

target :ikatomo do
    pod 'MaterialControls', '~> 1.0.2'
    pod 'BrightFutures'
    pod 'KeychainAccess'
    pod 'UIDeviceIdentifier', :git => 'https://github.com/squarefrog/UIDeviceIdentifier.git'
    pod 'MRProgress'
    pod 'Ji'
    pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git'
end

post_install do |installer|
  installer.pods_project.targets.each do |target|

    target.build_configurations.each do |config|
      config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
      config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
      config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
    end

  end
end

さて、このPodfileをv1.0.0向けに書き換えてみましょう。

CocoaPods 1.0.0に対応したPodfile

CocoaPods 1.0.0用に書き換えたPodfileです。前述のCocoaPods 0.39.0で使っていたPodfileと比較して行数は増えましたが見やすくなりましたね。

platform :ios, '9.0'
use_frameworks!

def shared_pods
    pod 'RealmSwift'
    pod 'SDWebImage'
    pod 'Alamofire', '~> 3.0'
    pod 'SwiftyJSON'
    pod 'BrightFutures'
end

target "ikatomo" do
    shared_pods

    pod 'MaterialControls', '~> 1.0.2'
    pod 'BrightFutures'
    pod 'KeychainAccess'
    pod 'UIDeviceIdentifier', :git => 'https://github.com/squarefrog/UIDeviceIdentifier.git'
    pod 'MRProgress'
    pod 'Ji'
    pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git'
end

target "TodayExtension" do
  shared_pods
end

target "FriendsWidget" do
  shared_pods
end

post_install do |installer|
  installer.pods_project.targets.each do |target|

    target.build_configurations.each do |config|
      config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
      config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
      config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
    end

  end
end

App Extensionを含んだプロジェクトの場合CocoaPodsを使うと自動リジェクト対象になるので対策する

CocoaPods 1.0.0を使ってもITMS-90205、ITMS-90206の指摘がありました。pod installや実機デバッグ時には問題になりませんが、iTunes Connectにバイナリを送信する段階で問題が発生してしまいます。CocoaPods 0.38.0、0.39.0だけでなく、CocoaPods 1.0.0でも同様の問題が発生します。

これはApp Extensionパッケージ内に余計なものが含まれているため、アップロード時に機械的にリジェクトされてしまう問題です。詳しくは下記の記事をご参照ください。

App Extensionのパッケージ(*.appex)の中にFrameworksというディレクトリがあって、このFrameworksディレクトリが存在しているのでリジェクトされてしまうのです。

不必要に追加されるEmbed Pods Frameworksを手動で消さないとビルドはできてもiTunes Connectに送信すると、前述の通り「ITMS-90205」「ITMS-90206」を理由に機械的に自動リジェクトされてしまいます。

今までは手動で対策をしていました。さすがにpod installpod updateする度に、手動でプロジェクト設定を弄らないと自動リジェクトされてしまうのがとても面倒なので、この問題に関してもきっちり解決しようと思います。

ikatomoではステージ情報Widget(TodayExtension)とフレンド情報Widget(FriendsWidget)を含んでいるので、下記のようにアプリ側のBuild PhasesでRun Scriptを追加します。

f:id:ch3cooh393:20160603094446p:plain

画像だとコピペしにくいのでスクリプト部分を抽出しておきます。ご使用の際には***.appexの部分を適切なアプリパッケージ名に修正してください。

EMBEDDED_EXTENSION_PLUGIN_PATH="$TARGET_BUILD_DIR/$PLUGINS_FOLDER_PATH/TodayExtension.appex/Frameworks"
if [[ -d "$EMBEDDED_EXTENSION_PLUGIN_PATH" ]]; then
rm -fr "$EMBEDDED_EXTENSION_PLUGIN_PATH"
fi

EMBEDDED_EXTENSION_PLUGIN_PATH="$TARGET_BUILD_DIR/$PLUGINS_FOLDER_PATH/FriendsWidget.appex/Frameworks"
if [[ -d "$EMBEDDED_EXTENSION_PLUGIN_PATH" ]]; then
rm -fr "$EMBEDDED_EXTENSION_PLUGIN_PATH"
fi

以上です。