我需要在application:didFinishLaunchingWithOptions:中的UnityAppController中添加一些代码,以便使用其Objective-C SDK配置Google AdWords转化跟踪。

每次Unity生成Xcode项目时,手动编辑此文件似乎容易出错,因此我正在考虑使用PostProcessBuild属性添加后期构建步骤,该步骤将对生成的Unity代码应用补丁。

但是,补丁文件很难维护,因此我正在寻找替代解决方案。似乎通过UnityAppController宏对IMPL_APP_CONTROLLER_SUBCLASS进行子类化并覆盖application:didFinishLaunchingWithOptions:可能是其中之一。

但是,在执行此操作后,另一个第三方插件(Google Play游戏)也使用相同的方法将UnityAppController子类化,因为它的应用程序控制器不再被调用,因此停止工作。这是该插件的相关代码段:

@interface GPGSAppController : UnityAppController {
}

@end

IMPL_APP_CONTROLLER_SUBCLASS(GPGSAppController)

所以我想知道是否有可能从多个地方继承Unity应用程序控制器。我找不到在线IMPL_APP_CONTROLLER_SUBCLASS的任何文档。

还是有更好的方法在iOS的Unity中添加自定义初始化代码?

最佳答案

我结束了麻烦的UnityAppController方法并在实现中进行了初始化。

如果有人感兴趣,这是我的解决方案:

#import <objc/runtime.h>

...

#import "UnityAppController.h"

namespace {

typedef BOOL (*ApplicationDidFinishLaunchingWithOptionsImp)(UnityAppController *appController,
                                                            SEL selector,
                                                            UIApplication *application,
                                                            NSDictionary *launchOptions);

ApplicationDidFinishLaunchingWithOptionsImp OriginalApplicationDidFinishLaunchingWithOptions;

BOOL ApplicationDidFinishLaunchingWithOptions(UnityAppController *appController,
                          SEL selector,
                          UIApplication *application,
                          NSDictionary *launchOptions) {
    // Initialize Google Play Games, etc
    return OriginalApplicationDidFinishLaunchingWithOptions(appController, selector, application, launchOptions);
}

IMP SwizzleMethod(SEL selector, Class klass, IMP newImp) {
    Method method = class_getInstanceMethod(klass, selector);
    if (method != nil) {
        return class_replaceMethod(klass, selector, newImp, method_getTypeEncoding(method));
    }
    return nil;
}

} // anonymous namespace

@interface AppController : UnityAppController

@end

@implementation AppController

+ (void)load {
    OriginalApplicationDidFinishLaunchingWithOptions = (ApplicationDidFinishLaunchingWithOptionsImp)
        SwizzleMethod(@selector(application:didFinishLaunchingWithOptions:),
                      [UnityAppController class],
                      (IMP)&ApplicationDidFinishLaunchingWithOptions);
}


@end

只需将此文件另存为AppController.mm并将其添加到您的Assets文件夹即可。 Unity将其识别为Objective-C++源文件,并自动将其包含在生成的Xcode项目中。

如果您需要包括框架或以其他方式修改Xcode项目,请查看 PostProcessBuildAttribute Xcode API

10-01 16:11