iOS Warning: CLIENT OF UIKIT REQUIRES UPDATE — UIScene lifecycle not adopted

Hi all,

When launching my cocos2d-x(3.17.1) app on iOS 18, I’m seeing this warning in the console:

CLIENT OF UIKIT REQUIRES UPDATE: This process does not adopt UIScene lifecycle. This will become an assert in a future version.

I understand that UIKit moved to a UIScene-based lifecycle in iOS 13, but I’m not sure how cocos2d-x handles this.

Do we need to update something in AppDelegate or elsewhere to prevent issues in the future?

Is there any cocos2d-x example that correctly adopts UIScene?

I’d appreciate any help or pointers.

Thanks in advance!

I did it for a Cocos2d game.
Will be very similiar to Cocos2d-x.

Note: Works only for iOS 13 or higher targets.

Add this in Info.plist :

<key>UIApplicationSceneManifest</key>
<dict>
	<key>UIApplicationSupportsMultipleScenes</key>
	<false/>
	<key>UISceneConfigurations</key>
	<dict>
		<key>UIWindowSceneSessionRoleApplication</key>
		<array>
			<dict>
				<key>UISceneConfigurationName</key>
				<string>Default Configuration</string>
				<key>UISceneDelegateClassName</key>
				<string>SceneDelegate</string>
			</dict>
		</array>
	</dict>
</dict>

A major change will be related how you create the UIWindow.
Look in the AppDelegate class and remove the UIWindow creation there .

Add SceneDelegate.m/h

SceneDelegate.h:

#import <UIKit/UIKit.h>

@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

@property (strong, nonatomic) UIWindow * window;

@end

SceneDelegate.m:

#import "SceneDelegate.h"

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    NSLog(@"scene willConnectToSession");

    self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
    self.window.windowScene = (UIWindowScene *)scene;

	//Here you should call the cocos2d setup code in AppDelegate class 
	(which you need to modify) where you forward the UIScene window to cocos2d.
   // [[AppDelegate appDelegate] cocos2dSetup:self.window ];

}
@end

The new Lifecyle events goes to the UIScene, but I just forward them to
the AppDelegate code base basically.

In AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  //Forward Lifecycle from UIScene to AppDelgate. 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UISceneWillDeactivateNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UISceneDidActivateNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground:) name:UISceneDidEnterBackgroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UISceneWillEnterForegroundNotification object:nil];

	....

	return YES;
}

#pragma mark - UISceneSession lifecycle

- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
    // Called when the user discards a scene session.
   
}