美文网首页
Unity iOS定制 UnityAppController

Unity iOS定制 UnityAppController

作者: 忆中异 | 来源:发表于2021-07-26 12:05 被阅读0次

    开发 Unity3d 手机游戏的时候,不免要和第三方 SDK 打交道。于是总是需要实现自己的 AppController 来维护 SDK 的生命周期。

    Unity3d 提供了一套插件机制,可以很方便地在项目中使用自己的 CustomAppController继承并重写默认的 UnityAppController的方法。

    0x00 CustomAppController

    在 Unity 插件目录下创建以下文件:
    Assets/Plugins/iOS/CustomAppController.mm
    <mark style="box-sizing: border-box; outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; background-color: rgb(248, 248, 64); color: rgb(0, 0, 0); overflow-wrap: break-word;">注意: 文件名必须是 ___AppController,前缀可自选,但不能省略;否则在 Build 项目的时候,会被移动到错误的目录中去</mark>
    CustomAppController.h头文件是可选的,不过通常直接把 @interface 直接放在 .mm 文件里就好。下面以微信 SDK 为例:

    #import "UnityAppController.h"
    #import "WXApi.h"
    
    @interface CustomAppController : UnityAppController < WXApiDelegate >
    @end
    
    IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)
    
    @implementation CustomAppController
    
    - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
        [super application:application didFinishLaunchingWithOptions:launchOptions];
    
        [WXApi registerApp: @"_________"];
    
        return YES;
    }
    
    - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    - (void)onResp:(BaseResp *)resp
    {
        // do something
    }
    
    - (void)onReq:(BaseReq *)req
    {
        // do something
    }
    
    @end
    
    

    在 Build iOS Project 的时候,Unity 会自动把 CustomAppController.mm复制到 project/Libraries/CustomAppController.mm

    而原来的 UnityAppController.mm则在 project/Classes/UnityAppController.mm

    那么 Unity 是如何知道要使用我们定制的 CustomAppController 而不是使用默认的 UnityAppController 呢?

    0x01 IMPL_APP_CONTROLLER_SUBCLASS

    很多文章在提到继承 UnityAppController 后,需要找到 project/Classes/main.mm里面的:

    const char* AppControllerClassName = "UnityAppController";
    
    

    将其修改为:

    const char* AppControllerClassName = "CustomAppController";
    
    

    从而使 Unity 在启动的时候使用我们制定的 CustomAppController 类。

    这样一来,每次 Build 项目都需要手动去修改这个常量,岂不是自找麻烦。其实完全可以利用 Objective-c 的特性来自动完成这个操作。

    注意到 UnityAppController.h 里面有这样一个宏:

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

    将这个宏加到 CustomAppController.mm中,即可实现自动设置 AppControllerClassName

    IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)
    
    

    IMPL_APP_CONTROLLER_SUBCLASS 使用了两个 Objective-C 的特性,一是 category ,用来给已有的类扩展新的方法;二是 +(void)load 静态方法,它会在运行时 CustomAppController 类被加载到内存中时触发,这个时间点比 int main() 函数还要早,所以能够提前“篡改” AppControllerClassName,达到我们的目的。

    转载于:https://blog.csdn.net/linxinfa/article/details/91811402

    相关文章

      网友评论

          本文标题:Unity iOS定制 UnityAppController

          本文链接:https://www.haomeiwen.com/subject/rlawmltx.html