APKit

MIT Licence

How to use

The under code block only for OS X:

if ( ![NSData dataWithContentsOfURL:[NSBundle mainBundle].appStoreReceiptURL] ) {
  exit(173);
}

Can be used in Objective-C or swift:

pod 'APKit', '~> 0.3.1'

run command pod update --no-repo-update.

InAppDelegate.m

#import <StoreKit/StoreKit.h>
#import <APKit/APKit.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#warning Add transaction observer
    [[SKPaymentQueue defaultQueue] addTransactionObserver:[APStoreObserver sharedInstance]];

    return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
#warning Remove transaction observer
    [[SKPaymentQueue defaultQueue] removeTransactionObserver: [APStoreObserver sharedInstance]];
}

Set result listener:

- (instancetype)init {
    self = [super init];
    if ( self ) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handleProductRequestNotification:)
                                                     name:APProductRequestNotification
                                                   object:[APProductManager sharedInstance]];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handlePurchasesNotification:)
                                                     name:APPurchaseNotification
                                                   object:[APStoreObserver sharedInstance]];
    }
    return self;
}

handleProductRequestNotificationwill be fired when get response for product.

handlePurchasesNotification will be fired when get response for purchase.

Request product with identifier:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *productIdentifiers = @[
                                    @"1994101101",
                                    @"1994101102",
                                    @"1994101103"
                                    ];

    APProductManager *productManager = [APProductManager sharedInstance];
    [productManager
     fetchProductInformationForIds:productIdentifiers];
}
-(void)handleProductRequestNotification: (NSNotification *)notification {
    APProductManager *productRequestNotification = (APProductManager*)notification.object;
    APProductRequestStatus result = (APProductRequestStatus)productRequestNotification.status;

    if (result == APProductRequestSuccess) {
        NSLog(@"VALID: %@", productRequestNotification.availableProducts);
        NSLog(@"INVALID: %@", productRequestNotification.invalidProductIds);
    }
}

1994101103 is an invalid product identifier.

Purchase:

NSArray *productArray = productRequestNotification.availableProducts;
if ( productArray.count > 0 ) {
    SKProduct *product_1 = productArray.firstObject;

    APStoreObserver *storeObs = [APStoreObserver sharedInstance];
    [storeObs buy:product_1];
}
#pragma mark - Handle purchase notification

-(void)handlePurchasesNotification: (NSNotification *)notification {
    APStoreObserver *purchasesNotification = (APStoreObserver *)notification.object;
    APPurchaseStatus status = (APPurchaseStatus)purchasesNotification.status;

    switch ( status ) {
#pragma - Purchase
        case APPurchaseSucceeded: {
            NSLog(@"Purchase-Success: %@", purchasesNotification.productsPurchased);
            // Verify receipts step.
            [self verifyReceipts];
            break;
        }
        case APPurchaseFailed: {
            NSLog(@"Purchase-Failed %@", purchasesNotification.errorMessage);
            break;
        }
        case APPurchaseCancelled: {
            NSLog(@"Purchase-Cancelled!");
            break;
        }
#pragma - Restore
        case APRestoredSucceeded: {
            NSLog(@"Restored-Success: %@", purchasesNotification.productsRestored);
            break;
        }
        case APRestoredFailed: {
            NSLog(@"Restored-Failed %@", purchasesNotification.errorMessage);
            break;
        }
        case APRestoredCancelled: {
            NSLog(@"Restored-Cancelled!");
            break;
        }
        default:
            break;
    }
}

Watch for line 12, [self verifyReceipts]; it's important.

Verify receipt:

If you get some error, try to use SKReceiptRefreshRequest

NSURL *localReceiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *data = [NSData dataWithContentsOfURL:localReceiptURL];
NSString *receiptStr = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

send receiptStrto your server.

About local receipt verify local verify your receipt.

Release note
License

MIT.