Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Commit

Permalink
Release v1.1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
lgarbo committed Feb 23, 2022
1 parent 5096c5e commit d096957
Show file tree
Hide file tree
Showing 25 changed files with 274 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Glassfy.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Glassfy"
s.version = "1.1.7"
s.version = "1.1.8"
s.summary = "Subscription and in-app-purchase service."
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.source = { :git => "https://github.com/glassfy/ios-sdk.git", :tag => s.version.to_s }
Expand Down
8 changes: 6 additions & 2 deletions Glassfy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
81EFB54425A772D900706FCB /* GYAPIPermissionsResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 81EFB54225A772D900706FCB /* GYAPIPermissionsResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
81EFB54525A772D900706FCB /* GYAPIPermissionsResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 81EFB54325A772D900706FCB /* GYAPIPermissionsResponse.m */; };
81EFB54B25A772F200706FCB /* GYPermission.m in Sources */ = {isa = PBXBuildFile; fileRef = 81EFB54925A772F200706FCB /* GYPermission.m */; };
81FCCE8627C3CE0A00DF3D1A /* GYPurchaseDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 81FCCE8527C3CE0A00DF3D1A /* GYPurchaseDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -164,6 +165,7 @@
81EFB54325A772D900706FCB /* GYAPIPermissionsResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GYAPIPermissionsResponse.m; sourceTree = "<group>"; };
81EFB54925A772F200706FCB /* GYPermission.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GYPermission.m; sourceTree = "<group>"; };
81EFB55025A7736B00706FCB /* GYPermission+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GYPermission+Private.h"; sourceTree = "<group>"; };
81FCCE8527C3CE0A00DF3D1A /* GYPurchaseDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GYPurchaseDelegate.h; path = Public/GYPurchaseDelegate.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -265,6 +267,7 @@
8191E86A26690C850077BDD7 /* GYUserProperties.h */,
816EF2882661161200513FB1 /* GYUserProperties.m */,
81951CD226443F82003901F1 /* GYTypes.h */,
81FCCE8527C3CE0A00DF3D1A /* GYPurchaseDelegate.h */,
816830B3258B6EA100565968 /* Core */,
8104537B25909F380015A728 /* Data */,
817A1CC7258CE9C700D1BA10 /* Utils */,
Expand Down Expand Up @@ -344,6 +347,7 @@
81010F292590C1AB00B07DE4 /* GYAPIOfferingsResponse.h in Headers */,
81951CD726443F94003901F1 /* GYOfferings.h in Headers */,
8138BAB225924D0A005CB44E /* SKProductSubscriptionPeriod+GYEncode.h in Headers */,
81FCCE8627C3CE0A00DF3D1A /* GYPurchaseDelegate.h in Headers */,
817A1CF5258CF63600D1BA10 /* GYAPIManager.h in Headers */,
817A1CE7258CF46600D1BA10 /* GYCacheManager.h in Headers */,
81E1DC3225933FC7003B5EBD /* SKPayment+GYEncode.h in Headers */,
Expand Down Expand Up @@ -668,7 +672,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.1.7;
MARKETING_VERSION = 1.1.8;
PRODUCT_BUNDLE_IDENTIFIER = net.glassfy.sdk;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -695,7 +699,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.1.7;
MARKETING_VERSION = 1.1.8;
PRODUCT_BUNDLE_IDENTIFIER = net.glassfy.sdk;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Our SDK can be easly integrated through Cocoapods or Swift Package Manager
#### Integrate using Cocoapods
Add the pod to your Podfile:

```pod 'Glassfy', '~> 1.1.7'```
```pod 'Glassfy', '~> 1.1.8'```

Then, run the following command:

Expand Down
1 change: 1 addition & 0 deletions Source/GYAPIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)getInitWithInfoWithCompletion:(GYGetInitCompletion _Nullable)block;

- (void)getSku:(NSString *)skuid withCompletion:(GYGetSkuCompletion _Nullable)block;
- (void)getSkuWithProductId:(NSString *)productid promotionalId:(NSString *_Nullable)promoid withCompletion:(GYGetSkuCompletion _Nullable)block;
- (void)getOfferingsWithCompletion:(GYGetOfferingsCompletion _Nullable)block;
- (void)getPermissionsWithCompletion:(GYGetPermissionsCompletion _Nullable)block;

Expand Down
15 changes: 15 additions & 0 deletions Source/GYAPIManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ - (void)getSku:(NSString *)skuid withCompletion:(GYGetSkuCompletion)block
[self callApiWithRequest:req response:GYAPISkuResponse.class completion:block];
}

- (void)getSkuWithProductId:(NSString *)productid promotionalId:(NSString *)promoid withCompletion:(GYGetSkuCompletion)block
{
NSURLComponents *url = [self baseURLV0];
url.path = [url.path stringByAppendingPathComponent:@"sku"];
NSMutableArray<NSURLQueryItem*> *queryItems = [(url.queryItems ?: @[]) mutableCopy];
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"productid" value:productid]];
if (promoid && promoid.length > 0) {
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"promotionalid" value:promoid]];
}
url.queryItems = queryItems;

NSURLRequest *req = [self authorizedRequestWithComponents:url];
[self callApiWithRequest:req response:GYAPISkuResponse.class completion:block];
}

- (void)getOfferingsWithCompletion:(GYGetOfferingsCompletion)block
{
NSURLComponents *url = [self baseURLV0];
Expand Down
6 changes: 5 additions & 1 deletion Source/GYManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#import <Foundation/Foundation.h>
#import "GYTypes.h"
#import "GYPurchaseDelegate.h"
@class GYSku;


Expand All @@ -18,12 +19,15 @@ NS_ASSUME_NONNULL_BEGIN

+ (GYManager *)managerWithApiKey:(NSString *)apiKey watcherMode:(BOOL)watcherMode;

- (void)setPurchaseDelegate:(id<GYPurchaseDelegate>)delegate;

- (void)loginUser:(NSString *_Nullable)userId withCompletion:(GYErrorCompletion _Nullable)block;
- (void)logoutWithCompletion:(GYErrorCompletion _Nullable)block;

- (void)permissionsWithCompletion:(GYPermissionsCompletion)block;
- (void)offeringsWithCompletion:(GYOfferingsCompletion)block;
- (void)skuWithIdentifier:(NSString *)skuid completion:(GYSkuBlock)block;
- (void)skuWithId:(NSString *)skuid completion:(GYSkuBlock)block;
- (void)skuWithProductId:(NSString *)productid promotionalId:(NSString *_Nullable)promoid completion:(GYSkuBlock)block;

- (void)purchaseSku:(GYSku *)sku completion:(GYPaymentTransactionBlock)block;
- (void)purchaseSku:(GYSku *)sku withDiscount:(SKProductDiscount *_Nullable)discount completion:(GYPaymentTransactionBlock)block API_AVAILABLE(ios(12.2), macos(10.14.4), watchos(6.2));
Expand Down
99 changes: 87 additions & 12 deletions Source/GYManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ @interface GYManager() <SKPaymentTransactionObserver>
@property(nonatomic, assign) BOOL watcherMode;
@property(nonatomic, assign) BOOL initialized;

@property(nonatomic, weak) id<GYPurchaseDelegate> purchasesDelegate;
@property(nonatomic, strong) NSMapTable<GYSku*, GYPaymentTransactionBlock> *purchaseCompletions;
@end

Expand Down Expand Up @@ -69,6 +70,11 @@ - (void)dealloc
[NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)setPurchaseDelegate:(id<GYPurchaseDelegate>)delegate
{
_purchasesDelegate = delegate;
}

- (NSString *)apiKey
{
return self.api.apiKey;
Expand Down Expand Up @@ -130,7 +136,7 @@ - (void)offeringsWithCompletion:(GYOfferingsCompletion)block
}];
}

- (void)skuWithIdentifier:(NSString *)skuid completion:(GYSkuBlock)block
- (void)skuWithId:(NSString *)skuid completion:(GYSkuBlock)block
{
[self.api getSku:skuid withCompletion:^(GYAPISkuResponse *res, NSError *apiErr) {
GYSku *sku = res.sku;
Expand Down Expand Up @@ -162,6 +168,38 @@ - (void)skuWithIdentifier:(NSString *)skuid completion:(GYSkuBlock)block
}];
}

- (void)skuWithProductId:(NSString *)productid promotionalId:(NSString *)promoid completion:(GYSkuBlock)block
{
[self.api getSkuWithProductId:productid promotionalId:promoid withCompletion:^(GYAPISkuResponse *res, NSError *apiErr) {
GYSku *sku = res.sku;
[self.store productWithIdentifier:sku.productId completion:^(SKProduct *product, NSError *storeErr) {
sku.product = product;

NSError *err = apiErr ?: storeErr;
if (!err) {
if (!product) {
err = GYError.storeProductNotFound;
}
else if (@available(iOS 12.2, macOS 10.14.4, watchOS 6.2, *)) {
if (sku.promotionalId && !sku.discount) {
err = GYError.storeProductNotFound;
}
}
else if (sku.promotionalId) {
err = GYError.storeProductNotFound;
}
}

typeof(block) __strong completion = block;
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
err ? completion(nil, err) : completion(sku, nil);
});
}
}];
}];
}

- (void)purchaseSku:(GYSku *)sku completion:(GYPaymentTransactionBlock)block
{
[self purchaseSku:sku withDiscountId:sku.promotionalId completion:block];
Expand Down Expand Up @@ -295,6 +333,37 @@ - (void)applicationDidBecomeActive:(NSNotification *)notification

#pragma mark - SKPaymentTransactionObserver

- (BOOL)paymentQueue:(SKPaymentQueue *)queue shouldAddStorePayment:(SKPayment *)payment forProduct:(SKProduct *)product
{
if ([self.purchasesDelegate respondsToSelector:@selector(handlePromotedProductId:withPromotionalId:purchaseHandler:)])
{
NSString *promoid;
if (@available(iOS 12.2, *)) {
promoid = payment.paymentDiscount.identifier;
}
NSString *productid = product.productIdentifier;

typeof(self) __weak weakSelf = self;
[self.purchasesDelegate handlePromotedProductId:productid
withPromotionalId:promoid
purchaseHandler:^(GYPaymentTransactionBlock completionHandler)
{
dispatch_async(Glassfy.shared.glqueue, ^{
GYPaymentTransactionBlock completion = completionHandler ?: ^void(GYTransaction *tranansaction, NSError *err) {
GYLogInfo(@"Promotion completion handler");
};

GYSku *sku = [GYSku skuWithProduct:product];
[weakSelf.purchaseCompletions setObject:completion forKey:sku];

[SKPaymentQueue.defaultQueue addPayment:payment];
});
}];
return NO;
}
return YES;
}

- (void)paymentQueue:(nonnull SKPaymentQueue *)queue updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions
{
typeof(self) __weak weakSelf = self;
Expand All @@ -310,11 +379,11 @@ - (void)handleUpdatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)tra
GYTransaction *t = [GYTransaction transactionWithPaymentTransaction:transaction];
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
GYLog(@"TRANSACTION %@ PURCHASED", t.productIdentifier);
GYLog(@"TRANSACTION %@ PURCHASED", t.productId);
[self handlePurchasedTransaction:t];
break;
case SKPaymentTransactionStateRestored: // status from -[SKPaymentQueue restoreCompletedTransactions];
GYLog(@"TRANSACTION %@ RESTORED", t.productIdentifier);
GYLog(@"TRANSACTION %@ RESTORED", t.productId);
if (!restored) {
[self handleRestoredTransaction:t];
restored = YES;
Expand All @@ -324,15 +393,15 @@ - (void)handleUpdatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)tra
}
break;
case SKPaymentTransactionStateFailed:
GYLogErr(@"TRANSACTION %@ FAILED: %@", t.productIdentifier, t.paymentTransaction.error.debugDescription);
GYLogErr(@"TRANSACTION %@ FAILED: %@", t.productId, t.paymentTransaction.error.debugDescription);
[self handleFailedTransaction:t];
break;
case SKPaymentTransactionStateDeferred:
GYLog(@"TRANSACTION %@ DEFERRED", t.productIdentifier);
GYLog(@"TRANSACTION %@ DEFERRED", t.productId);
[self handleDeferredTransaction:t];
break;
case SKPaymentTransactionStatePurchasing:
GYLog(@"TRANSACTION %@ PURCHASING", t.productIdentifier);
GYLog(@"TRANSACTION %@ PURCHASING", t.productId);
break;
}
}
Expand All @@ -343,7 +412,7 @@ - (void)handlePurchasedTransaction:(GYTransaction *)t
GYPaymentTransactionBlock completion;
GYSku *sku;
for (GYSku *s in self.purchaseCompletions.keyEnumerator) {
if ([s.productId isEqualToString:t.productIdentifier]) {
if ([s.productId isEqualToString:t.productId]) {
sku = s;
completion = [self.purchaseCompletions objectForKey:s];
[self.purchaseCompletions removeObjectForKey:s];
Expand All @@ -361,7 +430,7 @@ - (void)handlePurchasedTransaction:(GYTransaction *)t
if (appStoreURL && [NSFileManager.defaultManager fileExistsAtPath:appStoreURL.path]) {
typeof(self) __weak weakSelf = self;
if (!sku) {
[self.store productWithIdentifier:t.productIdentifier completion:^(SKProduct *p, NSError *err) {
[self.store productWithIdentifier:t.productId completion:^(SKProduct *p, NSError *err) {
if (p) {
GYSku *s = [GYSku skuWithProduct:p];
[weakSelf.purchaseCompletions setObject:completion forKey:s];
Expand All @@ -377,6 +446,9 @@ - (void)handlePurchasedTransaction:(GYTransaction *)t
t.receiptValidated = (err.code != GYErrorCodeAppleReceiptStatusError);
dispatch_async(dispatch_get_main_queue(), ^{
completion(t, err);
if (!err && [weakSelf.purchasesDelegate respondsToSelector:@selector(didPurchaseProduct:)]) {
[weakSelf.purchasesDelegate didPurchaseProduct:t];
}
});
[weakSelf completeTransaction:t];
}];
Expand All @@ -394,6 +466,9 @@ - (void)handlePurchasedTransaction:(GYTransaction *)t
t.receiptValidated = (err.code != GYErrorCodeAppleReceiptStatusError);
dispatch_async(dispatch_get_main_queue(), ^{
completion(t, err);
if (!err && [weakSelf.purchasesDelegate respondsToSelector:@selector(didPurchaseProduct:)]) {
[weakSelf.purchasesDelegate didPurchaseProduct:t];
}
});
[weakSelf completeTransaction:t];
}];
Expand All @@ -418,7 +493,7 @@ - (void)handleFailedTransaction:(GYTransaction *)t

GYPaymentTransactionBlock completion;
for (GYSku *s in self.purchaseCompletions.keyEnumerator) {
if ([s.productId isEqualToString:t.productIdentifier]) {
if ([s.productId isEqualToString:t.productId]) {
completion = [self.purchaseCompletions objectForKey:s];
[self.purchaseCompletions removeObjectForKey:s];
break;
Expand Down Expand Up @@ -474,7 +549,7 @@ - (void)handleDeferredTransaction:(GYTransaction *)t
{
GYPaymentTransactionBlock completion;
for (GYSku *s in self.purchaseCompletions.keyEnumerator) {
if ([s.productId isEqualToString:t.productIdentifier]) {
if ([s.productId isEqualToString:t.productId]) {
completion = [self.purchaseCompletions objectForKey:s];
[self.purchaseCompletions removeObjectForKey:s];
break;
Expand All @@ -489,10 +564,10 @@ - (void)handleDeferredTransaction:(GYTransaction *)t

- (void)completeTransaction:(GYTransaction *)t
{
GYLog(@"TRANSACTION %@ COMPLETED", t.productIdentifier);
GYLog(@"TRANSACTION %@ COMPLETED", t.productId);

if (t.paymentTransaction && !self.watcherMode) {
GYLog(@"TRANSACTION %@ FINISH", t.productIdentifier);
GYLog(@"TRANSACTION %@ FINISH", t.productId);
[[SKPaymentQueue defaultQueue] finishTransaction:t.paymentTransaction];
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/GYOffering+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN

@interface GYOffering (Private) <GYDecodeProtocol>
// @property(nonatomic, nullable, strong) NSString *name;
@property(nonatomic, strong) NSString *identifier;
@property(nonatomic, strong) NSString *offeringId;
@property(nonatomic, strong) NSArray<GYSku*> *skus;
@end

Expand Down
17 changes: 10 additions & 7 deletions Source/GYOffering.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

@interface GYOffering()
//@property(nonatomic, nullable, strong) NSString *name;
@property(nonatomic, strong) NSString *identifier;
@property(nonatomic, strong) NSString *offeringId;
@property(nonatomic, strong) NSArray<GYSku*> *skus;
@end

Expand All @@ -23,10 +23,6 @@ - (instancetype)initWithObject:(nonnull NSDictionary *)obj error:(NSError **)err
if ([obj[@"identifier"] isKindOfClass:NSString.class]) {
identifier = obj[@"identifier"];
}
// NSString *name;
// if ([obj[@"name"] isKindOfClass:NSString.class]) {
// name = obj[@"name"];
// }

NSMutableArray<GYSku*> *skus = [NSMutableArray array];
if ([obj[@"skus"] isKindOfClass:NSArray.class]) {
Expand Down Expand Up @@ -54,8 +50,7 @@ - (instancetype)initWithObject:(nonnull NSDictionary *)obj error:(NSError **)err

self = [super init];
if (self) {
// self.name = name;
self.identifier = identifier;
self.offeringId = identifier;
self.skus = skus;
}
return self;
Expand All @@ -65,4 +60,12 @@ - (instancetype)initWithObject:(nonnull NSDictionary *)obj error:(NSError **)err


@implementation GYOffering

#pragma mark - Deprecations

- (NSString *)identifier
{
return self.offeringId;
}

@end
4 changes: 2 additions & 2 deletions Source/GYOfferings.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ @implementation GYOfferings

#pragma mark - Custom Keyed Subscripting method

- (GYOffering *)objectForKeyedSubscript:(NSString *)identifier
- (GYOffering *)objectForKeyedSubscript:(NSString *)offeringid
{
GYOffering *result = nil;
if (!self.all || self.all.count == 0) {
return result;
}

for (GYOffering *o in self.all) {
if ([o.identifier isEqualToString:identifier]) {
if ([o.offeringId isEqualToString:offeringid]) {
result = o;
break;
}
Expand Down
Loading

0 comments on commit d096957

Please sign in to comment.