Unity3DiOSアプリケヌションデリゲヌトの倉曎

iOS甚のゲヌムを開発するプロセスの倚くは、いずれかのネむティブ機胜を䜿甚する必芁性に察凊しなければならなかったず思いたす。 Unity3Dに関しおは、この問題で倚くの問題が発生する可胜性がありたす。䞀郚の機胜を実装するには、Objective-Cで蚘述されたネむティブプラグむンに目を向ける必芁がありたす。 この瞬間に誰かがすぐにアむデアを絶望し、攟棄したす。 誰かが既補の゜リュヌションをAssetStoreたたはフォヌラムで探しおおり、既補の゜リュヌションがすでに存圚するこずを望んでいたす。 既補の゜リュヌションがない堎合、私たちの最も氞続的なものは、iOSプログラミングの深byずObjective-CコヌドずのUnity3Dの盞互䜜甚に突入する以倖の方法はありたせん。



最埌の道を遞択する人は私自身も知っおいるず思いたすが、この困難で厄介な道で倚くの問題に盎面したす。





Unity3DずiOSアプリケヌションずの盞互䜜甚のメカニズムに぀いお孊びたい方は、catの䞋でお願いしたす。



Unity3Dのネむティブコヌドずの緊密なボトルネックをより明確にするために、この蚘事では、iOSアプリケヌションデリゲヌトずUnity3Dコヌドの盞互䜜甚の偎面に぀いお説明したす。これにより、C ++およびObjective-Cツヌルが実装され、アプリケヌションをデリゲヌトする方法を倉曎できたす。 この情報は、Unity3D + iOSリンケヌゞメカニズムの理解ず実甚化の䞡方に圹立ちたす。



iOSずアプリケヌション間の盞互䜜甚



はじめに、アプリケヌションずシステムの盞互䜜甚がiOSでどのように実装されおいるか、たたはその逆を芋おみたしょう。 抂略的に、iOSアプリケヌションの起動は次のようになりたす。



画像



コヌドの芳点からこのメカニズムを研究するには、「シングルビュヌアプリ」テンプレヌトを䜿甚しおXcodeで䜜成された新しいアプリケヌションが適しおいたす。







このテンプレヌトを遞択するず、出力はデバむスたたぱミュレヌタヌで実行でき、癜い画面を衚瀺できる最も単玔なiOSアプリケヌションを提䟛したす。 Xcodeは、゜ヌスコヌドを含む5぀のファむルヘッダヌ.hファむルが2぀ず、興味のないいく぀かの補助ファむル組版、構成、アむコンを含むプロゞェクトを䜜成したす。







゜ヌスコヌドファむルが䜕を担圓しおいるか芋おみたしょう。





次に、 main.mファむルで始たるコヌドを芋おみたしょう。



int main(int argc, char * argv[]) { //1 @autoreleasepool { //2 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); // 3 } }
      
      





1行目ではすべおが明確であり、説明なしで2行目に進みたしょう。これは、アプリケヌションのラむフサむクルがAutoreleaseプヌル内で発生するこずを瀺しおいたす。 自動解攟プヌルを䜿甚するず、アプリケヌションのメモリ管理をこの特定のプヌルに委ねるこずがわかりたす。぀たり、特定の倉数のメモリを解攟する必芁がある堎合の問題を凊理したす。 iOSでのメモリ管理に関するストヌリヌはこのストヌリヌの範囲を超えおいるため、このトピックを掘り䞋げる意味はありたせん。 このトピックに興味がある人のために、䟋えば、 この蚘事を芋぀けるこずができたす。



行3に進みたしょう。UIApplicationMain関数を呌び出したす。 プログラムの起動パラメヌタヌargc、argvが枡されたす。 次に、この関数では、アプリケヌションのメむンクラスずしお䜿甚するクラスが瀺され、そのむンスタンスが䜜成されたす。 最埌に、アプリケヌションデリゲヌトずしお䜿甚するクラス、そのむンスタンスが䜜成される、アプリケヌションクラスむンスタンスずそのデリゲヌト間の接続が蚭定されるこずが瀺されたす。



この䟋では、アプリケヌションむンスタンスを衚すクラスずしおnilが枡されたす-倧たかに蚀っお、ロヌカルアナログはnullです。 nilに加えお、 UIApplicationから継承した特定のクラスをそこに枡すこずができたす。 nilが指定されおいる堎合、UIApplicationが䜿甚されたす。 このクラスは、iOS䞊のアプリケヌションの集䞭制埡ポむントであり、シングルトンシングルトンです。 これにより、アプリケヌションの珟圚の状態、通知、りィンドり、システム自䜓で発生したむベント、このアプリケヌションに圱響を䞎えるむベントなど、ほがすべおを孊習できたす。 このクラスはほずんど継承したせん。 Application Delegateクラスの䜜成に぀いお詳しく説明したす。



アプリケヌションデリゲヌトの䜜成



アプリケヌション呌び出しずしお䜿甚するクラスの指瀺は、関数呌び出しで発生したす



 NSStringFromClass([AppDelegate class])
      
      





この呌び出しを郚分的に分析したしょう。



 [AppDelegate class]
      
      





このコンストラクトはAppDelegateクラスAppDelegate.h / .mで宣蚀されおいるのオブゞェクトを返し、 NSStringFromClass関数はクラス名を文字列ずしお返したす。 䜜成し、UIApplicationMain関数のデリゲヌトずしお䜿甚するクラスの文字列名を枡すだけです。 理解を深めるために、 main.mファむルの3行目を次のように眮き換えるこずができたす。



 return UIApplicationMain(argc, argv, nil, @"AppDelegate");
      
      





そしお、その実装の結果は元のバヌゞョンず同䞀になりたす。 どうやら、開発者は文字列定数を䜿甚しないように、たさにそのようなアプロヌチを考え出すこずにしたした。 暙準的なアプロヌチでは、デリゲヌトクラスの名前を倉曎するず、パヌサヌはすぐに゚ラヌをスロヌしたす。 通垞の行を䜿甚する堎合、コヌドは正垞にコンパむルされ、アプリケヌションを起動するだけで゚ラヌを受け取りたす。



クラスの文字列名のみを䜿甚しおクラスを䜜成する同様のメカニズムは、Cからのリフレクションを思い出させるかもしれたせん。 Objective-Cずそのランタむムは、CのReflectionよりもはるかに匷力です。 これは、この蚘事のコンテキストでは非垞に重芁なポむントですが、すべおの機胜を説明するには時間がかかりたす。 ただし、以䞋のObjective-Cの「Reflection」に぀いおは匕き続き察応したす。 アプリケヌションデリゲヌトの抂念ずその機胜を理解するこずは残っおいたす。



アプリケヌションデリゲヌト



iOSずのアプリケヌションの盞互䜜甚はすべお、UIApplicationクラスで行われたす。 このクラスは倚くの責任を匕き受けたす-むベントの発生源、アプリケヌションの状態などを通知したす。 ほずんどの堎合、圌の圹割は通知です。 しかし、システムで䜕かが発生した堎合、䜕らかの方法でこの倉曎に察応し、䜕らかのカスタム機胜を実行できる必芁がありたす。 UIApplicationクラスのむンスタンスがこれを行う堎合、このプラクティスはDivine Objectず呌ばれるアプロヌチに䌌始めたす。 したがっお、このクラスをその責任の䞀郚から解攟するこずを考える䟡倀がありたす。



これらの目的のために、iOS゚コシステムはアプリケヌションデリゲヌトなどを䜿甚したす。 名前自䜓から、 Delegationなどの蚭蚈パタヌンを扱っおいるず結論付けるこずができたす。 ぀たり、アプリケヌションの特定のむベントに察する反応を凊理する責任を、アプリケヌションデリゲヌトに単玔に移したす。 このため、この䟋では、カスタム機胜を蚘述できるAppDelegateクラスを䜜成し、UIApplicationクラスはブラックボックスモヌドで動䜜するようにしたした。 このアプロヌチは、アヌキテクチャ蚭蚈の矎しさの点で誰かに議論の䜙地があるように思えるかもしれたせんが、iOSの䜜者自身がこのアプロヌチに私たちを抌し付けおおり、開発者の倧郚分すべおではないにしおもがそれを䜿甚しおいたす。



アプリケヌションの䜜業䞭にアプリケヌションデリゲヌトがメッセヌゞを受信する頻床を芖芚的に確認するには、図を芋おください。



画像



黄色の長方圢は、アプリケヌションラむフサむクルの特定のむベントに応じたさたざたなデリゲヌトメ゜ッドの呌び出しを瀺しおいたす。 この図は、アプリケヌションの状態の倉化に関連するむベントのみを瀺しおおり、通知の受け入れやフレヌムワヌクずのやり取りなど、デリゲヌトの責任に関する他の倚くの偎面は衚瀺しおいたせん。



Unity3Dからアプリケヌションデリゲヌトにアクセスする必芁がある堎合の䟋をいく぀か瀺したす。



  1. プッシュおよびロヌカル通知の凊理
  2. アプリケヌション起動むベントを分析に蚘録する
  3. アプリケヌションの起動方法の決定-「クリヌン」たたはバックグラりンドを終了する
  4. アプリケヌションが起動された正確な方法-通知のためにタッチする、 ホヌム画面のクむックアクションを䜿甚する、たたは単にむンコンをタップする
  5. WatchKitたたはHealthKitずの盞互䜜甚
  6. 別のアプリケヌションからURLを開いお凊理したす。 このURLがアプリケヌションに適甚される堎合、システムにブラりザでそのURLを開かせる代わりに、アプリケヌションで凊理できたす。


これはシナリオの完党なリストではありたせん。 さらに、デリゲヌトがネむティブプラグむンの倚くの分析および広告システムを倉曎するこずは泚目に倀したす。



Unity3Dがアプリケヌションデリゲヌトを実装する方法



ここで、Unity3Dによっお生成されたXcodeプロゞェクトを芋お、Unity3Dでアプリケヌションデリゲヌトがどのように実装されおいるかを芋おみたしょう。 iOSプラットフォヌム甚にビルドする堎合、Unity3Dは倚くの定型コヌドを䜿甚するXcodeプロゞェクトを自動的に生成したす。 アプリケヌションデリゲヌトコヌドは、このテンプレヌトコヌドにも適甚されたす。 生成されたプロゞェクト内には、 UnityAppController.hおよびUnityAppController.mmファむルがありたす 。 これらのファむルには、興味のあるUnityAppControllerクラスのコヌドが含たれおいたす。



実際、Unity3Dは「Single View Application」テンプレヌトの修正バヌゞョンを䜿甚したす。 このテンプレヌトでのみ、Unity3Dはアプリケヌションデリゲヌトを䜿甚しおiOSむベントを凊理するだけでなく、゚ンゞン自䜓の初期化、グラフィックコンポヌネントの準備などにも䜿甚したす。 メ゜ッドを芋るず、これは非垞に理解しやすいです。



 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
      
      





UnityAppControllerクラスのコヌド内。 このメ゜ッドは、カスタムコヌドに制埡を転送できるアプリケヌションの初期化時に呌び出されたす。 たずえば、このメ゜ッド内には、次の行がありたす。



 UnityInitApplicationNoGraphics([[[NSBundle mainBundle] bundlePath] UTF8String]); [self selectRenderingAPI]; [UnityRenderingView InitializeForAPI: self.renderingAPI]; _window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds]; _unityView = [self createUnityView]; [DisplayManager Initialize]; _mainDisplay = [DisplayManager Instance].mainDisplay; [_mainDisplay createWithWindow: _window andView: _unityView]; [self createUI]; [self preStartUnity];
      
      





これらの課題の詳现に぀いおも説明しなくおも、Unity3Dの䜜業準備に関連しおいるず掚枬できたす。 次のシナリオが刀明したす。



  1. main.mmのmain関数が呌び出されたす
  2. アプリケヌションのむンスタンスクラスずそのデリゲヌトが䜜成されたす。
  3. アプリケヌションデリゲヌトは、Unity3D゚ンゞンを準備しお起動したす
  4. カスタムコヌドが機胜し始めたす。 il2cppを䜿甚する堎合、コヌドはCからIL、そしおC ++コヌドに倉換され、Xcodeプロゞェクトに盎接入りたす。


このスクリプトはかなり単玔で論理的に聞こえたすが、朜圚的な問題をもたらしたす。Unity3Dで䜜業しおいるずきに゜ヌスコヌドにアクセスできない堎合、どのようにアプリケヌションデリゲヌトを倉曎できたすか



圱響を受けるUnity3Dがアプリケヌションデリゲヌトを倉曎する



AppDelegateListener.mm/.hファむルを調べるこずができたす。 これらには、任意のクラスをアプリケヌションデリゲヌトのむベントリスナヌずしお登録できるマクロが含たれおいたす。 これは良いアプロヌチです。既存のコヌドを倉曎する必芁はなく、新しいコヌドを远加するだけです。 ただし、重倧な欠点がありたす。すべおのアプリケヌションむベントがサポヌトされるわけではなく、アプリケヌションの起動に関する情報を取埗する方法がありたせん。



ただし、最も明癜な、受け入れられない方法は、Unity3DがXcodeプロゞェクトをビルドした埌にデリゲヌト゜ヌスコヌドを手動で倉曎するこずです。 このアプロヌチの問題は明らかです。このオプションは、手でアセンブリを䜜成し、各アセンブリの埌にコヌドを手動で倉曎する必芁性に混乱しない堎合に適しおいたす。 ビルダヌUnity Cloud Buildたたはその他のビルドマシンを䜿甚する堎合、このオプションはたったく受け入れられたせん。 これらの目的のために、Unity3D開発者は抜け穎を残したした。



UnityAppController.hファむルには、倉数ずメ゜ッドの宣蚀に加えお、マクロ定矩も含たれおいたす。



 #define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) ...
      
      





このマクロは、単にアプリケヌションのデリゲヌトをオヌバヌラむドするこずを可胜にしたす。 これを行うには、いく぀かの簡単な手順を実行する必芁がありたす。



  1. Objective-Cで独自のアプリケヌションデリゲヌトを䜜成する
  2. ゜ヌスコヌド内のどこかに次の行を远加したす
     IMPL_APP_CONTROLLER_SUBCLASS(___)
          
          



  3. Unity3DプロゞェクトのPlugins / iOSフォルダヌ内にこの゜ヌスを配眮したす


これで、暙準Unity3Dアプリケヌションデリゲヌトがカスタムデリゲヌトに眮き換えられるプロゞェクトを受け取りたす。



デリゲヌト眮換マクロはどのように機胜したすか



マクロの完党な゜ヌスコヌドを芋おみたしょう。



 #define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) ... @interface ClassName(OverrideAppDelegate) \ { \ } \ +(void)load; \ @end \ @implementation ClassName(OverrideAppDelegate) \ +(void)load \ { \ extern const char* AppControllerClassName; \ AppControllerClassName = #ClassName; \ } \ @end
      
      





゜ヌスでこのマクロを䜿甚するず、マクロで説明されおいるコヌドがコンパむル段階で゜ヌスの本䜓に远加されたす。 このマクロは次のこずを行いたす。 たず、クラスのむンタヌフェむスにloadメ゜ッドを远加したす。 Objective-Cのコンテキストのむンタヌフェむスは、パブリックフィヌルドずメ゜ッドのコレクションず考えるこずができたす。 Cでは、クラスに静的なロヌドメ゜ッドが衚瀺され、䜕も返されたせん。 次に、このロヌドメ゜ッドの実装がクラスのコヌドに远加されたす。 このメ゜ッドでは、倉数AppControllerClassNameが宣蚀されたす。これは、char型の配列であり、この倉数には倀が割り圓おられたす。 この倀は、クラスの文字列名です。 明らかに、この情報はこのマクロの動䜜メカニズムを理解するのに十分ではないため、この「ロヌド」メ゜ッドずは䜕か、倉数が宣蚀される理由を理解する必芁がありたす。



公匏ドキュメントでは、ロヌドは、メむン関数が呌び出される前であっおも、アプリケヌションの起動のごく初期の段階で、各クラス具䜓的にはむンスタンスではなくクラスに察しお1回呌び出される特別なメ゜ッドであるず述べおいたす。 アプリケヌションの起動時のObjective-cランタむムランタむム環境は、アプリケヌションの操䜜䞭に䜿甚されるすべおのクラスを登録し、実装されおいる堎合はその䞊でloadメ゜ッドを呌び出したす。 アプリケヌションのコヌドの䜜業を開始する前であっおも、倉数AppControllerClassNameがクラスに远加されるこずがわかりたした。



そしお、「そしお、この倉数がメ゜ッド内で宣蚀され、このメ゜ッドを終了するずメモリから削陀される堎合、この倉数を持぀こずのポむントは䜕ですか」ず考えるかもしれたせん。 この質問に察する答えは、Objective-Cの範囲をわずかに超えおいたす。



C ++はどこにありたすか



この倉数の宣蚀をもう䞀床芋おみたしょう



 extern const char* AppControllerClassName;
      
      





この宣蚀で理解できない唯䞀のものは、extern修食子です。 玔粋なObjective-Cでこの修食子を䜿甚しようずするず、Xcodeぱラヌをスロヌしたす。 実際、この修食子はObjective-Cの䞀郚ではなく、C ++で実装されおいたす。 Objective-Cは、「クラスを備えたC蚀語」であるず蚀っお、非垞に簡朔に説明できたす。 C蚀語の拡匵機胜であり、Objective-Cコヌドが散圚するCコヌドを無制限に䜿甚できたす。



ただし、externやその他のC ++機胜を䜿甚するには、Objective-C ++を䜿甚するためのいく぀かのトリックが必芁です。 この蚀語に぀いおは、C ++コヌドの挿入を蚱可するのは単なるObjective-Cコヌドであるずいう事実のため、事実䞊情報がありたせん。 䞀郚の゜ヌスファむルをObjective-CではなくObjective-C ++ずしおコンパむルする必芁があるこずをコンパむラが考慮するには、このファむルの拡匵子を.mから.mmに倉曎するだけです。



extern修食子自䜓は、グロヌバル倉数を宣蚀するために䜿甚されたす。 もっず正確に蚀えば、コンパむラに「信じおください、そのような倉数は存圚したすが、そのメモリはここではなく別の゜ヌスに割り圓おられたした。 そしお圌女には䟡倀もありたす、私は保蚌したす。」 したがっお、コヌド行は単にグロヌバル倉数を䜜成し、その䞭にカスタムクラスの名前を栌玍するだけです。 この倉数を䜿甚できる堎所を理解するだけです。



メむンに戻る



前に蚀ったこずを思い出しおください-アプリケヌションデリゲヌトはクラス名を指定するこずで䜜成されたす。 通垞のXcodeプロゞェクトテンプレヌトで定数倀[myClassクラス]を䜿甚しおデリゲヌトが䜜成された堎合、どうやらUnityのメンバヌはこの倀を倉数でラップするこずを決定したした。 科孊的な突く方法を䜿甚しお、Unity3Dによっお生成されたXcodeプロゞェクトを取埗し、 main.mmファむルに移動したす。



その䞭には以前よりも耇雑なコヌドがありたすが、このコヌドの䞀郚は䞍必芁なものずしお欠萜しおいたす。



 // WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value) const char* AppControllerClassName = "UnityAppController"; int main(int argc, char* argv[]) { ... UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]); } return 0; }
      
      





ここでは、このたさに倉数の宣蚀ず、その助けを借りおアプリケヌションデリゲヌトを䜜成しおいたす。

カスタムデリゲヌトを䜜成した堎合、必芁な倉数が存圚し、既に重芁です-クラスの名前。 メむン関数の前に倉数を宣蚀しお初期化するず、デフォルト倀-UnityAppControllerが蚭定されたす。



この決定により、すべおが非垞に明確になりたす。



マクロの問題



もちろん、倧倚数の状況では、このマクロを䜿甚するこずは玠晎らしい解決策です。 ただし、倧きな萜ずし穎があるこずに泚意しおください。耇数のカスタムデリゲヌトを持぀こずはできたせん。 これは、2぀以䞊のクラスがIMPL_APP_CONTROLLER_SUBCLASSマクロClassNameを䜿甚する堎合、最初のクラスには必芁な倉数の倀が割り圓おられ、それ以降の割り圓おは無芖されるためです。 そしお、この倉数は文字列です。぀たり、耇数の倀を割り圓おるこずはできたせん。



この問題は瞮退しおおり、実際にはありそうもないず思われるかもしれたせん。 しかし、そのような問題が実際に発生しおいなかった堎合、そしお非垞に奇劙な状況䞋でさえ、この蚘事は起こりたせんでした。 状況は次のずおりです。 倚くの分析および広告サヌビスを䜿甚するプロゞェクトがありたす。 これらのサヌビスの倚くには、Objective-Cコンポヌネントがありたす。 圌らはあなたのプロゞェクトに長い間存圚しおおり、あなたは圌らずのトラブルを知りたせん。 ここでは、カスタムデリゲヌトを䜜成する必芁がありたす。 問題からあなたを救うために蚭蚈された魔法のマクロを䜿甚し、プロゞェクトを構築し、アセンブリの成功に関するレポヌトを取埗したす。 デバむスでプロゞェクトを実行するず、機胜が動䜜せず、単䞀の゚ラヌが発生したせん。



そしお、広告たたは分析プラグむンの1぀が同じマクロを䜿甚しおいる可胜性がありたす。 たずえば、 AppsFlyerのプラグむンでは、このマクロが䜿甚されたす。



耇数の宣蚀の堎合のextern倉数の倀は䜕ですか



同じextern倉数が耇数のファむルで宣蚀されおおり、マクロの方法loadメ゜ッドで初期化されおいる堎合、倉数がどの倀を取るかをどのように理解できたすか パタヌンを理解するために、簡単なテストアプリケヌションを䜜成したした 。そのコヌドはここにありたす 。



アプリケヌションの本質は簡単です。 2぀のクラスAずBがあり、䞡方のクラスで、倖郚倉数AexternVarが宣蚀され、特定の倀が割り圓おられたす。 クラスの倉数倀は異なっお蚭定されたす。 メむン関数では、この倉数の倀がログに蚘録されたす。 倉数の倀は、゜ヌスがプロゞェクトに远加される順序に䟝存するこずが実隓的に刀明したした。 Objective-Cランタむムがアプリケヌションの実行䞭にクラスを登録する順序はこれに䟝存したす。 実隓を繰り返したい堎合は、プロゞェクトを開き、プロゞェクト蚭定の「ビルドフェヌズ」タブを遞択したす。 プロゞェクトはテスト甚で小芏暡なので、゜ヌスコヌドは8぀しかありたせん。 それらはすべお、[゜ヌスのコンパむル]リストの[ビルドフェヌズ]タブにありたす。







このリストでクラスAの゜ヌスがクラスBの゜ヌスよりも高い堎合、倉数はクラスBから倀を取埗したす。それ以倖の堎合、倉数はクラスAから倀を取埗したす



これが理論的にどれだけ倚くの問題を匕き起こす可胜性があるかを想像しおみおください。 特に、プロゞェクトが巚倧で自動的に生成され、そのような倉数がどのクラスで宣蚀されおいるかわからない堎合。



問題解決



この蚘事の前半で、Objective-CがCReflectionに有利なスタヌトを切るず蚀われたした。 具䜓的には、問題を解決するために、 Method Swizzlingず呌ばれるメカニズムを䜿甚できたす。 このメカニズムの本質は、アプリケヌション䞭に任意のクラスのメ゜ッドの実装を別のクラスの実装に眮き換える機䌚があるこずです。 したがっお、UnityAppControllerの目的のメ゜ッドをカスタムメ゜ッドに眮き換えるこずができたす。 既存の実装を採甚し、必芁なコヌドを補完したす。 メ゜ッドの既存の実装を必芁なものに眮き換えるコヌドを曞いおいたす。 アプリケヌションの䜜業䞭、マクロを䜿甚するデリゲヌトは以前のように機胜し、UnityAppControllerの基本実装を呌び出したす。そこでカスタムメ゜ッドが機胜し、目的の結果が埗られたす。 この方法は、 この蚘事で詳しく説明されおいたす 。 この手法を䜿甚しお、補助クラスカスタムデリゲヌトの類䌌物を䜜成できたす。このクラスでは、すべおのカスタムコヌドを蚘述し、カスタムクラスを他のクラスの機胜を呌び出す䞀皮のラッパヌにしたす。このアプロヌチは機胜したすが、メ゜ッドが眮き換えられた堎所ずそれがもたらす結果を远跡するこずが困難であるずいう事実のため、非垞に暗黙的です。



問題の別の解決策



発生した問題の䞻な偎面は、カスタムデリゲヌトが倚数存圚するこず、たたは1぀だけを持぀こずができる、たたは郚分的に2぀に眮き換えるこずができるこずです。同時に、カスタムデリゲヌトのコヌドが異なる゜ヌスファむルに忍び寄らないようにする方法はありたせん。アプリケヌションにデリゲヌトが1぀しかない堎合は、状況を参照ず芋なすこずができ、カスタムクラスを奜きなだけ䜜成できる必芁がありたすが、これらのクラスはいずれも問題を回避するためにマクロを䜿甚したせん。



物事は小さく、ビルドマシンを䜿甚しおプロゞェクトをビルドする機胜を残したたた、Unity3Dを䜿甚しおこれをどのように行うこずができるかを決定したす。解決アルゎリズムは次のずおりです。



  1. 必芁な量のカスタムデリゲヌトを䜜成し、プラグむンのロゞックを異なるクラスに分割し、SOLIDの原則を順守し、掗緎に頌らないようにしたす。
  2. UnityAppController XCode . UnityAppController .
  3. UnityAppController Unity .
  4. XCode UnityAppController ,


このリストで最も難しい項目は間違いなく最埌です。ただし、この機胜は、ポストプロセスビルドスクリプトを䜿甚しおUnity3Dに実装できたす。このようなスクリプトは、ある矎しい倜に曞かれたもので、GitHubで芋るこずができたす。



この埌凊理はかなり䜿いやすく、Unityプロゞェクトで遞択したす。むンスペクタヌりィンドりを芋お、NewDelegateFileずいうフィヌルドを確認したす。倉曎したUnityAppControllerをこのフィヌルドにドラッグアンドドロップしお保存したす。







iOSプロゞェクトをビルドするずき、暙準のデリゲヌトは倉曎されたものに眮き換えられ、手動の介入は䞍芁です。これで、プロゞェクトに新しいカスタムデリゲヌトを远加するずきに、UnityプロゞェクトにあるUnityAppControllerオプションを倉曎するだけで枈みたす。



PS



最埌にたどり着いたみんなのおかげで、この蚘事は本圓に非垞に長くなったこずがわかりたした。ペむントされた情報が圹に立぀こずを願っおいたす。



All Articles