145 lines
5.4 KiB
Objective-C
145 lines
5.4 KiB
Objective-C
/*
|
||
See LICENSE folder for this sample’s 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
|