Using a Custom App Delegate on iOS
If your game uses a custom App Delegate, there are some things you should be aware of.
Teak hooks several methods of the Unity App Delegate when the application launches. This means that Teak intercepts the call, does what it needs to do, and then sends along the event to the Unity App Delegate.
The flow of events is: iOS → Teak → Unity
When you use a custom App Delegate, your App Delegate will be the first to receive
the call, instead of Teak. In order for Teak to function properly, you will need to call super
.
The flow of events is now: iOS → Your App Delegate → Teak → Unity
Notable Methods
If things aren’t working as expected, be sure that you are calling super
from
these methods (if your App Delegate implements them).
Deep Links Aren’t Working
-
application:openURL:sourceApplication:annotation:
-
application:openURL:options:
-
application:continueUserActivity:restorationHandler:
Push Notifications Aren’t Working
-
application:didReceiveRemoteNotification:
-
application:didFailToRegisterForRemoteNotificationsWithError:
-
application:didRegisterForRemoteNotificationsWithDeviceToken:
-
application:didRegisterUserNotificationSettings:
You should always call super from any method your App Delegate implements.
|
Versions of Unity
If you remove Teak from this build, you may need to remove the call to super from some delegate methods as your version of Unity may not support them.
For example, Unity 2018.2.18f1 does not implement application:openURL:options:
,
and if you try and call that function on the Unity App Delegate the app will crash
with an unrecognized selector exception.
Teak suggests handling this case with the following:
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation {
[super application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
return [self handleOpenURL:url fromSelector:_cmd];
}
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<NSString*, id>*)options {
if (class_respondsToSelector(UnityAppController.class, _cmd)) {
[super application:application openURL:url options:options];
return [self handleOpenURL:url fromSelector:_cmd];
}
return [self application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
In this way, both "deep linking" selectors will be handled by the custom delegate
via a singular method that we implement, handleOpenURL:fromSelector:
.
Now whichever selector calls, will be handled. In the case that the UnityAppControler
class does not implement the application:openURL:options:
selector, it will instead
re-direct the call to application:openURL:sourceApplication:annotation:
and allow processing.
For reference, this is the implementation Teak uses in our test framework:
- (BOOL)handleOpenURL:(NSURL*)url fromSelector:(SEL)sel {
if (![url.scheme isEqualToString:@"nonteak"]) {
return NO;
}
NSDictionary* jsonDict = @{
@"run_id" : @0,
@"event_id" : @0,
@"timestamp" : @0,
@"event_type" : @"test.delegate",
@"log_level" : @"INFO",
@"event_data" : @{
@"url" : url.absoluteString,
@"method" : NSStringFromSelector(sel)
}
};
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict
options:0
error:&error];
if (error == nil) {
NSString* jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
UnitySendMessage("TeakGameObject", "LogEvent", [jsonString UTF8String]);
}
return YES;
}
It’s fairly specific to our needs, but should be easily adaptable to your needs.