Skip to content

Instantly share code, notes, and snippets.

@eofster
Last active August 8, 2016 12:25
Show Gist options
  • Save eofster/90765a154df290b35b82a0eebc467d02 to your computer and use it in GitHub Desktop.
Save eofster/90765a154df290b35b82a0eebc467d02 to your computer and use it in GitHub Desktop.
Objective-C version of the receipt attributes validation (in a single .m file)
@import Foundation;
#import "ReceiptChecksum.h"
#import "ReceiptPayload.h"
#import "ReceiptValidation.h"
@protocol ReceiptAttributes;
NS_ASSUME_NONNULL_BEGIN
@interface ReceiptAttributesValidation : NSObject <ReceiptValidation>
- (instancetype)initWithOrigin:(id<ReceiptValidation>)origin attributes:(id<ReceiptAttributes>)attributes NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
@protocol ReceiptAttributes <NSObject>
@property(readonly) NSString *identifier;
@property(readonly) NSString *version;
@property(readonly) NSData *guid;
@end
@interface ReceiptAttributesValidation ()
@property(nonatomic, readonly) id<ReceiptValidation> origin;
@property(nonatomic, readonly) id<ReceiptAttributes> attributes;
@end
NS_ASSUME_NONNULL_END
@implementation ReceiptAttributesValidation
- (instancetype)initWithOrigin:(nonnull id<ReceiptValidation>)origin attributes:(nonnull id<ReceiptAttributes>)attributes {
NSParameterAssert(origin);
NSParameterAssert(attributes);
if ((self = [super init])) {
_origin = origin;
_attributes = attributes;
}
return self;
}
- (instancetype)init {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"-init not available" userInfo:nil];
}
#pragma mark - ReceiptValidation
- (void)validateReceipt:(nonnull NSData *)data completion:(void (^ _Nonnull)(Result))completion {
NSParameterAssert(data);
NSParameterAssert(completion);
if ([self validateAttributesWithData:data]) {
[self.origin validateReceipt:data completion:completion];
} else {
completion(ResultReceiptIsInvalid);
}
}
#pragma mark - Private
- (BOOL)validateAttributesWithData:(nonnull NSData *)data {
NSParameterAssert(data);
ReceiptPayload *payload = [[ReceiptPayload alloc] initWithData:data];
if (payload) {
return [self validateAttributesWithPayload:payload];
} else {
return NO;
}
}
- (BOOL)validateAttributesWithPayload:(nonnull ReceiptPayload *)payload {
NSParameterAssert(payload);
ReceiptChecksum *checksum = [[ReceiptChecksum alloc] initWithGUID:self.attributes.guid opaque:payload.opaque identifier:payload.identifierData];
return [payload.identifier isEqualToString:self.attributes.identifier] &&
[payload.version isEqualToString:self.attributes.version] &&
[payload.checksum isEqualToData:checksum.dataValue];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment