diff options
| -rw-r--r-- | platform/iphone/SCsub | 1 | ||||
| -rw-r--r-- | platform/iphone/godot_app_delegate.h | 41 | ||||
| -rw-r--r-- | platform/iphone/godot_app_delegate.m | 497 | ||||
| -rw-r--r-- | platform/iphone/main.m | 5 | 
4 files changed, 542 insertions, 2 deletions
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 0a558f8e3d..d836f2ddcc 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -14,6 +14,7 @@ iphone_lib = [      "joypad_iphone.mm",      "godot_view.mm",      "display_layer.mm", +    "godot_app_delegate.m",      "godot_view_renderer.mm",      "godot_view_gesture_recognizer.mm",      "device_metrics.m", diff --git a/platform/iphone/godot_app_delegate.h b/platform/iphone/godot_app_delegate.h new file mode 100644 index 0000000000..ebb21c499b --- /dev/null +++ b/platform/iphone/godot_app_delegate.h @@ -0,0 +1,41 @@ +/*************************************************************************/ +/*  godot_app_delegate.h                                                 */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ +/*                                                                       */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the       */ +/* "Software"), to deal in the Software without restriction, including   */ +/* without limitation the rights to use, copy, modify, merge, publish,   */ +/* distribute, sublicense, and/or sell copies of the Software, and to    */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions:                                             */ +/*                                                                       */ +/* The above copyright notice and this permission notice shall be        */ +/* included in all copies or substantial portions of the Software.       */ +/*                                                                       */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ +/*************************************************************************/ + +#import <UIKit/UIKit.h> + +typedef NSObject<UIApplicationDelegate> ApplicationDelegateService; + +@interface GodotApplicalitionDelegate : NSObject <UIApplicationDelegate> + +@property(class, readonly, strong) NSArray<ApplicationDelegateService *> *services; + ++ (void)addService:(ApplicationDelegateService *)service; + +@end diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m new file mode 100644 index 0000000000..a5aad26bd5 --- /dev/null +++ b/platform/iphone/godot_app_delegate.m @@ -0,0 +1,497 @@ +/*************************************************************************/ +/*  godot_app_delegate.m                                                 */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ +/*                                                                       */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the       */ +/* "Software"), to deal in the Software without restriction, including   */ +/* without limitation the rights to use, copy, modify, merge, publish,   */ +/* distribute, sublicense, and/or sell copies of the Software, and to    */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions:                                             */ +/*                                                                       */ +/* The above copyright notice and this permission notice shall be        */ +/* included in all copies or substantial portions of the Software.       */ +/*                                                                       */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ +/*************************************************************************/ + +#import "godot_app_delegate.h" + +#import "app_delegate.h" + +@interface GodotApplicalitionDelegate () + +@end + +@implementation GodotApplicalitionDelegate + +static NSMutableArray<ApplicationDelegateService *> *services = nil; + ++ (NSArray<ApplicationDelegateService *> *)services { +	return services; +} + ++ (void)load { +	services = [NSMutableArray new]; +	[services addObject:[AppDelegate new]]; +} + ++ (void)addService:(ApplicationDelegateService *)service { +	if (!services || !service) { +		return; +	} +	[services addObject:service]; +} + +// UIApplicationDelegate documantation can be found here: https://developer.apple.com/documentation/uikit/uiapplicationdelegate + +// MARK: Window + +- (UIWindow *)window { +	UIWindow *result = nil; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		UIWindow *value = [service window]; + +		if (value) { +			result = value; +		} +	} + +	return result; +} + +// MARK: Initializing + +- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application willFinishLaunchingWithOptions:launchOptions]) { +			result = YES; +		} +	} + +	return result; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application didFinishLaunchingWithOptions:launchOptions]) { +			result = YES; +		} +	} + +	return result; +} + +/* Can be handled by Info.plist. Not yet supported by Godot. + +// MARK: Scene + +- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {} + +- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {} + +*/ + +// MARK: Life-Cycle + +- (void)applicationDidBecomeActive:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationDidBecomeActive:application]; +	} +} + +- (void)applicationWillResignActive:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationWillResignActive:application]; +	} +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationDidEnterBackground:application]; +	} +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationWillEnterForeground:application]; +	} +} + +- (void)applicationWillTerminate:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationWillTerminate:application]; +	} +} + +// MARK: Environment Changes + +- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationProtectedDataDidBecomeAvailable:application]; +	} +} + +- (void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationProtectedDataWillBecomeUnavailable:application]; +	} +} + +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationDidReceiveMemoryWarning:application]; +	} +} + +- (void)applicationSignificantTimeChange:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationSignificantTimeChange:application]; +	} +} + +// MARK: App State Restoration + +- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application shouldSaveSecureApplicationState:coder]) { +			result = YES; +		} +	} + +	return result; +} + +- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application shouldRestoreSecureApplicationState:coder]) { +			result = YES; +		} +	} + +	return result; +} + +- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray<NSString *> *)identifierComponents coder:(NSCoder *)coder { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		UIViewController *controller = [service application:application viewControllerWithRestorationIdentifierPath:identifierComponents coder:coder]; + +		if (controller) { +			return controller; +		} +	} + +	return nil; +} + +- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application willEncodeRestorableStateWithCoder:coder]; +	} +} + +- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didDecodeRestorableStateWithCoder:coder]; +	} +} + +// MARK: Download Data in Background + +- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application handleEventsForBackgroundURLSession:identifier completionHandler:completionHandler]; +	} + +	completionHandler(); +} + +// MARK: Remote Notification + +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +	} +} + +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didFailToRegisterForRemoteNotificationsWithError:error]; +	} +} + +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +	} + +	completionHandler(UIBackgroundFetchResultNoData); +} + +// MARK: User Activity and Handling Quick Actions + +- (BOOL)application:(UIApplication *)application willContinueUserActivityWithType:(NSString *)userActivityType { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application willContinueUserActivityWithType:userActivityType]) { +			result = YES; +		} +	} + +	return result; +} + +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application continueUserActivity:userActivity restorationHandler:restorationHandler]) { +			result = YES; +		} +	} + +	return result; +} + +- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didUpdateUserActivity:userActivity]; +	} +} + +- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application didFailToContinueUserActivityWithType:userActivityType error:error]; +	} +} + +- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application performActionForShortcutItem:shortcutItem completionHandler:completionHandler]; +	} +} + +// MARK: WatchKit + +- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application handleWatchKitExtensionRequest:userInfo reply:reply]; +	} +} + +// MARK: HealthKit + +- (void)applicationShouldRequestHealthAuthorization:(UIApplication *)application { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service applicationShouldRequestHealthAuthorization:application]; +	} +} + +// MARK: Opening an URL + +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:app openURL:url options:options]) { +			return YES; +		} +	} + +	return NO; +} + +// MARK: Disallowing Specified App Extension Types + +- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(UIApplicationExtensionPointIdentifier)extensionPointIdentifier { +	BOOL result = NO; + +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		if ([service application:application shouldAllowExtensionPointIdentifier:extensionPointIdentifier]) { +			result = YES; +		} +	} + +	return result; +} + +// MARK: SiriKit + +- (id)application:(UIApplication *)application handlerForIntent:(INIntent *)intent API_AVAILABLE(ios(14.0)) { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		id result = [service application:application handlerForIntent:intent]; + +		if (result) { +			return result; +		} +	} + +	return nil; +} + +// MARK: CloudKit + +- (void)application:(UIApplication *)application userDidAcceptCloudKitShareWithMetadata:(CKShareMetadata *)cloudKitShareMetadata { +	for (ApplicationDelegateService *service in services) { +		if (![service respondsToSelector:_cmd]) { +			continue; +		} + +		[service application:application userDidAcceptCloudKitShareWithMetadata:cloudKitShareMetadata]; +	} +} + +/* Handled By Info.plist file for now + +// MARK: Interface Geometry + +- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {} + +*/ + +@end diff --git a/platform/iphone/main.m b/platform/iphone/main.m index c292f02822..351b40a881 100644 --- a/platform/iphone/main.m +++ b/platform/iphone/main.m @@ -28,7 +28,7 @@  /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */  /*************************************************************************/ -#import "app_delegate.h" +#import "godot_app_delegate.h"  #import <UIKit/UIKit.h>  #include <stdio.h> @@ -49,7 +49,8 @@ int main(int argc, char *argv[]) {  	printf("running app main\n");  	@autoreleasepool { -		UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); +		NSString *className = NSStringFromClass([GodotApplicalitionDelegate class]); +		UIApplicationMain(argc, argv, nil, className);  	}  	printf("main done\n");  	return 0;  |