Cocos2d-Lua 接IOS支付记录

前端之家收集整理的这篇文章主要介绍了Cocos2d-Lua 接IOS支付记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

网上可以找到Cocos2d-X或者Cocos2d-Js接IOS支付的参考,但是没有Lua的,所以就暂且提供一个我的版本。
没有折腾Lua和C++之间的交互,暂且用着Cocos2d框架提供的LuaObjcBridge,非常简单。一些类名取自IAP Js版本作者。

第一个文件:IAPDelegates.h

#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>

@class AppController;

@interface iAPProductsRequestDelegate : NSObject<SKProductsRequestDelegate>
@property (nonatomic,assign) AppController *iosiap;
@end

@interface iAPTransactionObserver : NSObject<SKPaymentTransactionObserver>
@property (nonatomic,assign) AppController *iosiap;
@end

第二个文件:IAPDelegates.m

#import <Foundation/Foundation.h>
#import "IAPDelegates.h"
#import "AppController.h"

@implementation iAPProductsRequestDelegate

- (void)productsRequest:(SKProductsRequest *)request
     didReceiveResponse:(SKProductsResponse *)response
{
    if (_iosiap.skProducts) {
        [(NSArray *)(_iosiap.skProducts) release];
    }
    _iosiap.skProducts = [response.products retain];
}

- (void)requestDidFinish:(SKRequest *)request
{
    [request.delegate release];
    [request release];
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"%@",error);
}

@end

@implementation iAPTransactionObserver

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        if(transaction.transactionState == SKPaymentTransactionStatePurchased){
            [_iosiap onPaymentEvent:transaction.payment.productIdentifier andQuantity:transaction.payment.quantity];
        }
        if (transaction.transactionState != SKPaymentTransactionStatePurchasing) {
            [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
        }
    }
}

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
}

@end

文件,也就是Cocos2d提供的AppController.mm:

#import <UIKit/UIKit.h>
#import "cocos2d.h"
#import "platform/ios/CCLuaObjcBridge.h"

#import "AppController.h"
#import "AppDelegate.h"
#import "RootViewController.h"
#import "platform/ios/CCEAGLView-ios.h"
#import "IAPDelegates.h"

@implementation AppController
{
    iAPTransactionObserver* skTransactionObserver;
    int nLuaFunctionMemoryWarningCallback;
    int nLuaFunctionPaySuccessCallback;
    NSMutableDictionary* dictOfPayInfo;
    BOOL bTriggerAd;
}

#pragma mark -
#pragma mark Application lifecycle

// cocos2d application instance
static AppDelegate s_sharedApplication;
static AppController* s_sharedAppController;

+ (void)InitIAp:(NSDictionary *) dict{
    [s_sharedAppController applicationInitiAP:dict];
}

+ (void)Charge:(NSDictionary *) dict{
    [s_sharedAppController applicationPayRequest:dict];
}

+ (void)ListenMemoryWarning:(NSDictionary *) dict{
    s_sharedAppController->nLuaFunctionMemoryWarningCallback = [[dict objectForKey:@"callback"] intValue];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    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.
    window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
    CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds]
                                     pixelFormat: (NSString*)cocos2d::GLViewImpl::_pixelFormat
                                     depthFormat: cocos2d::GLViewImpl::_depthFormat
                              preserveBackbuffer: NO
                                      sharegroup: nil
                                   multiSampling: NO
                                 numberOfSamples: 0 ];

    [eaglView setMultipleTouchEnabled:YES];

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

    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // warning: addSubView doesn't work on iOS6
        [window addSubview: viewController.view];
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:viewController];
    }

    [window makeKeyAndVisible];

    [[UIApplication sharedApplication] setStatusBarHidden: YES];

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

    s_sharedAppController = self;

    app->run();
    return YES;
}

//初始化IAP
- (void)applicationInitiAP:(NSDictionary *) dict{
    // Initialize iAp Observer
    skTransactionObserver = [[iAPTransactionObserver alloc] init];
    ((iAPTransactionObserver *)skTransactionObserver).iosiap = self;
    [[SKPaymentQueue defaultQueue] addTransactionObserver:(iAPTransactionObserver *)skTransactionObserver];

    int productId = 1;
    NSMutableSet *set = [NSMutableSet setWithCapacity:4];//MagicNumber,but doesn't matter.
    NSString *productName = nil;
    while ((productName = [dict objectForKey:[NSString stringWithFormat:@"productid_%d",productId]]) != nil) {
        productId++;
        [set addObject:productName];
    }

    SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    iAPProductsRequestDelegate *delegate = [[iAPProductsRequestDelegate alloc] init];
    delegate.iosiap = self;
    productsRequest.delegate = delegate;
    [productsRequest start];
}

//调用IAP支付, dict中含有{"productId":"xxx","quantity":1,"callback":xx}
- (void)applicationPayRequest:(NSDictionary *) dict{
    NSString *productId = [dict objectForKey:@"productId"];
    for(int i = 0; i < [self.skProducts count]; i++){
        SKProduct *skProduct = [self.skProducts objectAtIndex:i];
        if([skProduct.productIdentifier isEqualToString:productId]){
            SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:skProduct];
            payment.quantity = [[dict objectForKey:@"quantity"] intValue];
            [[SKPaymentQueue defaultQueue] addPayment:payment];
            self->nLuaFunctionPaySuccessCallback = [[dict objectForKey:@"callback"] intValue];
            break;
        }
    }
}

- (void)applicationWillResignActive:(UIApplication *)application {
    /* Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. Use this method to pause ongoing tasks,disable timers,and throttle down OpenGL ES frame rates. Games should use this method to pause the game. */
    cocos2d::Director::getInstance()->pause();
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    /* Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was prevIoUsly in the background,optionally refresh the user interface. */
    cocos2d::Director::getInstance()->resume();
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    /* Use this method to release shared resources,save user data,invalidate timers,and store enough application state information to restore your application to its current state in case it is terminated later. If your application supports background execution,called instead of applicationWillTerminate: when the user quits. */
    cocos2d::Application::getInstance()->applicationDidEnterBackground();
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    /* Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. */
    cocos2d::Application::getInstance()->applicationWillEnterForeground();
}

- (void)applicationWillTerminate:(UIApplication *)application {
    /* Called when the application is about to terminate. See also applicationDidEnterBackground:. */
}

//支付成功的回调
- (void) onPaymentEvent:(NSString *)productId andQuantity:(NSInteger)count{
    cocos2d::LuaObjcBridge::pushLuaFunctionById(self->nLuaFunctionPaySuccessCallback);
    cocos2d::LuaObjcBridge::getStack()->pushLuaValue(cocos2d::LuaValue::stringValue([productId UTF8String]));
    cocos2d::LuaObjcBridge::getStack()->executeFunction(1);
    cocos2d::LuaObjcBridge::releaseLuaFunctionById(self->nLuaFunctionPaySuccessCallback);
}

#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /* Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. */
     cocos2d::Director::getInstance()->purgeCachedData();
    cocos2d::LuaObjcBridge::pushLuaFunctionById(self->nLuaFunctionMemoryWarningCallback);
    cocos2d::LuaObjcBridge::getStack()->executeFunction(0);
    //cocos2d::LuaObjcBridge::releaseLuaFunctionById(self->nLuaFunctionMemoryWarningCallback);
}

- (void)dealloc {
    [super dealloc];
}

@end

最后贴一下lua代码调用的片段:

function IsIOS()    --Lua的区分了iPad和iPhone,估计是历史包袱。
    return (cc.Application:getInstance():getTargetPlatform() == cc.PLATFORM_OS_IPHONE) or (cc.Application:getInstance():getTargetPlatform() == cc.PLATFORM_OS_IPAD)
end

--下面的是函数里的片段

if IsIOS() then
    local ok,ret = LuaObjcBridge.callStaticMethod("AppController","Charge",{
            ["productId"]=InfoAboutSDKPay[id],["quantity"]=1,["callback"]=PaySuccess
        })
    if(not ok) then
        print("AppController.Charge() err",ret)
    end
end
原文链接:https://www.f2er.com/cocos2dx/340297.html

猜你在找的Cocos2d-x相关文章