1. 程式人生 > >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.h 和 AppController.mm:

@class RootViewController;

@interface AppController : NSObject <UIApplicationDelegate>
{
    UIWindow *window;
    RootViewController *viewController;
}
//skProducts would be called outside the class
@property (nonatomic, assign) NSArray *skProducts;

- (void) onPaymentEvent:(NSString *)productId andQuantity:(NSInteger)count;
@end
#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

相關推薦

Cocos2d-Lua IOS支付記錄

網上可以找到Cocos2d-X或者Cocos2d-Js接IOS支付的參考,但是沒有Lua的,所以就暫且提供一個我的版本。 沒有折騰Lua和C++之間的互動,暫且用著Cocos2d框架提供的LuaObjcBridge,非常簡單。一些類名取自IAP Js版本作者。

cocos2d-lua整合到ios工程,即在ios原生應用中可以直接玩cocoslua開發的遊戲

前段時間配合其他部門把cocostudio做的動畫拿到ios原生引用中播放,把cocos2d-x做成靜態庫並保留了一個頭檔案給ios那邊呼叫,可以實現ios呼叫cocos2d-x,最近又要實現cocos2d-lua版本的,思路差不多,不過最後是呼叫的指令碼,可以把指令碼直接看做資源,坑也有幾看踩踩填

cocos2d-x + Lua接入iOS原生SDK的實現方案

相信很多朋友在使用cocos2d-x+lua開發遊戲時都遇到過接入iOS原生SDK的問題,比如常見的接應用內支付SDK,廣告SDK或是一些社交平臺SDK等等,我也沒少接過這類SDK。這篇文章主要是對我做過專案中接入iOS原生SDK實現方案的一個總結,在這裡分享給大家,希望對自己和大家的開發工作都有幫

add Admob with Cocos2d-x on iOS

nsobject code earch stack orm urn plain rda ima add Admob with Cocos2d-x on iOS (2013-02-27 14:12:00) 轉載▼ 標簽:

#iOS問題記錄#WKWebView 閃退異常

don nil @property debug oid oca eal ios10 erro 異常描述: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to

Cocos2d-x使用iOS遊戲內付費IAP(C++篇)

pos ack tegra cocos2d http tor -c html5 trac http://www.cocos2d-x.org/docs/manual/framework/html5/jsb-ios-iap/ios-storekit-integratio

IOS-學習記錄【01】

cancel screen color avi 需要 leg tco order isp 很久都沒寫博客了,從今天開始會記錄一些學習的心得/過程。現在對學習iOS的興趣也越來越濃。微信小程序的開發已經告一段落,目前會對產品進行代碼改進和功能優化。 第一個iOS應該從今天開始

Macaca 連iOS真機問題

test ice can 解決方法 多個 ide and 導致 瀏覽器 1. 查看連接的iOS設備:idevice_ID -l 2. 開啟Macaca服務:Macaca server -port 4444 -verbose 3. 開始錄制:UIrecorder start

Day22 【小程序】Credit Card(ATM),購物程序調用信用卡程序支付

logger nts 實現 管理 加載 相關 actions bin 目錄 程序介紹:   實現信用卡(ATM)常用功能:(支持多賬戶登陸)1.取款;2.還款;3.轉賬;4.查詢余額;5.查詢賬單(流水,支持按年月日時分秒記錄); 程序結構:ATM/├── README├─

第三方合同口示例記錄

anr input tput out utf put sign red eal public static String contractSign(Contract contract,Userbasicsinfo loanUser,Userbasicsinfo tend

騰訊社招iOS面試記錄 了解一下!!!

我想 監聽 針對 意思 碼率 分法 小視頻 demo runloop 畢業好幾年了,上周發送了簡歷給騰訊,參加了騰訊面試。具體部門這邊就不說了。這次面試還是收獲到了很多。 一面電話面試: 面試官主要是針對iOS相關的基礎問題。 先簡單自我介紹一下自己 對mrc和arc的理解

iOS記錄一下自己對於圓角優化效能的理解

公司開發多個專案中,檢視的圓角是不可避免的,也是增加美觀度的一種方式,下面談一下“老生常談”的圓角問題,以下是個人理解。 圓角的常用設法,cornerRadius設定圓角 , masksToBounds把整個圖層蒙上圓角 。 _whiteView.layer.cornerRad

搞定支付口—支付寶即時到賬支付口詳細流程和代碼

getc 配置 鍵值 writer his 僅供參考 ttr package art 搞定支付接口(

cocos2d-lua中pageview滑動事件回撥

1.在UIPageView.h中將addEventListener修改為如下 CC_DEPRECATED_ATTRIBUTE void addEventListener(const ccPageViewCallback& callback); using Scrol

【quick-cocos2d-lua】 獲取當前日期時間

local getTime = os.date(“%c”); 其中的%c可以是以下的一種:(注意大小寫) %a abbreviated weekday name (e.g., Wed) %A full weekday name (e.g., Wednesd

cocos2d-x 在ios端播放完mp4會崩潰的問題

在 cocos2d/cocos/ui/UIVideoPlayer-ios.mm 檔案裡,增加一個方法: - (void) deallocPlayer { if (self.moviePlayer != nullptr) { [[NSNotificationCenter

【quick-cocos2d-lua】 背景音樂與音效

同一時刻只支援播放一首背景音樂,但是可以播放多個音效。 1》播放與停止: audio.playMusic(filename,isLoop)        --播放背景音樂,filename是音訊檔名(放在res下),isLoop表示是否迴圈播放 handle = a

iOS支付寶問題之:呼叫支付寶AlipaySDK找不到標頭檔案

以下是網上找到得解決方案,但未能解決我的問題: http://my.oschina.net/u/734027/blog/358196 解決方案:openssl 和 Util目錄已經新增到Build setting --  header search path 的時候,我是

cocos2d-lua+cocos studio之ListView載入Item

這幾天換UI碰到一個問題,糾結了一天,然後各種百度,各種群諮詢,終於在幾番折騰後實現了自己想要的效果,現在分享思路和方法: 1.UI準備 在cocos studio裡面新建一個含有ListView容器

騰訊社招iOS面試記錄

點選上方“iOS開發”,選擇“置頂公眾號” 關鍵時刻,第一時間送達!     先不說楚楓的這般年紀,能夠踏入元武一重說明了什麼,最主要的是,楚楓在剛剛踏入核心地帶時,明明只是靈武七重,而在這兩個月不到的時間,連跳兩重修為,又跳過一個大境界,踏入了元武一重,這般進步