diff --git a/AffirmSDK.xcodeproj/project.pbxproj b/AffirmSDK.xcodeproj/project.pbxproj index 889fb4d..096e59f 100644 --- a/AffirmSDK.xcodeproj/project.pbxproj +++ b/AffirmSDK.xcodeproj/project.pbxproj @@ -36,9 +36,9 @@ 08FA5921222D08E5007E5E4E /* AffirmSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FA5913222D08E5007E5E4E /* AffirmSDK.h */; settings = {ATTRIBUTES = (Public, ); }; }; 08FA592D222D1176007E5E4E /* AffirmUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FA592B222D1176007E5E4E /* AffirmUtils.m */; }; 08FA592E222D1176007E5E4E /* AffirmUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FA592B222D1176007E5E4E /* AffirmUtils.m */; }; - 79088B4D2238D20E0059D691 /* AffirmPrequalModalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79088B4B2238D20D0059D691 /* AffirmPrequalModalViewController.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 79088B4D2238D20E0059D691 /* AffirmPrequalModalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79088B4B2238D20D0059D691 /* AffirmPrequalModalViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 79088B4E2238D20E0059D691 /* AffirmPrequalModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79088B4C2238D20D0059D691 /* AffirmPrequalModalViewController.m */; }; - 79088B512238DB840059D691 /* AffirmPromoModalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79088B4F2238DB840059D691 /* AffirmPromoModalViewController.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 79088B512238DB840059D691 /* AffirmPromoModalViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79088B4F2238DB840059D691 /* AffirmPromoModalViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 79088B522238DB840059D691 /* AffirmPromoModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79088B502238DB840059D691 /* AffirmPromoModalViewController.m */; }; 7944D9932240BF830040525E /* AffirmActivityIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7944D9912240BF830040525E /* AffirmActivityIndicatorView.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7944D9942240BF830040525E /* AffirmActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7944D9922240BF830040525E /* AffirmActivityIndicatorView.m */; }; @@ -293,10 +293,10 @@ 0827FF8B2325EB9200AEC14C /* AffirmDataHandler.h in Headers */, 7944D9C12248A84D0040525E /* AffirmUtils.h in Headers */, 7944D9B72240E2250040525E /* AffirmLogger.h in Headers */, - 7944D9932240BF830040525E /* AffirmActivityIndicatorView.h in Headers */, + 79088B4D2238D20E0059D691 /* AffirmPrequalModalViewController.h in Headers */, 79088B512238DB840059D691 /* AffirmPromoModalViewController.h in Headers */, + 7944D9932240BF830040525E /* AffirmActivityIndicatorView.h in Headers */, DA77629D223F959F00FB2DB3 /* AffirmPopupViewController.h in Headers */, - 79088B4D2238D20E0059D691 /* AffirmPrequalModalViewController.h in Headers */, 0841E334223A9948006D8B97 /* AffirmConstants.h in Headers */, 08A81F49223F986D00FAA8D2 /* AffirmClient.h in Headers */, 08C4306C223B7C640009E045 /* AffirmRequest.h in Headers */, diff --git a/AffirmSDK/AffirmCheckoutViewController.m b/AffirmSDK/AffirmCheckoutViewController.m index 77913c2..a5722bd 100644 --- a/AffirmSDK/AffirmCheckoutViewController.m +++ b/AffirmSDK/AffirmCheckoutViewController.m @@ -70,7 +70,7 @@ + (AffirmCheckoutViewController *)startCheckout:(AffirmCheckout *)checkout return [[self alloc] initWithDelegate:delegate checkout:checkout useVCN:useVCN - getReasonCodes:NO]; + getReasonCodes:NO]; } + (AffirmCheckoutViewController *)startCheckout:(AffirmCheckout *)checkout @@ -81,7 +81,7 @@ + (AffirmCheckoutViewController *)startCheckout:(AffirmCheckout *)checkout return [[self alloc] initWithDelegate:delegate checkout:checkout useVCN:useVCN - getReasonCodes:getReasonCodes]; + getReasonCodes:getReasonCodes]; } - (void)viewDidLoad @@ -90,10 +90,16 @@ - (void)viewDidLoad self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStyleDone target:self - action:@selector(dismiss)]; + action:@selector(cancel:)]; [self prepareForCheckout]; } +- (void)cancel:(id)sender +{ + [self.delegate checkoutCancelled:self]; + [self dismiss]; +} + - (void)prepareForCheckout { [[AffirmLogger sharedInstance] trackEvent:@"Checkout initiated"]; @@ -137,11 +143,11 @@ - (void)loadRedirectURL:(NSURL *)redirectURL @"{{CONFIRM_CB_URL}}": AFFIRM_CHECKOUT_CONFIRMATION_URL, @"{{CANCELLED_CB_URL}}": AFFIRM_CHECKOUT_CANCELLATION_URL} enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { - rawContent = [rawContent stringByReplacingOccurrencesOfString:key - withString:obj - options:NSLiteralSearch - range:[rawContent rangeOfString:key]]; - }]; + rawContent = [rawContent stringByReplacingOccurrencesOfString:key + withString:obj + options:NSLiteralSearch + range:[rawContent rangeOfString:key]]; + }]; NSString *baseUrl = [NSString stringWithFormat:@"https://%@", redirectURL.host]; [self.webView loadData:[rawContent dataUsingEncoding:NSUTF8StringEncoding] MIMEType:@"text/html" characterEncodingName:@"utf-8" baseURL:[NSURL URLWithString:baseUrl]]; } else { @@ -181,26 +187,26 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati if (_getReasonCodes) { NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:URL.absoluteString]; - for(NSURLQueryItem *item in urlComponents.queryItems) { + for (NSURLQueryItem *item in urlComponents.queryItems) { if([item.name isEqualToString:@"data"]) { [self.delegate checkoutCancelled:self - checkoutCanceledWithReason:[AffirmReasonCode reasonCodeWithDict:item.value.convertToDictionary]]; - [[AffirmLogger sharedInstance] trackEvent:@"Checkout cancelled with reason" parameters:@{@"checkout_ari": self.checkoutARI, @"checkout_canceled_reason": item.value != nil ? item.value : @"false"}]; + checkoutCanceledWithReason:[AffirmReasonCode reasonCodeWithDict:item.value.convertToDictionary]]; + [[AffirmLogger sharedInstance] trackEvent:@"Checkout cancelled with reason" parameters:@{@"checkout_ari": self.checkoutARI, @"checkout_canceled_reason": item.value != nil ? item.value : @"false"}]; break; } } } else { - [self.delegate checkoutCancelled:self]; + [self.delegate checkoutCancelled:self]; [[AffirmLogger sharedInstance] trackEvent:@"Checkout cancelled" parameters:@{@"checkout_ari": self.checkoutARI}]; } decisionHandler(WKNavigationActionPolicyCancel); return; } [self webView:webView checkIfURL:URL.absoluteString isPopupWithCompletion:^(BOOL isPopup) { - + if (isPopup) { - + AffirmPopupViewController *viewController = [[AffirmPopupViewController alloc] initWithURL:URL]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; [self presentViewController:navController animated:YES completion:nil]; @@ -208,7 +214,7 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati decisionHandler(WKNavigationActionPolicyCancel); } else { - + decisionHandler(WKNavigationActionPolicyAllow); } }]; @@ -236,13 +242,13 @@ - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSStr [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { - completionHandler(NO); - }]]; + completionHandler(NO); + }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - completionHandler(YES); - }]]; + completionHandler(YES); + }]]; [self presentViewController:alertController animated:YES completion:^{}]; } diff --git a/AffirmSDK/AffirmConstants.h b/AffirmSDK/AffirmConstants.h index ff840c5..a989c80 100644 --- a/AffirmSDK/AffirmConstants.h +++ b/AffirmSDK/AffirmConstants.h @@ -37,4 +37,34 @@ typedef NS_ENUM(NSInteger, AffirmLocale) { AffirmLocaleCA }; +typedef NS_ENUM(NSInteger, AffirmPageType) { + AffirmPageTypeNone, + AffirmPageTypeBanner, + AffirmPageTypeCart, + AffirmPageTypeCategory, + AffirmPageTypeHomepage, + AffirmPageTypeLanding, + AffirmPageTypePayment, + AffirmPageTypeProduct, + AffirmPageTypeSearch +}; + +typedef NS_ENUM(NSInteger, AffirmLogoType) { + AffirmLogoTypeName, + AffirmLogoTypeText, + AffirmLogoTypeSymbol, + AffirmLogoTypeSymbolHollow +}; + +typedef NS_ENUM(NSInteger, AffirmColorType) { + AffirmColorTypeDefault, + AffirmColorTypeBlue, + AffirmColorTypeBlack, + AffirmColorTypeWhite, + AffirmColorTypeBlueBlack +}; + +NSString * FormatAffirmPageTypeString(AffirmPageType type); +NSString * FormatAffirmColorString(AffirmColorType type); + NS_ASSUME_NONNULL_END diff --git a/AffirmSDK/AffirmConstants.m b/AffirmSDK/AffirmConstants.m index 1308759..8b8247b 100644 --- a/AffirmSDK/AffirmConstants.m +++ b/AffirmSDK/AffirmConstants.m @@ -25,3 +25,42 @@ NSString *const AFFIRM_CHECKOUT_CONFIRMATION_URL = @"affirm://checkout/confirmed"; NSString *const AFFIRM_CHECKOUT_CANCELLATION_URL = @"affirm://checkout/cancelled"; +NSString * FormatAffirmPageTypeString(AffirmPageType type) +{ + switch (type) { + case AffirmPageTypeNone: + return nil; + case AffirmPageTypeBanner: + return @"banner"; + case AffirmPageTypeCart: + return @"cart"; + case AffirmPageTypeCategory: + return @"category"; + case AffirmPageTypeHomepage: + return @"homepage"; + case AffirmPageTypeLanding: + return @"landing"; + case AffirmPageTypePayment: + return @"payment"; + case AffirmPageTypeProduct: + return @"product"; + case AffirmPageTypeSearch: + return @"search"; + } +} + +NSString * FormatAffirmColorString(AffirmColorType type) +{ + switch (type) { + case AffirmColorTypeBlue: + return @"blue"; + case AffirmColorTypeBlack: + return @"black"; + case AffirmColorTypeWhite: + return @"white"; + case AffirmColorTypeBlueBlack: + return @"blue-black"; + case AffirmColorTypeDefault: + return @"blue"; + } +} diff --git a/AffirmSDK/AffirmDataHandler.m b/AffirmSDK/AffirmDataHandler.m index c97d92f..91e957d 100644 --- a/AffirmSDK/AffirmDataHandler.m +++ b/AffirmSDK/AffirmDataHandler.m @@ -137,6 +137,7 @@ + (void)getPromoMessageWithPromoID:(nullable NSString *)promoID } else { viewController = [[AffirmPromoModalViewController alloc] initWithPromoId:promoID amount:decimal + pageType:pageType delegate:delegate]; } } diff --git a/AffirmSDK/AffirmPromoModalViewController.h b/AffirmSDK/AffirmPromoModalViewController.h index f8f6ca7..72de87c 100644 --- a/AffirmSDK/AffirmPromoModalViewController.h +++ b/AffirmSDK/AffirmPromoModalViewController.h @@ -8,18 +8,45 @@ #import "AffirmBaseWebViewController.h" #import "AffirmPrequalDelegate.h" +#import "AffirmConstants.h" NS_ASSUME_NONNULL_BEGIN @interface AffirmPromoModalViewController : AffirmBaseWebViewController +/** + The delegate which handles promo modal events. + */ @property (nonatomic, weak) id delegate; +/** + Initializer. See properties for more details. UseVCN is NO as default + + @param promoId Promo ID to use when getting terms (provided by Affirm) + @param amount Amount of the transaction + @param delegate A delegate object which responds to the promo modal events created by the view controller. + @return The newly created promo view controller. + */ - (instancetype)initWithPromoId:(nullable NSString *)promoId amount:(NSDecimalNumber *)amount delegate:(id)delegate NS_SWIFT_NAME(init(promoId:amount:delegate:)) NS_DESIGNATED_INITIALIZER; +/** + Initializer. See properties for more details. UseVCN is NO as default + + @param promoId Promo ID to use when getting terms (provided by Affirm) + @param amount Amount of the transaction + @param pageType type of Affirm page to display + @param delegate A delegate object which responds to the promo modal events created by the view controller. + @return The newly created promo view controller. + */ +- (instancetype)initWithPromoId:(nullable NSString *)promoId + amount:(NSDecimalNumber *)amount + pageType:(AffirmPageType)pageType + delegate:(id)delegate +NS_SWIFT_NAME(init(promoId:amount:pageType:delegate:)) NS_DESIGNATED_INITIALIZER; + - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; diff --git a/AffirmSDK/AffirmPromoModalViewController.m b/AffirmSDK/AffirmPromoModalViewController.m index dfa1602..f4d963a 100644 --- a/AffirmSDK/AffirmPromoModalViewController.m +++ b/AffirmSDK/AffirmPromoModalViewController.m @@ -7,6 +7,7 @@ // #import "AffirmPromoModalViewController.h" +#import "AffirmPromotionalButton.h" #import "AffirmConfiguration.h" #import "AffirmUtils.h" #import "AffirmClient.h" @@ -25,18 +26,43 @@ - (instancetype)initWithPromoId:(nullable NSString *)promoId { [AffirmValidationUtils checkNotNil:amount name:@"amount"]; [AffirmValidationUtils checkNotNil:delegate name:@"delegate"]; - + if (self = [super initWithNibName:nil bundle:nil]) { - NSString *jsURL = [AffirmConfiguration sharedInstance].jsURL; - NSString *filePath = [[NSBundle resourceBundle] pathForResource:@"promo_modal_template" - ofType:@"html"]; - NSString *rawContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; - _htmlString = [NSString stringWithFormat:rawContent, [AffirmConfiguration sharedInstance].publicKey, jsURL, amount, promoId ?: @"", AFFIRM_CHECKOUT_CANCELLATION_URL]; - _delegate = delegate; + [self initializeHtmlWithPromoId:promoId amount:amount pageType:AffirmPageTypeNone delegate:delegate]; } return self; } +- (instancetype)initWithPromoId:(nullable NSString *)promoId + amount:(NSDecimalNumber *)amount + pageType:(AffirmPageType)pageType + delegate:(id)delegate +{ + [AffirmValidationUtils checkNotNil:amount name:@"amount"]; + [AffirmValidationUtils checkNotNil:delegate name:@"delegate"]; + + if (self = [super initWithNibName:nil bundle:nil]) { + [self initializeHtmlWithPromoId:promoId amount:amount pageType:pageType delegate:delegate]; + } + return self; +} + +- (void)initializeHtmlWithPromoId:(nullable NSString *)promoId + amount:(NSDecimalNumber *)amount + pageType:(AffirmPageType)pageType + delegate:(id)delegate +{ + NSString *jsURL = [AffirmConfiguration sharedInstance].jsURL; + NSString *filePath = [[NSBundle resourceBundle] pathForResource:@"promo_modal_template" + ofType:@"html"]; + NSString *rawContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + + NSString *promoIdString = promoId ?: @""; + NSString *pageTypeString = FormatAffirmPageTypeString(pageType) ?: @""; + _htmlString = [NSString stringWithFormat:rawContent, [AffirmConfiguration sharedInstance].publicKey, jsURL, amount, promoIdString, pageTypeString, promoIdString, AFFIRM_CHECKOUT_CANCELLATION_URL]; + _delegate = delegate; +} + - (void)viewDidLoad { [super viewDidLoad]; diff --git a/AffirmSDK/AffirmPromotionalButton.h b/AffirmSDK/AffirmPromotionalButton.h index 9b432ab..a272882 100644 --- a/AffirmSDK/AffirmPromotionalButton.h +++ b/AffirmSDK/AffirmPromotionalButton.h @@ -8,76 +8,10 @@ #import #import "AffirmPrequalDelegate.h" - -typedef NS_ENUM(NSInteger, AffirmPageType) { - AffirmPageTypeNone, - AffirmPageTypeBanner, - AffirmPageTypeCart, - AffirmPageTypeCategory, - AffirmPageTypeHomepage, - AffirmPageTypeLanding, - AffirmPageTypePayment, - AffirmPageTypeProduct, - AffirmPageTypeSearch -}; - -typedef NS_ENUM(NSInteger, AffirmLogoType) { - AffirmLogoTypeName, - AffirmLogoTypeText, - AffirmLogoTypeSymbol, - AffirmLogoTypeSymbolHollow -}; - -typedef NS_ENUM(NSInteger, AffirmColorType) { - AffirmColorTypeDefault, - AffirmColorTypeBlue, - AffirmColorTypeBlack, - AffirmColorTypeWhite, - AffirmColorTypeBlueBlack -}; +#import "AffirmConstants.h" NS_ASSUME_NONNULL_BEGIN -static NSString * FormatAffirmPageTypeString(AffirmPageType type) -{ - switch (type) { - case AffirmPageTypeNone: - return nil; - case AffirmPageTypeBanner: - return @"banner"; - case AffirmPageTypeCart: - return @"cart"; - case AffirmPageTypeCategory: - return @"category"; - case AffirmPageTypeHomepage: - return @"homepage"; - case AffirmPageTypeLanding: - return @"landing"; - case AffirmPageTypePayment: - return @"payment"; - case AffirmPageTypeProduct: - return @"product"; - case AffirmPageTypeSearch: - return @"search"; - } -} - -static NSString * FormatAffirmColorString(AffirmColorType type) -{ - switch (type) { - case AffirmColorTypeBlue: - return @"blue"; - case AffirmColorTypeBlack: - return @"black"; - case AffirmColorTypeWhite: - return @"white"; - case AffirmColorTypeBlueBlack: - return @"blue-black"; - case AffirmColorTypeDefault: - return @"blue"; - } -} - /** An AffirmPromotionalButton displays the contents of an Affirm as low as object which describes the merchant and the item. */ diff --git a/AffirmSDK/AffirmSDK.bundle/promo_modal_template.html b/AffirmSDK/AffirmSDK.bundle/promo_modal_template.html index 2627900..16c9c71 100644 --- a/AffirmSDK/AffirmSDK.bundle/promo_modal_template.html +++ b/AffirmSDK/AffirmSDK.bundle/promo_modal_template.html @@ -64,7 +64,7 @@ (function(l,g,m,e,a,f,b){var d,c=l[m]||{},h=document.createElement(f),n=document.getElementsByTagName(f)[0],k=function(a,b,c){return function(){a[b]._.push([c,arguments])}};c[e]=k(c,e,"set");d=c[e];c[a]={};c[a]._=[];d._=[];c[a][b]=k(c,a,b);a=0;for(b="set add save post open empty reset on off trigger ready setProduct".split(" ");a #import #import +#import +#import diff --git a/Examples/Examples/Base.lproj/Main.storyboard b/Examples/Examples/Base.lproj/Main.storyboard index 112aaa6..91889f4 100644 --- a/Examples/Examples/Base.lproj/Main.storyboard +++ b/Examples/Examples/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -20,10 +20,10 @@ - + - + - +