244 lines
11 KiB
Plaintext
244 lines
11 KiB
Plaintext
//
|
|
// UIViewController+Purchase.cpp
|
|
// Unity-iPhone
|
|
//
|
|
// Created by Hl Zhang on 2023/3/21.
|
|
//
|
|
|
|
#import "UIViewController+Purchase.h"
|
|
#import "UIViewController+Wallet.h"
|
|
#import "Utilities.h"
|
|
#import "StoreManager.h"
|
|
#import "StoreObserver.h"
|
|
#import "AppConfiguration.h"
|
|
#import <Foundation/Foundation.h>
|
|
#import "SKProduct+SKProductAdditions.h"
|
|
#include <string>
|
|
#import "NSString+Customer.h"
|
|
#include "JcWallet.h"
|
|
#import "GlobalData.h"
|
|
|
|
static Utilities *utility = nil;
|
|
|
|
|
|
@implementation UIViewController (Purchase)
|
|
-(void)initPurchaseEnv {
|
|
utility = [[Utilities alloc] init];
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self
|
|
// selector:@selector(handleProductRequestNotification:)
|
|
// name:PCSProductRequestNotification
|
|
// object:[StoreManager sharedInstance]];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handlePurchaseNotification:)
|
|
name:PCSPurchaseNotification
|
|
object:[StoreObserver sharedInstance]];
|
|
}
|
|
#pragma mark - Query products
|
|
/// Retrieves product information from the App Store.
|
|
- (void)queryProducts:(NSString *) funId products: (NSString *) products {
|
|
if (utility == nil) {
|
|
[self initPurchaseEnv];
|
|
}
|
|
if (products == nil || [products isEqualToString:@""]) {
|
|
NSLog(@"queryProducts with empty products: %@", products);
|
|
[self nativeCb:funId hasErr:YES dataStr:@"queryProducts with empty products"];
|
|
return;
|
|
}
|
|
// split products to array
|
|
NSArray *identifiers = [products componentsSeparatedByString:@","];
|
|
// First, let's check whether the user is allowed to make purchases. Proceed if they are allowed. Display an alert, otherwise.
|
|
if ([StoreObserver sharedInstance].isAuthorizedForPayments) {
|
|
// Fetch the product information.
|
|
[[StoreManager sharedInstance] fetchProductsMatchingIdentifiers:identifiers completionBlock: ^(PCSProductRequestStatus status, NSMutableArray *storeResponse){
|
|
if (status == PCSStoreResponse) {
|
|
// define json array to return
|
|
NSMutableArray *jsonArray = [[NSMutableArray alloc] init];
|
|
for (Section *section in storeResponse) {
|
|
NSArray *content = section.elements;
|
|
if ([section.name isEqualToString:PCSProductsAvailableProducts]) {
|
|
for (SKProduct *product in content) {
|
|
NSMutableDictionary *json = [[NSMutableDictionary alloc] init];
|
|
[json setObject:product.productIdentifier forKey:@"id"];
|
|
[json setObject:product.localizedTitle forKey:@"name"];
|
|
[json setObject:product.localizedDescription forKey:@"description"];
|
|
[json setObject:product.priceLocale.currencyCode forKey:@"currencyCode"];
|
|
[json setObject:product.price.stringValue forKey:@"priceValue"];
|
|
[json setObject:product.regularPrice forKey:@"priceShow"];
|
|
[jsonArray addObject:json];
|
|
}
|
|
} else if ([section.name isEqualToString:PCSProductsInvalidIdentifiers]) {
|
|
// if there are invalid product identifiers, show them.
|
|
NSLog(@"Invalid product identifiers: %@", section.name);
|
|
// [self nativeCb:funId hasErr:YES dataStr: section.name];
|
|
}
|
|
}
|
|
NSError *error;
|
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonArray options:NSJSONWritingPrettyPrinted error:&error];
|
|
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
if (!jsonData) {
|
|
NSLog(@"Got an error: %@", error);
|
|
[self nativeCb:funId hasErr:YES dataStr: [NSString stringWithFormat:@"%@", error]];
|
|
} else {
|
|
NSLog(@"jsonString: %@", jsonString);
|
|
[self nativeCb:funId hasErr:NO dataStr: jsonString];
|
|
}
|
|
|
|
} else if (status == PCSRequestFailed) {
|
|
NSLog(@"Product request failed with message: %@", [StoreManager sharedInstance].message);
|
|
[self nativeCb:funId hasErr:YES dataStr: [StoreManager sharedInstance].message];
|
|
}
|
|
}];
|
|
|
|
} else {
|
|
// Warn the user that they are not allowed to make purchases.
|
|
NSLog(@"User is not allowed to make payments (Payments are disabled in Settings).");
|
|
[self nativeCb:funId hasErr:YES dataStr: [NSString stringWithFormat:@"%@", PCSMessagesCannotMakePayments]];
|
|
}
|
|
|
|
}
|
|
|
|
#pragma mark - Query Purchase
|
|
- (void)queryPurchase:(NSString *)funId {
|
|
if (utility == nil) {
|
|
[self initPurchaseEnv];
|
|
}
|
|
NSArray *transations = [[StoreObserver sharedInstance] queryPendingTransactions];
|
|
// convert to json string
|
|
NSError *error;
|
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:transations options:NSJSONWritingPrettyPrinted error:&error];
|
|
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
[self nativeCb:funId hasErr:NO dataStr:jsonString];
|
|
}
|
|
|
|
#pragma mark - Begin Buy Product
|
|
- (void)beginBuy:(NSString *)funId productId:(NSString *)productId orderId:(NSString *)orderId {
|
|
if (utility == nil) {
|
|
[self initPurchaseEnv];
|
|
}
|
|
if (productId == nil || [productId isEqualToString:@""]) {
|
|
NSLog(@"beginBy with empty productId: %@", productId);
|
|
[self nativeCb:funId hasErr:YES dataStr:@"beginBy with empty productId"];
|
|
return;
|
|
}
|
|
// check if currentFunId is empty
|
|
if ([StoreObserver sharedInstance].funid != nil && ![[StoreObserver sharedInstance].funid isEqualToString:@""]) {
|
|
NSLog(@"beginBy with currentFunId: %@", [StoreObserver sharedInstance].funid);
|
|
[self nativeCb:funId hasErr:YES dataStr:@"other purchase is processing"];
|
|
return;
|
|
}
|
|
|
|
[StoreObserver sharedInstance].funid = funId;
|
|
SKProduct *product = [[StoreManager sharedInstance] productMatchingIdentifier: productId];
|
|
if (product == nil) {
|
|
NSLog(@"beginBy with empty product: %@", productId);
|
|
[StoreObserver sharedInstance].funid = nil;
|
|
[self nativeCb:funId hasErr:YES dataStr:@"beginBy with empty product"];
|
|
return;
|
|
}
|
|
if (orderId == nil || [orderId isEqualToString:@""]) {
|
|
NSLog(@"beginBy with empty orderId: %@", orderId);
|
|
[StoreObserver sharedInstance].funid = nil;
|
|
[self nativeCb:funId hasErr:YES dataStr:@"beginBy with empty orderId"];
|
|
return;
|
|
}
|
|
[[StoreObserver sharedInstance] buy:product orderId: orderId];
|
|
}
|
|
|
|
#pragma mark - Finish Transaction
|
|
- (void)finishTransaction:(NSString *)funId transactionId: (NSString *) transactionId {
|
|
[[StoreObserver sharedInstance] finishTransaction: transactionId];
|
|
[self nativeCb:funId hasErr:NO dataStr:@""];
|
|
}
|
|
|
|
/// Creates and displays an alert.
|
|
-(void)alertWithTitle:(NSString *)title message:(NSString *)message {
|
|
UIAlertController *alertController = [utility alertWithTitle:title message:message];
|
|
[self.navigationController presentViewController:alertController animated:YES completion:nil];
|
|
}
|
|
|
|
#pragma mark - Handle PCSProductRequest Notification
|
|
|
|
/// Updates the UI according to the product request notification result.
|
|
-(void)handleProductRequestNotification:(NSNotification *)notification {
|
|
StoreManager *productRequestNotification = (StoreManager*)notification.object;
|
|
PCSProductRequestStatus status = (PCSProductRequestStatus)productRequestNotification.status;
|
|
NSLog(@"handleProductRequestNotification status: %ld", (long)status);
|
|
}
|
|
|
|
#pragma mark - Handle PCSPurchase Notification
|
|
/// Updates the UI according to the purchase request notification result.
|
|
-(void)handlePurchaseNotification:(NSNotification *)notification {
|
|
NSDictionary* dic = notification.userInfo;
|
|
NSNumber *errcode = dic[@"errcode"];
|
|
NSLog(@"handlePurchaseNotification status: %@", errcode);
|
|
NSString *funid = [StoreObserver sharedInstance].funid;
|
|
[StoreObserver sharedInstance].funid = nil;
|
|
// check if errcode is zero or not
|
|
if (errcode != nil && [errcode intValue] != 0) {
|
|
[self nativeCb:funid hasErr:YES dataStr: [NSString stringWithFormat:@"%@", dic[@"errmsg"]]];
|
|
} else {
|
|
NSString *tid = dic[@"dataid"];
|
|
NSMutableArray *transactions = [[NSMutableArray alloc] init];
|
|
[transactions addObject:tid];
|
|
NSError *error;
|
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:transactions options:NSJSONWritingPrettyPrinted error:&error];
|
|
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
[self nativeCb:funid hasErr:NO dataStr: jsonString];
|
|
|
|
}
|
|
}
|
|
|
|
#pragma mark - Handle Restored Transactions
|
|
|
|
/// Handles succesful restored transactions. Switches to the Purchases view.
|
|
-(void)handleRestoredSucceededTransaction {
|
|
utility.restoreWasCalled = YES;
|
|
|
|
// Refresh the Purchases view with the restored purchases.
|
|
// [self switchToViewController:ParentViewControllerSegmentPurchases];
|
|
// [self.purchases reloadWithData:self.utility.dataSourceForPurchasesUI];
|
|
// self.segmentedControl.selectedSegmentIndex = ParentViewControllerSegmentPurchases;
|
|
}
|
|
|
|
extern "C" void nativeQueryProducts(const char *funid, const char *skuListStr) {
|
|
NSString *nfunid = [NSString stringWithCString:funid encoding:NSUTF8StringEncoding];
|
|
NSString *nParams = [NSString stringWithCString:skuListStr encoding:NSUTF8StringEncoding];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
|
|
[window.rootViewController queryProducts:nfunid products: nParams];
|
|
});
|
|
}
|
|
|
|
extern "C" void nativeBuyProduct(const char *funid, const char *productId, const char *orderId) {
|
|
[[GlobalData shareInstance] setFromJS:false];
|
|
NSString *nfunid = [NSString stringWithCString:funid encoding:NSUTF8StringEncoding];
|
|
NSString *nParam0 = [NSString stringWithCString:productId encoding:NSUTF8StringEncoding];
|
|
NSString *nParam1 = [NSString stringWithCString:orderId encoding:NSUTF8StringEncoding];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
|
|
[window.rootViewController beginBuy:nfunid productId: nParam0 orderId:nParam1];
|
|
});
|
|
}
|
|
|
|
extern "C" void nativeQueryPurchase(const char *funid) {
|
|
[[GlobalData shareInstance] setFromJS:false];
|
|
NSString *nfunid = [NSString stringWithCString:funid encoding:NSUTF8StringEncoding];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
|
|
[window.rootViewController queryPurchase:nfunid];
|
|
});
|
|
}
|
|
|
|
extern "C" void nativeFinishTransaction(const char *funid, const char *transactionId) {
|
|
[[GlobalData shareInstance] setFromJS:false];
|
|
NSString *nfunid = [NSString stringWithCString:funid encoding:NSUTF8StringEncoding];
|
|
NSString *nTransactionId = [NSString stringWithCString:transactionId encoding:NSUTF8StringEncoding];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
|
|
[window.rootViewController finishTransaction:nfunid transactionId: nTransactionId];
|
|
});
|
|
}
|
|
|
|
@end
|