ios-unity/Classes_cocos/UIViewController+Purchase.mm
2023-08-03 13:14:23 +08:00

204 lines
8.8 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"
static Utilities *utility = nil;
@interface UIViewController (Purchase)
@property (nonatomic) NSString *currentFunId;
@end
@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 (self.currentFunId != nil && ![self.currentFunId isEqualToString:@""]) {
NSLog(@"beginBy with currentFunId: %@", self.currentFunId);
[self nativeCb:funId hasErr:YES dataStr:@"other purchase is processing"];
return;
}
self.currentFunId = funId;
SKProduct *product = [[StoreManager sharedInstance] productMatchingIdentifier: productId];
if (product == nil) {
NSLog(@"beginBy with empty product: %@", productId);
self.currentFunId = nil;
[self nativeCb:funId hasErr:YES dataStr:@"beginBy with empty product"];
return;
}
if (orderId == nil || [orderId isEqualToString:@""]) {
NSLog(@"beginBy with empty orderId: %@", orderId);
self.currentFunId = 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);
// check if errcode is zero or not
self.currentFunId = nil;
if (errcode != nil && [errcode intValue] != 0) {
[self nativeCb:self.currentFunId 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:self.currentFunId 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;
}
@end