Cocos2d-x의 iOS 부분에서 Swift를 사용하고 싶습니다.

15469 단어 Swiftcocos2d-x

소개



cocos 명령으로 생성되는 기본 Cocos2d-x 프로젝트에서,
현재 Objective-C가 사용되고 있습니다만, Swift는 사용할 수 없는 것인가? 라고 생각해, 시험해 보았습니다.

아무튼 처음에 정리해 두면, Swift로부터 Objective-C++를 부르게 하면,
그런 일이 가능했습니다.

개요로서
1. 앱이 시작될 때 AppController.swift가 호출되도록 합니다.
2. Objective-C++의 Bridge File 준비
3. AppController.swift로 (2)에서 만든 Bridge File을 부른다
입니다.

※Cocos2d-x ver3.8.1에서 실시했습니다.

1. 앱이 시작될 때 AppController.swift가 호출되도록 합니다.



기본 프로젝트라면 앱을 시작할 때 AppController.mm이 호출되지만,
새로 만드는 AppController.swift를 호출합니다.

먼저 main.m 파일을 삭제합니다.
이 녀석이 내부적으로 AppController.mm을 부르고 있기 때문입니다.


그런 다음 AppController.swift를 만듭니다.
(Xcode에서 싱글 뷰 애플리케이션을 만들 때 생성되는 AppDelegate.swift를 복사하면 좋다고 생각합니다)
포인트는 @UIApplicationMain입니다.
이렇게하면 AppController.swift가 앱 시작시로드됩니다.

AppController.swift

import UIKit

@UIApplicationMain
class AppController: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        return true
    }

    func applicationWillResignActive(application: UIApplication) {}

    func applicationDidEnterBackground(application: UIApplication) {}

    func applicationWillEnterForeground(application: UIApplication) {}

    func applicationDidBecomeActive(application: UIApplication) {}

    func applicationWillTerminate(application: UIApplication) {}
}

현재 디렉토리는 이런 느낌 ↓


2. Objective-C++의 Bridge File 준비



간이되는 부분.
지금까지 AppController.mm에서 cocos의 초기화 등을 실시했지만, 그것을 AppController.swift에서 호출하기 위해,
Bridge File을 작성해, Swift → Objective-C++ 와 연동시킨다.

NativeBridge.h 및 NativeBridge.mm을 만듭니다. (이 이름은 좋지 않을까…)
NativeBridge.mm에 원래 AppController.mm에서 부르고 있던 cocos의 처리를 씁니다. (조금 리팩토링하고 있습니다)

NativeBridge.h

#import <Foundation/Foundation.h>

@interface NativeBridge : NSObject

+ (void) applicationDidFinishLaunchingWithOptions;
+ (void) applicationWillEnterForeground;
+ (void) applicationDidEnterBackground;

@end

NativeBridge.mm

#import "NativeBridge.h"
#import "cocos2d.h"
#import "platform/ios/CCEAGLView-ios.h"
#import "RootViewController.h"

@implementation NativeBridge


+ (void) applicationDidFinishLaunchingWithOptions {
    cocos2d::Application *app = cocos2d::Application::getInstance();
    app->initGLContextAttrs();
    cocos2d::GLViewImpl::convertAttrs();

    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    UIWindow *window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];

    // Init the CCEAGLView
    CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds]
                                         pixelFormat: (NSString*)cocos2d::GLViewImpl::_pixelFormat
                                         depthFormat: cocos2d::GLViewImpl::_depthFormat
                                  preserveBackbuffer: NO
                                          sharegroup: nil
                                       multiSampling: NO
                                     numberOfSamples: 0 ];

    // Enable or disable multiple touches
    [eaglView setMultipleTouchEnabled:NO];

    // Use RootViewController manage CCEAGLView
    RootViewController *viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    viewController.view = eaglView;

    [window setRootViewController:viewController];

    [window makeKeyAndVisible];

    [[UIApplication sharedApplication] setStatusBarHidden:true];

    // IMPORTANT: Setting the GLView should be done after creating the RootViewController
    cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView(eaglView);
    cocos2d::Director::getInstance()->setOpenGLView(glview);

    app->run();
}

+ (void) applicationWillEnterForeground {
    cocos2d::Application::getInstance()->applicationWillEnterForeground();
}

+ (void) applicationDidEnterBackground {
    cocos2d::Application::getInstance()->applicationDidEnterBackground();
}

@end


그런 다음 Build Settings > Objective-C Bridging Header$(SRCROOT)/ios/NativeBridge.h 같은 느낌으로 위에서 만든 NativeBridge.h가 로드되도록 합니다.
이것을 하는 것으로 swift 파일로부터 NativeBridge의 메소드등을 호출할 수 있게 됩니다.

현재 디렉토리 구조↓


3. AppController.swift에서 2로 만든 Bridge File을 부른다



마지막으로 AppController.swift를 다음과 같이 합니다.
(2)로 만든 NativeBridge의 클래스 메소드를 부르고 있습니다.
이것으로 작업이 끝납니다.
실행하면 평소에 익숙한 cocos의 이상한 마크 화면이 나올 것입니다.

AppController.swift

import UIKit

@UIApplicationMain
class AppController: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        NativeBridge.applicationDidFinishLaunchingWithOptions()
        return true
    }

    func applicationWillResignActive(application: UIApplication) {}

    func applicationDidEnterBackground(application: UIApplication) {
        NativeBridge.applicationDidEnterBackground()
    }

    func applicationWillEnterForeground(application: UIApplication) {
        NativeBridge.applicationWillEnterForeground()
    }

    func applicationDidBecomeActive(application: UIApplication) {}

    func applicationWillTerminate(application: UIApplication) {}
}

이상 ...!

결론



이제 cocos 개발에서도 swift 사용할 수 있습니다! 라고 생각했습니다만, 일단 Bridge File를 만들어야 하는 것은 조금 귀찮아…
뭐든지 안드로이드의 경우도 jni 경유하지 않으면 안 되고, 어떤 의미 같은 형태가 될까.
우선 swift를 사용할 수 있다는 것만으로 기쁜 생각이 든다.

(뭔가 실수가 있다면 지적해 주시면 감사하겠습니다.)

좋은 웹페이지 즐겨찾기