1

I've completed my game using Buildbox 2.3.3 and have cleaned up as many warnings as possible on Xcode. However, I've been at this for weeks now on me migrating from OpenGL to Metal which I assume is the reason I have that error in Xcode saying GLKit is deprecated, consider migrating to metal instead.

I attempted to upload the game to App store connect without me solving this error but then I instantly got sent an email saying

ITMS-90809: Deprecated API Usage, New apps no longer use UIWebView, use WKWebView instead.

I've no clue how to go about converting my code to cater for this I would really appreciate some guidance or if anyone can rewrite my code for me converting the OpenGL to metal.

I'll attach the code I'm using below, I would really appreciate it if anyone can help me. I've been stuck at this final stage for weeks now, its very frustrating.

AppDelegate.h

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>{
}

@property (strong, nonatomic) UIWindow *window;


@end

AppDelegate.mm

#import "AppDelegate.h"
#import <GLKit/GLKit.h>
#include "PTPSettingsController.h"
#include "libs/cocos2dx/include/audio/include/SimpleAudioEngine.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    cocos2d::CCDirector::sharedDirector()->pause();
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    cocos2d::CCApplication::sharedApplication()->applicationDidEnterBackground();
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    cocos2d::CCApplication::sharedApplication()->applicationWillEnterForeground();
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    cocos2d::CCDirector::sharedDirector()->resume();
}

- (void)applicationWillTerminate:(UIApplication *)application {
}

- (void)loadingDidComplete{
}

-(void)showCustomFullscreenAd{
}

- (void)screenOnEnter:(const char*) name{
}

- (void)screenOnExit:(const char*) name{
}

@end

GameViewController.h

#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>

@interface GameViewController : GLKViewController

@end

GameViewController.mm

#import "GameViewController.h"
#import <OpenGLES/ES2/glext.h>
#import "PTModelController.h"
#import "PTModelGeneralSettings.h"
#import "PTPAppDelegate.h"
#import "cocos2d.h"
#import "PTPConfig.h"
#include "PTPSettingsController.h"


#define IOS_MAX_TOUCHES_COUNT     10

static PTPAppDelegate s_sharedApplication;

@interface GameViewController () {
    NSString* shareMessage;
    bool sheduledForShareWidget;
}
@property (strong, nonatomic) EAGLContext *context;

@end

@implementation GameViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    
    sheduledForShareWidget = false;
    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }
    
    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    [view setMultipleTouchEnabled: YES];
    
    [self setPreferredFramesPerSecond:60];
    [EAGLContext setCurrentContext:self.context];
    
    PTModelController *mc = PTModelController::shared();
    mc->clean();
    
    unsigned long size = 0;
    char* pBuffer = (char*)CCFileUtils::sharedFileUtils()->getFileData("data/data.pkg", "rb", &size);
    if (pBuffer != NULL && size > 0){
        mc->setUsingDataEncryption( true );
    }
    
    mc->loadDataForSplashScreen("data/data.pkg", processor().c_str());
    
    s_sharedApplication.setDataArchiveProcessor(processor());
    
    
    cocos2d::CCApplication::sharedApplication()->run();
}

- (void)dealloc{
    if ([EAGLContext currentContext] == self.context) {
        [EAGLContext setCurrentContext:nil];
    }
}

- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];

    if ([self isViewLoaded] && ([[self view] window] == nil)) {
        self.view = nil;
        
        if ([EAGLContext currentContext] == self.context) {
            [EAGLContext setCurrentContext:nil];
        }
        self.context = nil;
    }

    // Dispose of any resources that can be recreated.
}

- (BOOL)prefersStatusBarHidden {
    return YES;
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    cocos2d::CCDirector::sharedDirector()->setViewport();
    cocos2d::CCDirector::sharedDirector()->mainLoop();
}


- (void)update{
    if(sheduledForShareWidget == true){
        sheduledForShareWidget = false;
        
        GLKView *view  = (GLKView *)self.view;
        UIImage* screenshot = view.snapshot;
        
        PTLog("Opens Share Widget: screenshot was taken");
        
        UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[shareMessage, screenshot] applicationActivities:nil];
        
        NSArray *excludeActivities = @[UIActivityTypeSaveToCameraRoll,
                                       UIActivityTypeAssignToContact];
        activityVC.excludedActivityTypes = excludeActivities;
        
        
        float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue];
        if(iOSVersion > 8.0){
            activityVC.popoverPresentationController.sourceView = self.view;
        }
        
        [self presentViewController:activityVC animated:YES completion:nil];
        PTLog("opens Share Widget: view controller presented");
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    int ids[IOS_MAX_TOUCHES_COUNT] = {0};
    float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    
    int i = 0;
    for (UITouch *touch in touches) {
        ids[i] = (intptr_t)touch;
        xs[i] = [touch locationInView: [touch view]].x * self.view.contentScaleFactor;
        ys[i] = [touch locationInView: [touch view]].y * self.view.contentScaleFactor;
        ++i;
    }
    cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesBegin(i, ids, xs, ys);
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    int ids[IOS_MAX_TOUCHES_COUNT] = {0};
    float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    
    int i = 0;
    for (UITouch *touch in touches) {
        ids[i] = (intptr_t)touch;
        xs[i] = [touch locationInView: [touch view]].x * self.view.contentScaleFactor;;
        ys[i] = [touch locationInView: [touch view]].y * self.view.contentScaleFactor;;
        ++i;
    }
    cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesMove(i, ids, xs, ys);
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    int ids[IOS_MAX_TOUCHES_COUNT] = {0};
    float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    
    int i = 0;
    for (UITouch *touch in touches) {
        ids[i] = (intptr_t)touch;
        xs[i] = [touch locationInView: [touch view]].x * self.view.contentScaleFactor;;
        ys[i] = [touch locationInView: [touch view]].y * self.view.contentScaleFactor;;
        ++i;
    }
    cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesEnd(i, ids, xs, ys);
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    int ids[IOS_MAX_TOUCHES_COUNT] = {0};
    float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
    
    int i = 0;
    for (UITouch *touch in touches) {
        ids[i] = (intptr_t)touch;
        xs[i] = [touch locationInView: [touch view]].x * self.view.contentScaleFactor;;
        ys[i] = [touch locationInView: [touch view]].y * self.view.contentScaleFactor;;
        ++i;
    }
    cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesCancel(i, ids, xs, ys);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    PTModelGeneralSettingsPtr generalSettings = PTModelGeneralSettings::shared();
    if(generalSettings->orientation() == PTModelGeneralSettings::LandscapeOrientation){
        return UIInterfaceOrientationIsLandscape( interfaceOrientation );
    }
    else if(generalSettings->orientation() == PTModelGeneralSettings::PortraitOrientation){
        return UIInterfaceOrientationIsPortrait( interfaceOrientation );
    }
    
    return NO;
}

- (NSUInteger) supportedInterfaceOrientations{
    PTModelGeneralSettingsPtr generalSettings = PTModelGeneralSettings::shared();
    if(generalSettings->orientation() == PTModelGeneralSettings::LandscapeOrientation){
        return UIInterfaceOrientationMaskLandscape;
        
    }
    else if(generalSettings->orientation() == PTModelGeneralSettings::PortraitOrientation){
        return UIInterfaceOrientationMaskPortrait;
    }
    
    return NO;
}

- (BOOL) shouldAutorotate {
    return NO;
}

-(void) scheduleOpenShareWidget:(const char*) message{
    shareMessage = [NSString stringWithUTF8String:message];
    sheduledForShareWidget = true;
}

@end
Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48
user13548860
  • 11
  • 1
  • 3
  • I'm sorry, but this is _way_ out of scope for StackOverflow. Porting a game from OpenGL to Metal is nothing you do by changing a few lines of code. However, OpenGL is _just_ deprecated – you can still use it. The error you are getting is not related to that. It seems somewhere in your codebase (or even in a dependency) you are using `UIWebView`. That needs to be replaced with `WKWebView`, then you should e able to submit the app. – Frank Rupprecht May 15 '20 at 13:22
  • OK i appreciate the response, i assumed i would have to convert to metal completely to be able to submit to apple, its my first game so i'm still new at this. So i just need to find that UIWebView and replace it, thanks. – user13548860 May 15 '20 at 22:35
  • Ive searched my codebase up and down i have no UIWebView anywhere. Im still receiving the email from apple, i'm trying to migrate from the GLKView in my storyboard to WKWebView. Do you think this will solve the problem? Ive already tried, however it seems my game is loading past the home page when i change the view to WKWebview – user13548860 May 18 '20 at 20:46
  • No, you can't replace `GLKView` (made for rendering OpenGL content) to `WKWebview` (basically Safari). Did you check your dependencies, including cocos2d, if they contain `UIWebViews`? – Frank Rupprecht May 19 '20 at 10:01
  • yes i've checked no UIWebViews present in the dependencies – user13548860 May 24 '20 at 19:54

2 Answers2

1

As you've already been told, your question is a little unsuitable for Stack Overflow. You can start rewriting your project from OpenGL to Metal, and ask questions if anything goes wrong.

Apple documentation is a good starting point:

You could also watch WWDC 2019 video and learn a step-by-step approach for transitioning OpenGL-based apps to the Metal API.

Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48
0

OpenGL is portable and widely supported, so it's a pity not to be able to use it. Luckily the MetalANGLE framework is an almost perfect drop-in replacement for GLKit. I have started using it in the development branch of my map rendering library, CartoType, and it works correctly: I can't see any difference in the graphics compared to GLKit, and I had to make only one minor change to my code to get it working - and that change was probably caused by an incorrect use of GLKit.

So my advice is: stay with OpenGL and use MetalANGLE.

Graham Asher
  • 1,648
  • 1
  • 24
  • 34