技術と趣味の亜空間

主にゲームプログラミングとその周辺に関する記事を不定期で上げていきます

OneSignal の Unity SDK が Unity 2018 以降だとビルドで失敗するので修正した話

概要

OneSginal という超便利なプッシュ通知サービスがUnityで導入できますが、
私のプロジェクトだとiOSAndroidのビルドどちらも失敗してしまいました。
今回はそれを修正してみました。

onesignal.com

開発環境

  • OneSignal-Unity-SDK 2.7.8 release
  • Unity 2018.3.0b12
  • Xcode Version 10.1 (10B61)

iOSAndroid両方対応します。

iOS

Xcode設定の自動化が反映されない

OneSignal SDKにはiOSビルド時に PostProcessBuild でXcodeの設定を自動化させるコードが付属していますが、残念ながら私の環境ではうまくいきませんでした。

Unity-SDKのPostBuildProcessorに自動化処理は含まれているものの、記述が不完全だったのが原因でした。 リモート通知のCapabilityを有効にするには ProjectCapabilityManager クラスのメソッドを使う必要があります。 リモート通知はBackgroundModesのCapabilityのオプションとして存在するので、 PBXProject クラスのメソッドでは設定できません。 GithubIssuesにも同様の報告がされていますが、音沙汰がありません。 というわけで、こちらで修正しました。

PostProcessBuildPlayer_iOS.cs の130行目以降を以下のように変更します:

これでiOSの自動化が正常に実行されるようになりました。

Android

Androidだと主に2つのエラーが発生しました。

1. ビルドエラー

ビルド時に↓のエラーが発生。

CommandInvokationFailure: Gradle build failed. 
/Applications/Unity/Hub/Editor/2018.3.0b12/PlaybackEngines/AndroidPlayer/Tools/OpenJDK/MacOS/bin/java -classpath "/Applications/Unity/Hub/Editor/2018.3.0b12/PlaybackEngines/AndroidPlayer/Tools/gradle/lib/gradle-launcher-4.6.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleDebug"
stderr[
D8: Program type already present: android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':transformDexArchiveWithExternalLibsDexMergerForDebug'.
> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: /Users/○○○○○○/MyScriptProject/Temp/gradleOut/build/intermediates/transforms/dexBuilder/debug/0.jar, /Users/○○○○○○/MyScriptProject/Temp/gradleOut/build/intermediates/transforms/dexBuilder/debug/1.jar, /Users/○○○○○○/MyScriptProject/Temp/gradleOut/build/intermediates/transforms/dexBuilder/debug/2.jar, /Users/○○○○○○/...
...
  • ↑のログを見てみると android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat が重複しているのが原因
    • これは自プロジェクトに入れていたローカル通知用のプラグイン UniLocalNotificationsupport-compat-25.3.1.aarが、OneSignalのcom.android.support.support-compat-27.1.1.aarと競合していたのが原因でした
    • バージョンが古い UniLocalNotification側のを削除してビルドしたら無事通りました
    • 最近はUnity公式のMobile Notificationsが登場したので、正式版になった際はそちらに乗り換えるべきかも

2. サブモジュールを利用した際のエラー

自プロジェクトでは2Dデータと3Dデータを、スクリプトから切り分けて別プロジェクトで運用しており、スクリプトがあるプリジェクトをサブモジュールとしていました。しかし、この構造よる問題がAndroidで2件発生しました。

  • OneSignal付属のPlayServicesResolverが、勝手にスクリプト側のプロジェクトのaarファイルを2D側のPluginフォルダに移そうとする
    → 初期化時にProjectSettingに自動生成される AndroidResolverDependencies.xml のパスを書き換えて移させないようにします。今回サブモジュールはAssets直下に置いてあるので、 Assets/MyScriptProject/Assets/Plugins/Android/...となるようにします↓
...
  <files>
    <file>Assets/MyScriptProject/Assets/Plugins/Android/android.arch.core.common-1.1.0.jar</file>
    <file>Assets/MyScriptProject/Assets/Plugins/Android/android.arch.core.runtime-1.1.0.aar</file>
    <file>Assets/MyScriptProject/Assets/Plugins/Android/android.arch.lifecycle.common-1.1.0.jar</file>
    ...
  </files>
</dependencies>
  • OneSignalEditorScriptAndroid.cs でスクリプト側のプロジェクトのAndroidManifest.xml を書き換えてしまう
    → 下図のコードのように、OneSignalEditorScript_Androidにて2Dと3Dのプロジェクトでは書き換えが実行されないようにしました

PROJECT_ASSET_3DPROJECT_ASSET_2D という見慣れないマクロがありますが、これは両プロジェクトそれぞれに定義された専用マクロです。

以上で問題なくビルドが成功するようになりました。 参考になる人がいれば幸いです。