とりあえず(1)は良いとして、(2)ですが、適当にクラスを作ります。
MyPayment.h、MyPayment.mを以下の感じで。
// .h
@interface MyPayment : NSObject <SKProductsRequestDelegate>
+ (MyPayment*) node;
- (void)startBuy:(int)product_idx;
@end
// .m
@implementation MyPayment
- (id) init {
self = [super init];
if (!self) return NULL;
return self;
}
- (void) dealloc {
[super dealloc];
}
+ (MyPayment*) node {
return [[MyPayment alloc] init];
}
- (void)startBuy:(int)product_idx {
// 購入処理
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:product_id]];
request.delegate = self;
[request start];
}
@end
ちゃんとした購入処理は各自実装するとして、今回は流れだけ。
この2ファイルは、プロジェクトフォルダ内にあるlibsに「MyPayment」というフォルダを作り、そこに入れていると仮定して進めます。
そして、(3)の部分です。
「libs/jsbindings/configs」に「MyPayment」というフォルダを作り、中に以下のファイルを作ります。
MyPayment_jsb.ini
(CocosBuilderReader_jsb.iniをコピペして、以下項目を適当に修正)
[MyPayment]
obj_class_prefix_to_remove = My
classes_to_parse = MyPayment
classes_to_ignore = NS(.*), SK(.*)
import_files = jsb_NS_manual.h,
MyPayment.h
method_properties = MyPayment # node = name:"create",
bridge_support_file = MyPayment.bridgesupport
complement_file = MyPayment-complement.txt
gen_MyPayment.sh
#!/bin/sh
cd プロジェクトのパス/libs/MyPayment
gen_bridge_metadata -F complete --no-64-bit -c '-DNDEBUG -I.' *.h -o プロジェクトのパス/libs/jsbindings/configs/MyPayment/MyPayment.bridgesupport
プロジェクトのパス/libs/jsbindings/generate_complement.py -o プロジェクトのパス/libs/jsbindings/configs/MyPayment/MyPayment-complement.txt *.h
プロジェクトのパス/libs/jsbindings/generate_jsb.py -c プロジェクトのパス/libs/jsbindings/configs/MyPayment/MyPayment_jsb.ini
shファイルは今後のために作っておきます。要は、ObjectiveCのヘッダファイルや設定(ini)ファイルを参考に、Javascriptに組み込めるファイルを出力してくれます。ちょっと難しく言うと、Javascript側をタダのラッパーと考えて、内部的には高速に実行出来るObjective-Cが呼ばれるようにしてくれるライブラリがあって、それに必要なファイルを作るのです。
で、ターミナルでgen_MyPayment.shを実行してうまく行けば色々とファイルが出力されますので、それを全てxcodeに追加します。
もう少しです。
今度は、以下のファイルを作ります。作る場所は、自動で出力されたファイルと同じであり、最初にクラスファイルを作ったフォルダが良いと思います。
jsb_MyPayment_registration.h
#ifndef __JSB_MYPAYMENT_REGISTRATION
#define __JSB_MYPAYMENT_REGISTRATION
void jsb_register_MyPayment( JSContext *globalC, JSObject *globalO);
#endif // __JSB_MYPAYMENT_REGISTRATION
jsb_MyPayment_registration.mm
#import "jsb_config.h"
#import "jsb_core.h"
#import "jsb_MyPayment_registration.h"
void jsb_register_MyPayment( JSContext *_cx, JSObject *object)
{
JSObject *myPayment = JS_NewObject(_cx, NULL, NULL, NULL);
jsval myPaymentVal = OBJECT_TO_JSVAL(myPayment);
JS_SetProperty(_cx, object, "myP", &myPaymentVal);
#import "jsb_MyPayment_classes_registration.h"
}
これで準備はほぼ整いましたので、ついに既存のファイルに組み込んで行きます。
「libs/jsbindings/src/manual」内の一部を変更します。
jsb_config.hに、以下の3行を追加。JSB_INCLUDE_COCOSBUILDERREADERの下辺りが良いでしょうか。
#ifndef JSB_INCLUDE_MYPAYMENT
#define JSB_INCLUDE_MYPAYMENT 1
#endif // JSB_INCLUDE_MYPAYMENT
jsb_core.mmの頭、importしてるそれらしき部分に以下を追加。
#import "jsb_MyPayment_registration.h"
同じファイルのJSB_NewGlobalObject関数内のそれっぽいところに、以下3行を追加。
#if JSB_INCLUDE_MYPAYMENT
jsb_register_MyPayment(cx, glob);
#endif // JSB_INCLUDE_MYPAYMENT
最後の最後に、Javascriptを入れます。
「libs/jsbindings/src/js」内に、以下ファイルを追加。
jsb_mypayment.js
var myP = myP || {};
myP.Payment = function() {
return myP.myPayment.create();
};
で、jsb.jsの最後に以下の1行を追加。
require('jsb_mypayment.js');
忘れてはならないのが、.jsファイルはコンパイル側に入ってしまうので、ビルドフェーズでコンパイル側から消し、リソース側に追加しとくことです。
なが~くなりましたが、これでCocosBuilder側のJavascriptで
myP.Payment().startBuy("プロダクトID");
を呼べば購入処理が行えます。
今回、自分が色々と作ったものを切り出した感じで書いてしまったため、要らないものも多々あると思います。ソースもほぼ手書きなので誤字脱字あったらごめんなさい。
この手順は最初だけで、次回からはクラスに関数を追加したらターミナルでshして終了です。JavascriptとObjective-C側でやり取りを行なったりしたい場合はiniファイル含めもうちょっと複雑になりますが、CocosBuilderやCocosDenshionが参考になります。
StoreKitを組み込んだ際、購入完了後にJavascript側で作ったコールバック関数を呼びたい!って事態になると思いますが、これこそ自分のやり方が間違ってる気がしてならない部分です。
以下は超メモ的に。
クラス側はこんな感じで
@interface MyPayment {
void (^block)(id sender);
}
- (void)setCompletedPaymentCallbackBlock:(void(^)(id sender))b;
@end
manual.mm側では登録用の関数用意して、処理内容を抜粋すると以下の感じ。
js_block js_func;
JSB_jsval_to_block_1( cx, argvp[1], js_this, &js_func );
MyPayment *real = (MyPayment*) [proxy realObj];
[real setCompletedPaymentCallbackBlock:(void(^)(id sender))js_func];
って感じで直接関数を保存しちゃって、StoreKitの購入完了後に
- (void)completePayment
{
if (block) block(self);
}
という感じでコールバックを実行してます。
Javascript側は
payment.setComplateCallback(this, this.complate);//callback登録
function complete() {
cc.log("complate!!");
}
みたいな感じです。
これで良いのかわかりませんが、ちゃんと動いていて、しかもAppleの審査に通り今もAppStoreに並んでたりします。だから多分不正解では無いと思います。誰かの参考になれば幸いです。
- 関連記事
-