mirror of
https://github.com/purplecabbage/phonegap-plugins.git
synced 2026-01-14 16:58:03 -05:00
262 lines
8.7 KiB
Objective-C
262 lines
8.7 KiB
Objective-C
//
|
|
// InAppPurchaseManager.m
|
|
// beetight
|
|
//
|
|
// Created by Matt Kane on 20/02/2011.
|
|
// Copyright 2011 Matt Kane. All rights reserved.
|
|
//
|
|
|
|
#import "InAppPurchaseManager.h"
|
|
|
|
// Help create NSNull objects for nil items (since neither NSArray nor NSDictionary can store nil values).
|
|
#define NILABLE(obj) ((obj) != nil ? (NSObject *)(obj) : (NSObject *)[NSNull null])
|
|
|
|
// To avoid compilation warning, declare JSONKit and SBJson's
|
|
// category methods without including their header files.
|
|
@interface NSArray (StubsForSerializers)
|
|
- (NSString *)cdvjk_JSONString;
|
|
- (NSString *)cdvjk_JSONRepresentation;
|
|
@end
|
|
|
|
// Helper category method to choose which JSON serializer to use.
|
|
@interface NSArray (cdvjk_JSONSerialize)
|
|
- (NSString *)cdvjk_JSONSerialize;
|
|
@end
|
|
|
|
@implementation NSArray (cdvjk_JSONSerialize)
|
|
- (NSString *)cdvjk_JSONSerialize {
|
|
return [self respondsToSelector:@selector(cdvjk_JSONString)] ? [self cdvjk_JSONString] : [self cdvjk_JSONRepresentation];
|
|
}
|
|
@end
|
|
|
|
@implementation InAppPurchaseManager
|
|
|
|
-(void) setup:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
|
|
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
|
|
}
|
|
|
|
- (void) requestProductData:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
if([arguments count] < 3) {
|
|
return;
|
|
}
|
|
NSLog(@"Getting product data");
|
|
NSSet *productIdentifiers = [NSSet setWithObject:[arguments objectAtIndex:0]];
|
|
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
|
|
|
|
ProductsRequestDelegate* delegate = [[[ProductsRequestDelegate alloc] init] retain];
|
|
delegate.command = self;
|
|
delegate.successCallback = [arguments objectAtIndex:1];
|
|
delegate.failCallback = [arguments objectAtIndex:2];
|
|
|
|
productsRequest.delegate = delegate;
|
|
[productsRequest start];
|
|
|
|
}
|
|
|
|
/**
|
|
* Request product data for the productIds given in the option with
|
|
* key "productIds". See js for further documentation.
|
|
*/
|
|
- (void) requestProductsData:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
if([arguments count] < 1) {
|
|
return;
|
|
}
|
|
|
|
NSSet *productIdentifiers = [NSSet setWithArray:[options objectForKey:@"productIds"]];
|
|
|
|
NSLog(@"Getting products data");
|
|
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
|
|
|
|
BatchProductsRequestDelegate* delegate = [[[BatchProductsRequestDelegate alloc] init] retain];
|
|
delegate.command = self;
|
|
delegate.callback = [arguments objectAtIndex:0];
|
|
|
|
productsRequest.delegate = delegate;
|
|
[productsRequest start];
|
|
}
|
|
|
|
- (void) makePurchase:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
NSLog(@"About to do IAP");
|
|
if([arguments count] < 1) {
|
|
return;
|
|
}
|
|
|
|
SKMutablePayment *payment = [SKMutablePayment paymentWithProductIdentifier:[arguments objectAtIndex:0]];
|
|
|
|
if([arguments count] > 1) {
|
|
id quantity = [arguments objectAtIndex:1];
|
|
if ([quantity respondsToSelector:@selector(integerValue)]) {
|
|
payment.quantity = [quantity integerValue];
|
|
}
|
|
}
|
|
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
|
}
|
|
|
|
- (void) restoreCompletedTransactions:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
|
|
{
|
|
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
|
|
}
|
|
|
|
// SKPaymentTransactionObserver methods
|
|
// called when the transaction status is updated
|
|
//
|
|
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
|
|
{
|
|
NSString *state, *error, *transactionIdentifier, *transactionReceipt, *productId;
|
|
NSInteger errorCode;
|
|
|
|
for (SKPaymentTransaction *transaction in transactions)
|
|
{
|
|
error = state = transactionIdentifier = transactionReceipt = productId = @"";
|
|
errorCode = 0;
|
|
|
|
switch (transaction.transactionState)
|
|
{
|
|
case SKPaymentTransactionStatePurchasing:
|
|
continue;
|
|
|
|
case SKPaymentTransactionStatePurchased:
|
|
state = @"PaymentTransactionStatePurchased";
|
|
transactionIdentifier = transaction.transactionIdentifier;
|
|
transactionReceipt = [[transaction transactionReceipt] base64EncodedString];
|
|
productId = transaction.payment.productIdentifier;
|
|
break;
|
|
|
|
case SKPaymentTransactionStateFailed:
|
|
state = @"PaymentTransactionStateFailed";
|
|
error = transaction.error.localizedDescription;
|
|
errorCode = transaction.error.code;
|
|
NSLog(@"error %d %@", errorCode, error);
|
|
|
|
break;
|
|
|
|
case SKPaymentTransactionStateRestored:
|
|
state = @"PaymentTransactionStateRestored";
|
|
transactionIdentifier = transaction.originalTransaction.transactionIdentifier;
|
|
transactionReceipt = [[transaction transactionReceipt] base64EncodedString];
|
|
productId = transaction.originalTransaction.payment.productIdentifier;
|
|
break;
|
|
|
|
default:
|
|
NSLog(@"Invalid state");
|
|
continue;
|
|
}
|
|
NSLog(@"state: %@", state);
|
|
NSArray *callbackArgs = [NSArray arrayWithObjects:
|
|
NILABLE(state),
|
|
[NSNumber numberWithInt:errorCode],
|
|
NILABLE(error),
|
|
NILABLE(transactionIdentifier),
|
|
NILABLE(productId),
|
|
NILABLE(transactionReceipt),
|
|
nil];
|
|
NSString *js = [NSString stringWithFormat:@"plugins.inAppPurchaseManager.updatedTransactionCallback.apply(plugins.inAppPurchaseManager, %@)", [callbackArgs cdvjk_JSONSerialize]];
|
|
NSLog(@"js: %@", js);
|
|
[self writeJavascript: js];
|
|
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
|
|
|
}
|
|
}
|
|
|
|
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
|
|
{
|
|
NSString *js = [NSString stringWithFormat:@"plugins.inAppPurchaseManager.onRestoreCompletedTransactionsFailed(%d)", error.code];
|
|
[self writeJavascript: js];
|
|
}
|
|
|
|
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
|
|
{
|
|
NSString *js = @"plugins.inAppPurchaseManager.onRestoreCompletedTransactionsFinished()";
|
|
[self writeJavascript: js];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ProductsRequestDelegate
|
|
|
|
@synthesize successCallback, failCallback, command;
|
|
|
|
|
|
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
|
|
{
|
|
NSLog(@"got iap product response");
|
|
for (SKProduct *product in response.products) {
|
|
NSLog(@"sending js for %@", product.productIdentifier);
|
|
NSArray *callbackArgs = [NSArray arrayWithObjects:
|
|
NILABLE(product.productIdentifier),
|
|
NILABLE(product.localizedTitle),
|
|
NILABLE(product.localizedDescription),
|
|
NILABLE(product.localizedPrice),
|
|
nil];
|
|
NSString *js = [NSString stringWithFormat:@"%@.apply(plugins.inAppPurchaseManager, %@)", successCallback, [callbackArgs cdvjk_JSONSerialize]];
|
|
NSLog(@"js: %@", js);
|
|
[command writeJavascript: js];
|
|
}
|
|
|
|
for (NSString *invalidProductId in response.invalidProductIdentifiers) {
|
|
NSLog(@"sending fail (%@) js for %@", failCallback, invalidProductId);
|
|
|
|
[command writeJavascript: [NSString stringWithFormat:@"%@('%@')", failCallback, invalidProductId]];
|
|
}
|
|
NSLog(@"done iap");
|
|
|
|
[command writeJavascript: [NSString stringWithFormat:@"%@('__DONE')", successCallback]];
|
|
|
|
[request release];
|
|
[self release];
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[successCallback release];
|
|
[failCallback release];
|
|
[command release];
|
|
[super dealloc];
|
|
}
|
|
|
|
|
|
@end
|
|
|
|
/**
|
|
* Receives product data for multiple productIds and passes arrays of
|
|
* js objects containing these data to a single callback method.
|
|
*/
|
|
@implementation BatchProductsRequestDelegate
|
|
|
|
@synthesize callback, command;
|
|
|
|
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
|
|
|
|
NSMutableArray *validProducts = [NSMutableArray array];
|
|
for (SKProduct *product in response.products) {
|
|
[validProducts addObject:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
NILABLE(product.productIdentifier), @"id",
|
|
NILABLE(product.localizedTitle), @"title",
|
|
NILABLE(product.localizedDescription), @"description",
|
|
NILABLE(product.localizedPrice), @"price",
|
|
nil]];
|
|
}
|
|
|
|
NSArray *callbackArgs = [NSArray arrayWithObjects:
|
|
NILABLE(validProducts),
|
|
NILABLE(response.invalidProductIdentifiers),
|
|
nil];
|
|
NSString *js = [NSString stringWithFormat:@"%@.apply(plugins.inAppPurchaseManager, %@);", callback, [callbackArgs cdvjk_JSONSerialize]];
|
|
[command writeJavascript: js];
|
|
|
|
[request release];
|
|
[self release];
|
|
}
|
|
|
|
- (void) dealloc {
|
|
[callback release];
|
|
[command release];
|
|
[super dealloc];
|
|
}
|
|
|
|
@end
|