ios-unity/purchase/StoreManager.m
2023-08-03 13:14:23 +08:00

145 lines
5.4 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
See LICENSE folder for this samples licensing information.
Abstract:
Retrieves product information from the App Store using SKRequestDelegate, SKProductsRequestDelegate, SKProductsResponse, and
SKProductsRequest. Notifies its observer with a list of products available for sale along with a list of invalid product identifiers. Logs an error
message if the product request failed.
*/
#import "Section.h"
#import "StoreManager.h"
@interface StoreManager()<SKRequestDelegate, SKProductsRequestDelegate>
/// Keeps track of all valid products. These products are available for sale in the App Store.
@property (strong) NSMutableArray *availableProducts;
/// Keeps track of all invalid product identifiers.
@property (strong) NSMutableArray *invalidProductIdentifiers;
/// Keeps a strong reference to the product request.
@property (strong) SKProductsRequest *productRequest;
@property (copy, nonatomic) void (^completionBlock) (PCSProductRequestStatus, NSMutableArray *);
@end
@implementation StoreManager
+ (StoreManager *)sharedInstance {
static dispatch_once_t onceToken;
static StoreManager * storeManagerSharedInstance;
dispatch_once(&onceToken, ^{
storeManagerSharedInstance = [[StoreManager alloc] init];
});
return storeManagerSharedInstance;
}
- (instancetype)init {
self = [super init];
if (self != nil) {
_availableProducts = [[NSMutableArray alloc] initWithCapacity:0];
_invalidProductIdentifiers = [[NSMutableArray alloc] initWithCapacity:0];
_storeResponse = [[NSMutableArray alloc] initWithCapacity:0];
_status = PCSProductRequestStatusNone;
}
return self;
}
#pragma mark - Request Information
/// Fetches information about your products from the App Store.
-(void)fetchProductsMatchingIdentifiers:(NSArray *)identifiers completionBlock: (void (^) (PCSProductRequestStatus status, NSMutableArray *resultAsString))completionBlock{
self.completionBlock = completionBlock;
// Create a set for the product identifiers.
NSSet *productIdentifiers = [NSSet setWithArray:identifiers];
// Initialize the product request with the above identifiers.
self.productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
self.productRequest.delegate = self;
// Send the request to the App Store.
[self.productRequest start];
}
#pragma mark - SKProductsRequestDelegate
/// Used to get the App Store's response to your request and notify your observer.
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
if (self.storeResponse.count > 0) {
[self.storeResponse removeAllObjects];
}
// products contains products whose identifiers have been recognized by the App Store. As such, they can be purchased.
if ((response.products).count > 0) {
self.availableProducts = [NSMutableArray arrayWithArray:response.products];
Section *section = [[Section alloc] initWithName:PCSProductsAvailableProducts elements:response.products];
[self.storeResponse addObject:section];
}
// invalidProductIdentifiers contains all product identifiers not recognized by the App Store.
if ((response.invalidProductIdentifiers).count > 0) {
self.invalidProductIdentifiers = [NSMutableArray arrayWithArray:response.invalidProductIdentifiers];
Section *section = [[Section alloc] initWithName:PCSProductsInvalidIdentifiers elements:response.invalidProductIdentifiers];
[self.storeResponse addObject:section];
}
if (self.storeResponse.count > 0) {
self.status = PCSStoreResponse;
if (_completionBlock) {
_completionBlock(self.status, self.storeResponse);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:PCSProductRequestNotification object:self];
});
}
}
#pragma mark - SKRequestDelegate
/// Called when the product request failed.
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
self.status = PCSRequestFailed;
self.message = error.localizedDescription;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:PCSProductRequestNotification object:self];
});
}
#pragma mark - Helper Methods
/// - returns: Existing product's title matching the specified product identifier.
-(NSString *)titleMatchingIdentifier:(NSString *)identifier {
NSString *title = nil;
// Search availableProducts for a product whose productIdentifier property matches identifier. Return its localized title when found.
for (SKProduct *product in self.availableProducts) {
if ([product.productIdentifier isEqualToString:identifier]) {
title = product.localizedTitle;
}
}
return title;
}
-(SKProduct *) productMatchingIdentifier:(NSString *)identifier {
SKProduct *result = nil;
for (SKProduct *product in self.availableProducts) {
if ([product.productIdentifier isEqualToString:identifier]) {
result = product;
}
}
return result;
}
/// - returns: Existing product's title associated with the specified payment transaction.
-(NSString *)titleMatchingPaymentTransaction:(SKPaymentTransaction *) transaction {
NSString *title = [self titleMatchingIdentifier:transaction.payment.productIdentifier];
return (title != nil) ? title : transaction.payment.productIdentifier;
}
@end