はじめに
Unityから生成してiOSアプリを作る場合、Google AnalyticsやPush通知などサードパーティが提供するモジュールが、
Unityにまで対応していない、ということはよくあります。
また、これを書いている今現在のUnity最新版(4.5.5f1)にはiOS8に対応しているようなメソッドが見つからなかったので
Unity本体に変更が入るたびに出力したiOSのProjectファイルに修正を入れることに疑問を感じて対応してみました。
※証明書の作成や、provisioing Fileなどの出し方は特に変わったことをしていませんので割愛しています。
環境
Unity Version 4.5.5f1
Xcode 6.1
Mac OS X Marvelicks
送信側:PyAPNs
https://github.com/djacobs/PyAPNs
実装:Unity
UnityのPlugin機能を使います。
Assetsの配下にPlugins, iOSとフォルダを作成し
* MyAppDelegate.h
* MyAppDelegate.mm
上記二つのファイルをドラッグ & ドロップなどで追加します。
MyAppDelegate.h
1 2 3 4 5 |
#import "UnityAppController.h" @interface MyAppDelegate : UnityAppController @end |
MyAppDelegate.mm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#import "MyAppDelegate.h" @implementation MyAppDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [super application:application didFinishLaunchingWithOptions:launchOptions]; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } else { [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)]; } return YES; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { [super application:application didRegisterForRemoteNotificationsWithDeviceToken:devToken]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"deviceToken" message:devToken.description delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; [alertView show]; } @end |
File > Build Settings
で “Build”ボタンを押すとiOS用のProject ファイルが出力されます。設定は場合に合わせてください。
画面上では実機転送用に書き出しています。
※出されない場合はエラーを確認してみてください。
実装:Xcode
出力したProjectファイルのLibrariesフォルダに追加した MyAppDelegate.mmファイルを見つけました。
変更がある場合はこちらのファイルを編集します。
main.mmを編集して派生させたAppDelegateを呼び出すように修正します
main.mm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#import <UIKit/UIKit.h> #include <time.h> #include "RegisterClasses.h" #include "RegisterMonoModules.h" // Hack to work around iOS SDK 4.3 linker problem // we need at least one __TEXT, __const section entry in main application .o files // to get this section emitted at right time and so avoid LC_ENCRYPTION_INFO size miscalculation static const int constsection = 0; void UnityInitTrampoline(); // WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value) //元々の指定 //const char* AppControllerClassName = "UnityAppController"; //派生させたクラス名を指定 const char* AppControllerClassName = "MyAppDelegate"; int main(int argc, char* argv[]) { NSAutoreleasePool* pool = [NSAutoreleasePool new]; UnityInitTrampoline(); if(!UnityParseCommandLine(argc, argv)) return -1; RegisterMonoModules(); NSLog(@"-> registered mono modules %p\n", &constsection); UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]); [pool release]; return 0; } #if TARGET_IPHONE_SIMULATOR extern "C" clock_t clock$UNIX2003(void) { return clock(); } #endif // TARGET_IPHONE_SIMULATOR |
実機に転送して、通知を送ってみます。
送信方法はいろいろですが、個人的にはPyAPNsを使っています。
参考URL
UnityのiOSでAppDelegateに処理を追加する
http://starzero.hatenablog.com/entry/2014/02/24/182646
さいごに
運用的に修正のたびに派生する作業は削らないと時間の無駄になることが多いので、調べて解決できることは結構あります。
知見を公開してくださっている技術者には感謝です。