Commit d956de37 by Dima Bart

Merge pull request #157 from Shopify/task/ui-migration

Migrate view classes from framework to advanced sample app
parents 53102c3a 5c64de6e
......@@ -7,6 +7,42 @@
objects = {
/* Begin PBXBuildFile section */
842799661CB31498003AD0CE /* PaymentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 842799651CB31498003AD0CE /* PaymentViewController.m */; };
847612671CAB047600AB17AA /* DisclosureIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612251CAB047600AB17AA /* DisclosureIndicatorView.m */; };
847612681CAB047600AB17AA /* Theme+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612271CAB047600AB17AA /* Theme+Additions.m */; };
847612691CAB047600AB17AA /* Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612291CAB047600AB17AA /* Theme.m */; };
8476126A1CAB047600AB17AA /* VisualEffectView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476122B1CAB047600AB17AA /* VisualEffectView.m */; };
8476126C1CAB047600AB17AA /* ActionableFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612301CAB047600AB17AA /* ActionableFooterView.m */; };
8476126D1CAB047600AB17AA /* ActionableFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 847612311CAB047600AB17AA /* ActionableFooterView.xib */; };
8476126E1CAB047600AB17AA /* CheckoutButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612331CAB047600AB17AA /* CheckoutButton.m */; };
8476126F1CAB047600AB17AA /* ErrorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612351CAB047600AB17AA /* ErrorView.m */; };
847612701CAB047600AB17AA /* GradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612371CAB047600AB17AA /* GradientView.m */; };
847612711CAB047600AB17AA /* AsyncImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612391CAB047600AB17AA /* AsyncImageView.m */; };
847612721CAB047600AB17AA /* ProductViewPresentationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476123B1CAB047600AB17AA /* ProductViewPresentationController.m */; };
847612731CAB047600AB17AA /* ProductDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476123D1CAB047600AB17AA /* ProductDescriptionCell.m */; };
847612741CAB047600AB17AA /* ProductHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476123F1CAB047600AB17AA /* ProductHeaderCell.m */; };
847612751CAB047600AB17AA /* ProductImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612411CAB047600AB17AA /* ProductImageCell.m */; };
847612761CAB047600AB17AA /* ProductVariantCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612431CAB047600AB17AA /* ProductVariantCell.m */; };
847612771CAB047600AB17AA /* ProductView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612451CAB047600AB17AA /* ProductView.m */; };
847612781CAB047600AB17AA /* ProductViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612471CAB047600AB17AA /* ProductViewController.m */; };
8476127A1CAB047600AB17AA /* ProductViewHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476124A1CAB047600AB17AA /* ProductViewHeader.m */; };
8476127B1CAB047600AB17AA /* HeaderBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476124C1CAB047600AB17AA /* HeaderBackgroundView.m */; };
8476127C1CAB047600AB17AA /* HeaderOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476124E1CAB047600AB17AA /* HeaderOverlayView.m */; };
8476127D1CAB047600AB17AA /* ProductViewNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612501CAB047600AB17AA /* ProductViewNavigationController.m */; };
8476127E1CAB047600AB17AA /* OptionSelectionNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612531CAB047600AB17AA /* OptionSelectionNavigationController.m */; };
8476127F1CAB047600AB17AA /* OptionSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612551CAB047600AB17AA /* OptionSelectionViewController.m */; };
847612801CAB047600AB17AA /* OptionValueCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612571CAB047600AB17AA /* OptionValueCell.m */; };
847612811CAB047600AB17AA /* VariantSelectionPresentationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612591CAB047600AB17AA /* VariantSelectionPresentationController.m */; };
847612821CAB047600AB17AA /* OptionBreadCrumbsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476125B1CAB047600AB17AA /* OptionBreadCrumbsView.m */; };
847612831CAB047600AB17AA /* VariantOptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476125D1CAB047600AB17AA /* VariantOptionView.m */; };
847612841CAB047600AB17AA /* VariantSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476125F1CAB047600AB17AA /* VariantSelectionViewController.m */; };
847612961CAB059100AB17AA /* ImageKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612911CAB059100AB17AA /* ImageKit.m */; };
847612971CAB059100AB17AA /* UIButton+PaymentButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612931CAB059100AB17AA /* UIButton+PaymentButton.m */; };
847612981CAB059100AB17AA /* UIImage+PaymentButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 847612951CAB059100AB17AA /* UIImage+PaymentButton.m */; };
847612A01CAB05BE00AB17AA /* UIColor+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476129B1CAB05BE00AB17AA /* UIColor+BUYAdditions.m */; };
847612A11CAB05BE00AB17AA /* UIFont+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476129D1CAB05BE00AB17AA /* UIFont+BUYAdditions.m */; };
847612A21CAB05BE00AB17AA /* UIImage+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8476129F1CAB05BE00AB17AA /* UIImage+BUYAdditions.m */; };
84BA52EE1CB2E83C00AB1560 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BA52ED1CB2E83C00AB1560 /* NavigationController.m */; };
902C9B8C1BB06BF300FC456E /* GetShopOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 902C9B8B1BB06BF300FC456E /* GetShopOperation.m */; };
902C9B8F1BB0729F00FC456E /* ShippingRateTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 902C9B8E1BB0729F00FC456E /* ShippingRateTableViewCell.m */; };
902C9B921BB08FF500FC456E /* SummaryItemsTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 902C9B911BB08FF500FC456E /* SummaryItemsTableViewCell.m */; };
......@@ -15,6 +51,9 @@
90B2623E1BB0A47B006D888F /* ProductViewControllerThemeStyleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B2623D1BB0A47B006D888F /* ProductViewControllerThemeStyleTableViewCell.m */; };
90B262411BB0A726006D888F /* ProductViewControllerToggleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B262401BB0A726006D888F /* ProductViewControllerToggleTableViewCell.m */; };
90B262441BB18B10006D888F /* ProductViewControllerThemeTintColorTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B262431BB18B10006D888F /* ProductViewControllerThemeTintColorTableViewCell.m */; };
9A0B0C871CEC8F370037D68F /* BUYPaymentButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B0C861CEC8F370037D68F /* BUYPaymentButton.m */; };
9A0B0C921CEC90D40037D68F /* BUYImageKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B0C8F1CEC90D40037D68F /* BUYImageKit.m */; };
9A0B0C931CEC90D40037D68F /* UIFont+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B0C911CEC90D40037D68F /* UIFont+BUYAdditions.m */; };
BE3437A21BC5C19D00C71330 /* Buy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE34379F1BC5C18400C71330 /* Buy.framework */; };
BE3437A31BC5C19D00C71330 /* Buy.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BE34379F1BC5C18400C71330 /* Buy.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BE8B82511B8CF49D00E3F871 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BE8B82501B8CF49D00E3F871 /* main.m */; };
......@@ -83,6 +122,77 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
842799641CB31498003AD0CE /* PaymentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaymentViewController.h; sourceTree = "<group>"; };
842799651CB31498003AD0CE /* PaymentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PaymentViewController.m; sourceTree = "<group>"; };
847612241CAB047600AB17AA /* DisclosureIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisclosureIndicatorView.h; sourceTree = "<group>"; };
847612251CAB047600AB17AA /* DisclosureIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DisclosureIndicatorView.m; sourceTree = "<group>"; };
847612261CAB047600AB17AA /* Theme+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Theme+Additions.h"; sourceTree = "<group>"; };
847612271CAB047600AB17AA /* Theme+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Theme+Additions.m"; sourceTree = "<group>"; };
847612281CAB047600AB17AA /* Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Theme.h; sourceTree = "<group>"; };
847612291CAB047600AB17AA /* Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Theme.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
8476122A1CAB047600AB17AA /* VisualEffectView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisualEffectView.h; sourceTree = "<group>"; };
8476122B1CAB047600AB17AA /* VisualEffectView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VisualEffectView.m; sourceTree = "<group>"; };
8476122F1CAB047600AB17AA /* ActionableFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ActionableFooterView.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
847612301CAB047600AB17AA /* ActionableFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ActionableFooterView.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612311CAB047600AB17AA /* ActionableFooterView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ActionableFooterView.xib; sourceTree = "<group>"; };
847612321CAB047600AB17AA /* CheckoutButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CheckoutButton.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
847612331CAB047600AB17AA /* CheckoutButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CheckoutButton.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612341CAB047600AB17AA /* ErrorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ErrorView.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
847612351CAB047600AB17AA /* ErrorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ErrorView.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612361CAB047600AB17AA /* GradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GradientView.h; sourceTree = "<group>"; };
847612371CAB047600AB17AA /* GradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GradientView.m; sourceTree = "<group>"; };
847612381CAB047600AB17AA /* AsyncImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncImageView.h; sourceTree = "<group>"; };
847612391CAB047600AB17AA /* AsyncImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsyncImageView.m; sourceTree = "<group>"; };
8476123A1CAB047600AB17AA /* ProductViewPresentationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductViewPresentationController.h; sourceTree = "<group>"; };
8476123B1CAB047600AB17AA /* ProductViewPresentationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductViewPresentationController.m; sourceTree = "<group>"; };
8476123C1CAB047600AB17AA /* ProductDescriptionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductDescriptionCell.h; sourceTree = "<group>"; };
8476123D1CAB047600AB17AA /* ProductDescriptionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductDescriptionCell.m; sourceTree = "<group>"; };
8476123E1CAB047600AB17AA /* ProductHeaderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductHeaderCell.h; sourceTree = "<group>"; };
8476123F1CAB047600AB17AA /* ProductHeaderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductHeaderCell.m; sourceTree = "<group>"; };
847612401CAB047600AB17AA /* ProductImageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductImageCell.h; sourceTree = "<group>"; };
847612411CAB047600AB17AA /* ProductImageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductImageCell.m; sourceTree = "<group>"; };
847612421CAB047600AB17AA /* ProductVariantCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductVariantCell.h; sourceTree = "<group>"; };
847612431CAB047600AB17AA /* ProductVariantCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductVariantCell.m; sourceTree = "<group>"; };
847612441CAB047600AB17AA /* ProductView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ProductView.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
847612451CAB047600AB17AA /* ProductView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ProductView.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612461CAB047600AB17AA /* ProductViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductViewController.h; sourceTree = "<group>"; };
847612471CAB047600AB17AA /* ProductViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ProductViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612491CAB047600AB17AA /* ProductViewHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ProductViewHeader.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
8476124A1CAB047600AB17AA /* ProductViewHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductViewHeader.m; sourceTree = "<group>"; };
8476124B1CAB047600AB17AA /* HeaderBackgroundView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeaderBackgroundView.h; sourceTree = "<group>"; };
8476124C1CAB047600AB17AA /* HeaderBackgroundView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HeaderBackgroundView.m; sourceTree = "<group>"; };
8476124D1CAB047600AB17AA /* HeaderOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeaderOverlayView.h; sourceTree = "<group>"; };
8476124E1CAB047600AB17AA /* HeaderOverlayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HeaderOverlayView.m; sourceTree = "<group>"; };
8476124F1CAB047600AB17AA /* ProductViewNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductViewNavigationController.h; sourceTree = "<group>"; };
847612501CAB047600AB17AA /* ProductViewNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductViewNavigationController.m; sourceTree = "<group>"; };
847612521CAB047600AB17AA /* OptionSelectionNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionSelectionNavigationController.h; sourceTree = "<group>"; };
847612531CAB047600AB17AA /* OptionSelectionNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionSelectionNavigationController.m; sourceTree = "<group>"; };
847612541CAB047600AB17AA /* OptionSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionSelectionViewController.h; sourceTree = "<group>"; };
847612551CAB047600AB17AA /* OptionSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionSelectionViewController.m; sourceTree = "<group>"; };
847612561CAB047600AB17AA /* OptionValueCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionValueCell.h; sourceTree = "<group>"; };
847612571CAB047600AB17AA /* OptionValueCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionValueCell.m; sourceTree = "<group>"; };
847612581CAB047600AB17AA /* VariantSelectionPresentationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariantSelectionPresentationController.h; sourceTree = "<group>"; };
847612591CAB047600AB17AA /* VariantSelectionPresentationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VariantSelectionPresentationController.m; sourceTree = "<group>"; };
8476125A1CAB047600AB17AA /* OptionBreadCrumbsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionBreadCrumbsView.h; sourceTree = "<group>"; };
8476125B1CAB047600AB17AA /* OptionBreadCrumbsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionBreadCrumbsView.m; sourceTree = "<group>"; };
8476125C1CAB047600AB17AA /* VariantOptionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariantOptionView.h; sourceTree = "<group>"; };
8476125D1CAB047600AB17AA /* VariantOptionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VariantOptionView.m; sourceTree = "<group>"; };
8476125E1CAB047600AB17AA /* VariantSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariantSelectionViewController.h; sourceTree = "<group>"; };
8476125F1CAB047600AB17AA /* VariantSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VariantSelectionViewController.m; sourceTree = "<group>"; };
847612901CAB059100AB17AA /* ImageKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageKit.h; sourceTree = "<group>"; };
847612911CAB059100AB17AA /* ImageKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageKit.m; sourceTree = "<group>"; };
847612921CAB059100AB17AA /* UIButton+PaymentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+PaymentButton.h"; sourceTree = "<group>"; };
847612931CAB059100AB17AA /* UIButton+PaymentButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "UIButton+PaymentButton.m"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
847612941CAB059100AB17AA /* UIImage+PaymentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+PaymentButton.h"; sourceTree = "<group>"; };
847612951CAB059100AB17AA /* UIImage+PaymentButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+PaymentButton.m"; sourceTree = "<group>"; };
8476129A1CAB05BE00AB17AA /* UIColor+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+BUYAdditions.h"; sourceTree = "<group>"; };
8476129B1CAB05BE00AB17AA /* UIColor+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+BUYAdditions.m"; sourceTree = "<group>"; };
8476129C1CAB05BE00AB17AA /* UIFont+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+BUYAdditions.h"; sourceTree = "<group>"; };
8476129D1CAB05BE00AB17AA /* UIFont+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+BUYAdditions.m"; sourceTree = "<group>"; };
8476129E1CAB05BE00AB17AA /* UIImage+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+BUYAdditions.h"; sourceTree = "<group>"; };
8476129F1CAB05BE00AB17AA /* UIImage+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+BUYAdditions.m"; sourceTree = "<group>"; };
84BA52EC1CB2E83C00AB1560 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = "<group>"; };
84BA52ED1CB2E83C00AB1560 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = "<group>"; };
902C9B8A1BB06BF300FC456E /* GetShopOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetShopOperation.h; sourceTree = "<group>"; };
902C9B8B1BB06BF300FC456E /* GetShopOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GetShopOperation.m; sourceTree = "<group>"; };
902C9B8D1BB0729F00FC456E /* ShippingRateTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ShippingRateTableViewCell.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
......@@ -98,6 +208,12 @@
90B262401BB0A726006D888F /* ProductViewControllerToggleTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductViewControllerToggleTableViewCell.m; sourceTree = "<group>"; };
90B262421BB18B10006D888F /* ProductViewControllerThemeTintColorTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProductViewControllerThemeTintColorTableViewCell.h; sourceTree = "<group>"; };
90B262431BB18B10006D888F /* ProductViewControllerThemeTintColorTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProductViewControllerThemeTintColorTableViewCell.m; sourceTree = "<group>"; };
9A0B0C851CEC8F370037D68F /* BUYPaymentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYPaymentButton.h; sourceTree = "<group>"; };
9A0B0C861CEC8F370037D68F /* BUYPaymentButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYPaymentButton.m; sourceTree = "<group>"; };
9A0B0C8E1CEC90D40037D68F /* BUYImageKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYImageKit.h; sourceTree = "<group>"; };
9A0B0C8F1CEC90D40037D68F /* BUYImageKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYImageKit.m; sourceTree = "<group>"; };
9A0B0C901CEC90D40037D68F /* UIFont+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+BUYAdditions.h"; sourceTree = "<group>"; };
9A0B0C911CEC90D40037D68F /* UIFont+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+BUYAdditions.m"; sourceTree = "<group>"; };
BE34378F1BC5C18400C71330 /* Mobile Buy SDK.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Mobile Buy SDK.xcodeproj"; path = "../../Mobile Buy SDK/Mobile Buy SDK.xcodeproj"; sourceTree = "<group>"; };
BE5E28451B94F5C300D2ECB5 /* Mobile Buy SDK Advanced Sample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Mobile Buy SDK Advanced Sample.entitlements"; sourceTree = "<group>"; };
BE8B824B1B8CF49D00E3F871 /* Mobile Buy SDK Advanced Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mobile Buy SDK Advanced Sample.app"; sourceTree = BUILT_PRODUCTS_DIR; };
......@@ -135,6 +251,123 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
847612231CAB047600AB17AA /* Appearance */ = {
isa = PBXGroup;
children = (
847612261CAB047600AB17AA /* Theme+Additions.h */,
847612271CAB047600AB17AA /* Theme+Additions.m */,
847612281CAB047600AB17AA /* Theme.h */,
847612291CAB047600AB17AA /* Theme.m */,
8476122A1CAB047600AB17AA /* VisualEffectView.h */,
8476122B1CAB047600AB17AA /* VisualEffectView.m */,
);
path = Appearance;
sourceTree = "<group>";
};
8476122E1CAB047600AB17AA /* Product View */ = {
isa = PBXGroup;
children = (
8476122F1CAB047600AB17AA /* ActionableFooterView.h */,
847612301CAB047600AB17AA /* ActionableFooterView.m */,
847612311CAB047600AB17AA /* ActionableFooterView.xib */,
847612381CAB047600AB17AA /* AsyncImageView.h */,
847612391CAB047600AB17AA /* AsyncImageView.m */,
847612321CAB047600AB17AA /* CheckoutButton.h */,
847612331CAB047600AB17AA /* CheckoutButton.m */,
847612241CAB047600AB17AA /* DisclosureIndicatorView.h */,
847612251CAB047600AB17AA /* DisclosureIndicatorView.m */,
847612341CAB047600AB17AA /* ErrorView.h */,
847612351CAB047600AB17AA /* ErrorView.m */,
847612361CAB047600AB17AA /* GradientView.h */,
847612371CAB047600AB17AA /* GradientView.m */,
8476124B1CAB047600AB17AA /* HeaderBackgroundView.h */,
8476124C1CAB047600AB17AA /* HeaderBackgroundView.m */,
8476124D1CAB047600AB17AA /* HeaderOverlayView.h */,
8476124E1CAB047600AB17AA /* HeaderOverlayView.m */,
8476123C1CAB047600AB17AA /* ProductDescriptionCell.h */,
8476123D1CAB047600AB17AA /* ProductDescriptionCell.m */,
8476123E1CAB047600AB17AA /* ProductHeaderCell.h */,
8476123F1CAB047600AB17AA /* ProductHeaderCell.m */,
847612401CAB047600AB17AA /* ProductImageCell.h */,
847612411CAB047600AB17AA /* ProductImageCell.m */,
847612421CAB047600AB17AA /* ProductVariantCell.h */,
847612431CAB047600AB17AA /* ProductVariantCell.m */,
847612441CAB047600AB17AA /* ProductView.h */,
847612451CAB047600AB17AA /* ProductView.m */,
847612461CAB047600AB17AA /* ProductViewController.h */,
847612471CAB047600AB17AA /* ProductViewController.m */,
847612491CAB047600AB17AA /* ProductViewHeader.h */,
8476124A1CAB047600AB17AA /* ProductViewHeader.m */,
8476124F1CAB047600AB17AA /* ProductViewNavigationController.h */,
847612501CAB047600AB17AA /* ProductViewNavigationController.m */,
8476123A1CAB047600AB17AA /* ProductViewPresentationController.h */,
8476123B1CAB047600AB17AA /* ProductViewPresentationController.m */,
847612511CAB047600AB17AA /* Variant Selection */,
847612601CAB047600AB17AA /* View Controllers */,
);
path = "Product View";
sourceTree = "<group>";
};
847612511CAB047600AB17AA /* Variant Selection */ = {
isa = PBXGroup;
children = (
8476125A1CAB047600AB17AA /* OptionBreadCrumbsView.h */,
8476125B1CAB047600AB17AA /* OptionBreadCrumbsView.m */,
847612521CAB047600AB17AA /* OptionSelectionNavigationController.h */,
847612531CAB047600AB17AA /* OptionSelectionNavigationController.m */,
847612541CAB047600AB17AA /* OptionSelectionViewController.h */,
847612551CAB047600AB17AA /* OptionSelectionViewController.m */,
847612561CAB047600AB17AA /* OptionValueCell.h */,
847612571CAB047600AB17AA /* OptionValueCell.m */,
8476125C1CAB047600AB17AA /* VariantOptionView.h */,
8476125D1CAB047600AB17AA /* VariantOptionView.m */,
847612581CAB047600AB17AA /* VariantSelectionPresentationController.h */,
847612591CAB047600AB17AA /* VariantSelectionPresentationController.m */,
8476125E1CAB047600AB17AA /* VariantSelectionViewController.h */,
8476125F1CAB047600AB17AA /* VariantSelectionViewController.m */,
);
path = "Variant Selection";
sourceTree = "<group>";
};
847612601CAB047600AB17AA /* View Controllers */ = {
isa = PBXGroup;
children = (
842799641CB31498003AD0CE /* PaymentViewController.h */,
842799651CB31498003AD0CE /* PaymentViewController.m */,
84BA52EC1CB2E83C00AB1560 /* NavigationController.h */,
84BA52ED1CB2E83C00AB1560 /* NavigationController.m */,
);
path = "View Controllers";
sourceTree = "<group>";
};
8476128F1CAB059100AB17AA /* PaymentButton */ = {
isa = PBXGroup;
children = (
9A0B0C851CEC8F370037D68F /* BUYPaymentButton.h */,
9A0B0C861CEC8F370037D68F /* BUYPaymentButton.m */,
847612901CAB059100AB17AA /* ImageKit.h */,
847612911CAB059100AB17AA /* ImageKit.m */,
847612921CAB059100AB17AA /* UIButton+PaymentButton.h */,
847612931CAB059100AB17AA /* UIButton+PaymentButton.m */,
847612941CAB059100AB17AA /* UIImage+PaymentButton.h */,
847612951CAB059100AB17AA /* UIImage+PaymentButton.m */,
);
path = PaymentButton;
sourceTree = "<group>";
};
847612991CAB05BE00AB17AA /* UIKit Additions */ = {
isa = PBXGroup;
children = (
8476129A1CAB05BE00AB17AA /* UIColor+BUYAdditions.h */,
8476129B1CAB05BE00AB17AA /* UIColor+BUYAdditions.m */,
8476129C1CAB05BE00AB17AA /* UIFont+BUYAdditions.h */,
8476129D1CAB05BE00AB17AA /* UIFont+BUYAdditions.m */,
8476129E1CAB05BE00AB17AA /* UIImage+BUYAdditions.h */,
8476129F1CAB05BE00AB17AA /* UIImage+BUYAdditions.m */,
);
path = "UIKit Additions";
sourceTree = "<group>";
};
90B262451BB18BEF006D888F /* Table View Cells */ = {
isa = PBXGroup;
children = (
......@@ -152,6 +385,17 @@
name = "Table View Cells";
sourceTree = "<group>";
};
9A0B0C8D1CEC90D40037D68F /* Utils */ = {
isa = PBXGroup;
children = (
9A0B0C8E1CEC90D40037D68F /* BUYImageKit.h */,
9A0B0C8F1CEC90D40037D68F /* BUYImageKit.m */,
9A0B0C901CEC90D40037D68F /* UIFont+BUYAdditions.h */,
9A0B0C911CEC90D40037D68F /* UIFont+BUYAdditions.m */,
);
path = Utils;
sourceTree = "<group>";
};
BE3437901BC5C18400C71330 /* Products */ = {
isa = PBXGroup;
children = (
......@@ -183,15 +427,20 @@
BE8B824D1B8CF49D00E3F871 /* Mobile Buy SDK Advanced Sample */ = {
isa = PBXGroup;
children = (
BE5E28451B94F5C300D2ECB5 /* Mobile Buy SDK Advanced Sample.entitlements */,
BE8B82971B8E6A7100E3F871 /* Operations */,
BE8B82961B8E6A6900E3F871 /* View Controllers */,
BE948D4C1B95087A009AB20B /* Images.xcassets */,
BE8B82521B8CF49D00E3F871 /* AppDelegate.h */,
BE8B82531B8CF49D00E3F871 /* AppDelegate.m */,
BE8B825B1B8CF49D00E3F871 /* Main.storyboard */,
9A0B0C8D1CEC90D40037D68F /* Utils */,
847612231CAB047600AB17AA /* Appearance */,
8476128F1CAB059100AB17AA /* PaymentButton */,
BE948D4C1B95087A009AB20B /* Images.xcassets */,
BE8B82601B8CF49D00E3F871 /* LaunchScreen.xib */,
BE8B825B1B8CF49D00E3F871 /* Main.storyboard */,
BE5E28451B94F5C300D2ECB5 /* Mobile Buy SDK Advanced Sample.entitlements */,
BE8B82971B8E6A7100E3F871 /* Operations */,
8476122E1CAB047600AB17AA /* Product View */,
BE8B824E1B8CF49D00E3F871 /* Supporting Files */,
847612991CAB05BE00AB17AA /* UIKit Additions */,
BE8B82961B8E6A6900E3F871 /* View Controllers */,
);
path = "Mobile Buy SDK Advanced Sample";
sourceTree = "<group>";
......@@ -331,6 +580,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8476126D1CAB047600AB17AA /* ActionableFooterView.xib in Resources */,
BE948D4D1B95087A009AB20B /* Images.xcassets in Resources */,
BE8B825D1B8CF49D00E3F871 /* Main.storyboard in Resources */,
BE8B82621B8CF49D00E3F871 /* LaunchScreen.xib in Resources */,
......@@ -344,21 +594,59 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
847612A01CAB05BE00AB17AA /* UIColor+BUYAdditions.m in Sources */,
847612A11CAB05BE00AB17AA /* UIFont+BUYAdditions.m in Sources */,
BE948D491B9500DC009AB20B /* GetCompletionStatusOperation.m in Sources */,
8476127B1CAB047600AB17AA /* HeaderBackgroundView.m in Sources */,
BE8B82951B8E65D700E3F871 /* PreCheckoutViewController.m in Sources */,
8476127F1CAB047600AB17AA /* OptionSelectionViewController.m in Sources */,
9A0B0C871CEC8F370037D68F /* BUYPaymentButton.m in Sources */,
8476127C1CAB047600AB17AA /* HeaderOverlayView.m in Sources */,
8476127A1CAB047600AB17AA /* ProductViewHeader.m in Sources */,
847612841CAB047600AB17AA /* VariantSelectionViewController.m in Sources */,
90B2623E1BB0A47B006D888F /* ProductViewControllerThemeStyleTableViewCell.m in Sources */,
847612801CAB047600AB17AA /* OptionValueCell.m in Sources */,
847612821CAB047600AB17AA /* OptionBreadCrumbsView.m in Sources */,
902C9B921BB08FF500FC456E /* SummaryItemsTableViewCell.m in Sources */,
8476127D1CAB047600AB17AA /* ProductViewNavigationController.m in Sources */,
8476126F1CAB047600AB17AA /* ErrorView.m in Sources */,
847612811CAB047600AB17AA /* VariantSelectionPresentationController.m in Sources */,
847612781CAB047600AB17AA /* ProductViewController.m in Sources */,
8476126A1CAB047600AB17AA /* VisualEffectView.m in Sources */,
847612721CAB047600AB17AA /* ProductViewPresentationController.m in Sources */,
902C9B8C1BB06BF300FC456E /* GetShopOperation.m in Sources */,
847612731CAB047600AB17AA /* ProductDescriptionCell.m in Sources */,
8476126C1CAB047600AB17AA /* ActionableFooterView.m in Sources */,
902C9B8F1BB0729F00FC456E /* ShippingRateTableViewCell.m in Sources */,
BE8B829A1B8E72CC00E3F871 /* CheckoutViewController.m in Sources */,
847612681CAB047600AB17AA /* Theme+Additions.m in Sources */,
9A0B0C931CEC90D40037D68F /* UIFont+BUYAdditions.m in Sources */,
847612831CAB047600AB17AA /* VariantOptionView.m in Sources */,
847612981CAB059100AB17AA /* UIImage+PaymentButton.m in Sources */,
8476126E1CAB047600AB17AA /* CheckoutButton.m in Sources */,
8476127E1CAB047600AB17AA /* OptionSelectionNavigationController.m in Sources */,
847612971CAB059100AB17AA /* UIButton+PaymentButton.m in Sources */,
9A0B0C921CEC90D40037D68F /* BUYImageKit.m in Sources */,
847612761CAB047600AB17AA /* ProductVariantCell.m in Sources */,
847612691CAB047600AB17AA /* Theme.m in Sources */,
847612701CAB047600AB17AA /* GradientView.m in Sources */,
90B262441BB18B10006D888F /* ProductViewControllerThemeTintColorTableViewCell.m in Sources */,
90B262411BB0A726006D888F /* ProductViewControllerToggleTableViewCell.m in Sources */,
847612961CAB059100AB17AA /* ImageKit.m in Sources */,
847612A21CAB05BE00AB17AA /* UIImage+BUYAdditions.m in Sources */,
847612771CAB047600AB17AA /* ProductView.m in Sources */,
9079F5F41BB1AAA100CB1B35 /* CollectionListViewController.m in Sources */,
BE8B82541B8CF49D00E3F871 /* AppDelegate.m in Sources */,
BE8B827B1B8CFF0E00E3F871 /* GetShippingRatesOperation.m in Sources */,
842799661CB31498003AD0CE /* PaymentViewController.m in Sources */,
847612671CAB047600AB17AA /* DisclosureIndicatorView.m in Sources */,
BE8B82571B8CF49D00E3F871 /* ProductListViewController.m in Sources */,
BE8B82511B8CF49D00E3F871 /* main.m in Sources */,
BE8B82921B8E612700E3F871 /* ShippingRatesTableViewController.m in Sources */,
847612711CAB047600AB17AA /* AsyncImageView.m in Sources */,
84BA52EE1CB2E83C00AB1560 /* NavigationController.m in Sources */,
847612751CAB047600AB17AA /* ProductImageCell.m in Sources */,
847612741CAB047600AB17AA /* ProductHeaderCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
//
// BUYTheme+Additions.h
// Theme+Additions.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,52 +24,13 @@
// THE SOFTWARE.
//
#import "BUYTheme.h"
#import "BUYPaymentButton.h"
#import "Theme.h"
#define BUY_RGB(r, g, b) BUY_RGBA(r, g, b, 1)
#define BUY_RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
@interface BUYTheme (Additions)
@interface Theme (Additions)
#pragma mark - Colors
/**
* The product view background color used in various views based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)backgroundColor;
/**
* The background color for selected table view cells based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)selectedBackgroundColor;
/**
* The product view's table view separator color based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)separatorColor;
/**
* The product view's table view disclosure indicator color based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)disclosureIndicatorColor;
/**
* The Checkout button's text color based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)checkoutButtonTextColor;
/**
* Top gradient color
*
* @return A dark color
......@@ -77,82 +38,33 @@
+ (UIColor*)topGradientViewTopColor;
/**
* The background color for the error toast view in the product view
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)errorTintOverlayColor;
/**
* The navigation bar's title color based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)navigationBarTitleColor;
/**
* The variant selection's navigation bar's title color based on the theme
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)navigationBarTitleVariantSelectionColor;
/**
* The color for the product title text
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)productTitleColor;
/**
* The color for the product "compare at" text
*
* @return The color appropriate for the BUYThemeStyle
* @return The color appropriate for the ThemeStyle
*/
+ (UIColor*)comparePriceTextColor;
/**
* The color for the product's description text
*
* @return The color appropriate for the BUYThemeStyle
* @return The color appropriate for the ThemeStyle
*/
+ (UIColor*)descriptionTextColor;
/**
* The color for the variant option name text
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)variantOptionNameTextColor;
/**
* The color for the variant price text
*
* @return The color appropriate for the BUYThemeStyle
* @return The color appropriate for the ThemeStyle
*/
+ (UIColor*)variantPriceTextColor;
/**
* The color for the variant "sold out" text
*
* @return The color appropriate for the BUYThemeStyle
* @return The color appropriate for the ThemeStyle
*/
+ (UIColor*)variantSoldOutTextColor;
/**
* The background color for the variant selection bread crumb view
*
* @return The color appropriate for the BUYThemeStyle
*/
- (UIColor*)variantBreadcrumbsBackground;
/**
* The text color for the variant selection bread crumb view
*
* @return The color appropriate for the BUYThemeStyle
*/
+ (UIColor*)variantBreadcrumbsTextColor;
#pragma mark - Padding and Sizes
/**
......@@ -258,34 +170,4 @@ extern CGFloat const kBuyBottomGradientHeightWithoutPageControl;
*/
+ (UIFont*)errorLabelFont;
#pragma mark - Misc
/**
* Blur effect style for for the product view
*
* @return The blur effect appropriate for the theme
*/
- (UIBlurEffect*)blurEffect;
/**
* Activity indicator style for the product view when loading a product
*
* @return The activity indicator style appropriate for the theme
*/
- (UIActivityIndicatorViewStyle)activityIndicatorViewStyle;
/**
* Navigation bar style for the product view
*
* @return The navigation bar style appropriate for the theme
*/
- (UIBarStyle)navigationBarStyle;
/**
* Apple Pay button style for the product view
*
* @return The button style appropriate for the theme
*/
- (BUYPaymentButtonStyle)paymentButtonStyle;
@end
//
// BUYTheme+Additions.m
// Theme+Additions.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,63 +24,19 @@
// THE SOFTWARE.
//
#import "BUYTheme+Additions.h"
#import "Theme+Additions.h"
#import "UIFont+BUYAdditions.h"
#import "UIColor+BUYAdditions.h"
@implementation BUYTheme (Additions)
@implementation Theme (Additions)
#pragma mark - Colors
- (UIColor*)backgroundColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(26, 26, 26) : [UIColor whiteColor];
}
- (UIColor*)selectedBackgroundColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(60, 60, 60) : BUY_RGB(242, 242, 242);
}
- (UIColor*)separatorColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(217, 217, 217);
}
- (UIColor*)disclosureIndicatorColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(191, 191, 191);
}
- (UIColor*)checkoutButtonTextColor
{
return self.style == BUYThemeStyleLight ? [UIColor whiteColor] : [UIColor blackColor];
}
+ (UIColor*)topGradientViewTopColor
{
return [UIColor colorWithWhite:0 alpha:0.25f];
}
- (UIColor*)errorTintOverlayColor
{
return self.style == BUYThemeStyleDark ? BUY_RGBA(255, 66, 66, 0.75f) : BUY_RGBA(209, 44, 44, 0.75f);
}
- (UIColor*)navigationBarTitleColor
{
return self.style == BUYThemeStyleDark ? [UIColor whiteColor] : [UIColor blackColor];
}
- (UIColor*)navigationBarTitleVariantSelectionColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(229, 229, 229) : [UIColor blackColor];
}
- (UIColor*)productTitleColor
{
return self.style == BUYThemeStyleDark ? [UIColor whiteColor] : [UIColor blackColor];
}
+ (UIColor*)comparePriceTextColor
{
return [UIColor colorWithWhite:0.4f alpha:1];
......@@ -91,11 +47,6 @@
return [UIColor colorWithWhite:0.4f alpha:1];
}
- (UIColor*)variantOptionNameTextColor
{
return self.style == BUYThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(191, 191, 191);
}
+ (UIColor*)variantPriceTextColor
{
return BUY_RGB(140, 140, 140);
......@@ -106,16 +57,6 @@
return BUY_RGB(220, 96, 96);
}
- (UIColor*)variantBreadcrumbsBackground
{
return self.style == BUYThemeStyleDark ? BUY_RGB(13, 13, 13) : BUY_RGB(229, 229, 229);
}
+ (UIColor*)variantBreadcrumbsTextColor
{
return BUY_RGB(140, 140, 140);
}
#pragma mark - Padding and Sizes
CGFloat const kBuyPaddingSmall = 8.0f;
......@@ -180,26 +121,4 @@ CGFloat const kBuyBottomGradientHeightWithoutPageControl = 20.0f;
return [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
}
#pragma mark - Misc
- (UIBlurEffect*)blurEffect
{
return [UIBlurEffect effectWithStyle:self.style == BUYThemeStyleDark ? UIBlurEffectStyleDark : UIBlurEffectStyleLight];
}
- (UIActivityIndicatorViewStyle)activityIndicatorViewStyle
{
return self.style == BUYThemeStyleDark ? UIActivityIndicatorViewStyleWhite : UIActivityIndicatorViewStyleGray;
}
- (UIBarStyle)navigationBarStyle
{
return self.style == BUYThemeStyleDark ? UIBarStyleBlack : UIBarStyleDefault;
}
- (BUYPaymentButtonStyle)paymentButtonStyle
{
return self.style == BUYThemeStyleLight ? BUYPaymentButtonStyleBlack : BUYPaymentButtonStyleWhite;
}
@end
//
// BUYTheme.h
// Theme.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -29,49 +29,38 @@
/**
* The theme style for the BUYProductViewController
*/
typedef NS_ENUM(NSInteger, BUYThemeStyle){
typedef NS_ENUM(NSInteger, ThemeStyle) {
/**
* Light theme style, providing light backgrounds and light styled UIVisualEffectViews
*/
BUYThemeStyleLight,
ThemeStyleLight,
/**
* Dark theme style, providing dark backgrounds and dark styled UIVisualEffectViews
*/
BUYThemeStyleDark
ThemeStyleDark
};
/**
* This class provides properties used for theming the BUYProductViewController UI elements.
*/
@interface BUYTheme : NSObject
@interface Theme : NSObject
/**
* Used for the highlight color
* Used for the highlight color. Default is the tintColor of the app's keyWindow if not nil,
* other falls back to a "Shopify green" color
*/
@property (nonatomic, strong) UIColor *tintColor;
/**
* Theme style for the views
*/
@property (nonatomic, assign) BUYThemeStyle style;
@property (nonatomic, assign) ThemeStyle style;
/**
* Determines whether a blurred scaled-up product image should appear behind the product details. Default is YES
*/
@property (nonatomic, assign) BOOL showsProductImageBackground;
@end
/**
* Protocol to enable theming for any class
*/
@protocol BUYThemeable <NSObject>
/**
* Sets the theme for the view, and its subviews
*
* @param theme The new theme to apply
*/
- (void)setTheme:(BUYTheme *)theme;
- (void)styleProductViewController;
@end
//
// Theme.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "DisclosureIndicatorView.h"
#import "ErrorView.h"
#import "NavigationController.h"
#import "OptionSelectionNavigationController.h"
#import "OptionValueCell.h"
#import "ProductDescriptionCell.h"
#import "ProductHeaderCell.h"
#import "ProductVariantCell.h"
#import "OptionBreadCrumbsView.h"
#import "HeaderOverlayView.h"
#import "ProductViewNavigationController.h"
#import "ProductViewController.h"
#import "ProductView.h"
#import "Theme.h"
#import "Theme+Additions.h"
#import "VariantOptionView.h"
#import "VisualEffectView.h"
#import "UIColor+BUYAdditions.h"
#import "CheckoutButton.h"
@implementation Theme
- (instancetype)init
{
self = [super init];
if (self) {
self.style = ThemeStyleLight;
self.showsProductImageBackground = YES;
}
return self;
}
- (void)styleProductViewController
{
UIColor *contentBackgroundColor = self.style == ThemeStyleDark ? BUY_RGB(26, 26, 26) : [UIColor whiteColor];
UIColor *contentBackgroundSelectedColor = self.style == ThemeStyleDark ? BUY_RGB(60, 60, 60) : BUY_RGB(242, 242, 242);
UIColor *contentBackgroundComplimentaryColor = self.style == ThemeStyleDark ? [UIColor whiteColor] : [UIColor blackColor];
UIColor *primaryColor = self.tintColor;
UIColor *secondaryLightColor = self.style == ThemeStyleDark ? BUY_RGB(13, 13, 13) : BUY_RGB(229, 229, 229);
UIColor *secondaryMediumColor = self.style == ThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(217, 217, 217);
UIColor *secondaryDarkColor = self.style == ThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(191, 191, 191);
UIBarStyle barStyle = self.style == ThemeStyleDark ? UIBarStyleBlack : UIBarStyleDefault;
UIColor *errorColor = self.style == ThemeStyleDark ? BUY_RGBA(255, 66, 66, 0.75f) : BUY_RGBA(209, 44, 44, 0.75f);
UIBlurEffectStyle blurEffectStyle = self.style == ThemeStyleDark ? UIBlurEffectStyleDark : UIBlurEffectStyleLight;
UIScrollViewIndicatorStyle scrollViewIndicatorStyle = self.style == ThemeStyleDark ? UIScrollViewIndicatorStyleWhite : UIScrollViewIndicatorStyleDefault;
// Add some Theme-specific styling:
UIColor *navigationBarTitleColor = self.style == ThemeStyleDark ? [UIColor whiteColor] : [UIColor blackColor];
UIColor *navigationBarTitleVariantSelectionColor = self.style == ThemeStyleDark ? BUY_RGB(229, 229, 229) : [UIColor blackColor];
if ([[UINavigationBar class] respondsToSelector:@selector(appearanceWhenContainedInInstancesOfClasses:)]) {
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[OptionSelectionNavigationController class]]] setTitleTextAttributes:@{ NSForegroundColorAttributeName : navigationBarTitleVariantSelectionColor }];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setTitleTextAttributes:@{ NSForegroundColorAttributeName : navigationBarTitleColor }];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setTintColor:primaryColor];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setBarStyle:barStyle];
[[UITableView appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setBackgroundColor:contentBackgroundColor];
[[UITableView appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setSeparatorColor:secondaryMediumColor];
[[UIScrollView appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setIndicatorStyle:scrollViewIndicatorStyle];
[[UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[ProductViewController class]]] setColor:primaryColor];
} else {
[[UINavigationBar appearanceWhenContainedIn:[OptionSelectionNavigationController class], nil] setTitleTextAttributes:@{ NSForegroundColorAttributeName : navigationBarTitleVariantSelectionColor }];
[[UINavigationBar appearanceWhenContainedIn:[NavigationController class], nil] setTitleTextAttributes:@{ NSForegroundColorAttributeName : navigationBarTitleColor }];
[[UINavigationBar appearanceWhenContainedIn:[NavigationController class], nil] setTintColor:primaryColor];
[[UINavigationBar appearanceWhenContainedIn:[NavigationController class], nil] setBarStyle:barStyle];
[[UITableView appearanceWhenContainedIn:[NavigationController class], nil] setBackgroundColor:contentBackgroundColor];
[[UITableView appearanceWhenContainedIn:[NavigationController class], nil] setSeparatorColor:secondaryMediumColor];
[[UIScrollView appearanceWhenContainedIn:[NavigationController class], nil] setIndicatorStyle:scrollViewIndicatorStyle];
[[UIActivityIndicatorView appearanceWhenContainedIn:[ProductViewController class], nil] setColor:primaryColor];
}
[[ProductView appearance] setTintColor:primaryColor];
[[ProductView appearance] setShowsProductImageBackground:self.showsProductImageBackground];
[[VariantOptionView appearance] setOptionNameTextColor:self.style == ThemeStyleDark ? BUY_RGB(76, 76, 76) : BUY_RGB(191, 191, 191)];
[[VisualEffectView appearance] setBlurEffectStyle:blurEffectStyle];
[[CheckoutButton appearance] setBackgroundColor:primaryColor];
[[CheckoutButton appearance] setTextColor:contentBackgroundColor];
[[DisclosureIndicatorView appearance] setTintColor:secondaryDarkColor];
[[ErrorView appearance] setOverlayColor:errorColor];
[[ProductView appearance] setBackgroundColor:contentBackgroundColor];
[[ProductHeaderCell appearance] setProductTitleColor:contentBackgroundComplimentaryColor];
[[ProductHeaderCell appearance] setBackgroundColor:contentBackgroundColor];
[[ProductDescriptionCell appearance] setBackgroundColor:contentBackgroundColor];
[[ProductVariantCell appearance] setBackgroundColor:contentBackgroundColor];
[[ProductVariantCell appearance] setSelectedBackgroundViewBackgroundColor:contentBackgroundSelectedColor];
[[VariantOptionView appearance] setBackgroundColor:contentBackgroundColor];
[[OptionValueCell appearance] setTintColor:primaryColor];
[[OptionValueCell appearance] setBackgroundColor:contentBackgroundColor];
[[OptionValueCell appearance] setSelectedBackgroundViewBackgroundColor:contentBackgroundSelectedColor];
[[HeaderOverlayView appearance] setOverlayBackgroundColor:contentBackgroundColor];
[[OptionBreadCrumbsView appearance] setBackgroundColor:secondaryLightColor];
[[OptionBreadCrumbsView appearance] setVariantOptionTextColor:BUY_RGB(140, 140, 140)];
}
@end
//
// VisualEffectView.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
@interface VisualEffectView : UIVisualEffectView
- (void)setBlurEffectStyle:(UIBlurEffectStyle)blurEffectStyle UI_APPEARANCE_SELECTOR;
@end
//
// VisualEffectView.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "VisualEffectView.h"
@implementation VisualEffectView
- (void)setBlurEffectStyle:(UIBlurEffectStyle)blurEffectStyle
{
self.effect = [UIBlurEffect effectWithStyle:blurEffectStyle];
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="rS3-R9-Ivy">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="rS3-R9-Ivy">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
</dependencies>
<scenes>
<!--Master-->
......@@ -11,6 +11,7 @@
<navigationController title="Master" id="rS3-R9-Ivy" sceneMemberID="viewController">
<navigationBar key="navigationBar" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="yXu-0R-QUA">
<autoresizingMask key="autoresizingMask"/>
<animations/>
</navigationBar>
<connections>
<segue destination="pGg-6v-bdr" kind="relationship" relationship="rootViewController" id="RxB-wf-QIq"/>
......@@ -27,6 +28,7 @@
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="mLL-gJ-YKr">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="calibratedRGB"/>
<sections/>
<connections>
......
......@@ -25,8 +25,9 @@
//
@import UIKit;
@class BUYCheckout;
@class BUYClient;
@import Buy;
@import PassKit;
@import SafariServices;
extern NSString * const CheckoutCallbackNotification;
......
......@@ -24,16 +24,14 @@
// THE SOFTWARE.
//
#import <Buy/Buy.h>
#import "CheckoutViewController.h"
#import "GetCompletionStatusOperation.h"
#import "SummaryItemsTableViewCell.h"
#import "ProductListViewController.h"
@import Buy;
@import PassKit;
@import SafariServices;
#import "UIButton+PaymentButton.h"
NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
NSString * const MerchantId = @"";
@interface CheckoutViewController () <GetCompletionStatusOperationDelegate, SFSafariViewControllerDelegate, PKPaymentAuthorizationViewControllerDelegate>
......@@ -87,7 +85,7 @@ NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
[webCheckoutButton addTarget:self action:@selector(checkoutOnWeb) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:webCheckoutButton];
UIButton *applePayButton = [BUYPaymentButton buttonWithType:BUYPaymentButtonTypeBuy style:BUYPaymentButtonStyleBlack];
UIButton *applePayButton = [UIButton paymentButtonWithType:PaymentButtonTypeBuy style:PaymentButtonStyleBlack];
applePayButton.translatesAutoresizingMaskIntoConstraints = NO;
[applePayButton addTarget:self action:@selector(checkoutWithApplePay) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:applePayButton];
......@@ -139,11 +137,11 @@ NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
return cell;
}
- (void)addCreditCardToCheckout:(void (^)(BOOL success))callback
- (void)addCreditCardToCheckout:(void (^)(BOOL success, id<BUYPaymentToken> token))callback
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[self.client storeCreditCard:[self creditCard] checkout:self.checkout completion:^(BUYCheckout *checkout, NSString *paymentSessionId, NSError *error) {
[self.client storeCreditCard:[self creditCard] checkout:self.checkout completion:^(BUYCheckout *checkout, id<BUYPaymentToken> token, NSError *error) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
......@@ -156,7 +154,7 @@ NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
NSLog(@"Error applying credit card: %@", error);
}
callback(error == nil && checkout);
callback(error == nil && checkout, token);
}];
}
......@@ -212,14 +210,14 @@ NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
__weak CheckoutViewController *welf = self;
// First, the credit card must be stored on the checkout
[self addCreditCardToCheckout:^(BOOL success) {
[self addCreditCardToCheckout:^(BOOL success, id<BUYPaymentToken> token) {
if (success) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
// Upon successfully adding the credit card to the checkout, complete checkout must be called immediately
[welf.client completeCheckout:welf.checkout completion:^(BUYCheckout *checkout, NSError *error) {
[welf.client completeCheckout:welf.checkout paymentToken:token completion:^(BUYCheckout *checkout, NSError *error) {
if (error == nil && checkout) {
......@@ -292,7 +290,7 @@ NSString * const CheckoutCallbackNotification = @"CheckoutCallbackNotification";
{
PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init];
[paymentRequest setMerchantIdentifier:MERCHANT_ID];
[paymentRequest setMerchantIdentifier:MerchantId];
[paymentRequest setRequiredBillingAddressFields:PKAddressFieldAll];
[paymentRequest setRequiredShippingAddressFields:self.checkout.requiresShipping ? PKAddressFieldAll : PKAddressFieldEmail|PKAddressFieldPhone];
[paymentRequest setSupportedNetworks:@[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard]];
......
//
// BUYPaymentButton.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
typedef NS_ENUM(NSInteger, BUYPaymentButtonStyle) {
BUYPaymentButtonStyleWhite = 0,
BUYPaymentButtonStyleWhiteOutline,
BUYPaymentButtonStyleBlack
};
typedef NS_ENUM(NSInteger, BUYPaymentButtonType) {
BUYPaymentButtonTypePlain = 0,
BUYPaymentButtonTypeBuy,
BUYPaymentButtonTypeSetup NS_ENUM_AVAILABLE_IOS(9_0)
};
@interface BUYPaymentButton : UIButton
+ (instancetype)buttonWithType:(BUYPaymentButtonType)buttonType style:(BUYPaymentButtonStyle)buttonStyle;
@end
//
// ImageKit.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import Foundation;
@import UIKit;
/**
* Image generator for a variety of images using the BUYProductViewController.
*/
@interface ImageKit : NSObject
/**
* Generates a close button image for the variant selection navigation bar.
*
* @param frame The frame size of the image
*
* @return A close button image
*/
+ (UIImage*)imageOfVariantCloseImageWithFrame: (CGRect)frame;
/**
* Generates a checkmark image for use of displaying the previously selected variant
*
* @param frame The frame size of the image
*
* @return A checkmark for the previous variant selection
*/
+ (UIImage*)imageOfPreviousSelectionIndicatorImageWithFrame: (CGRect)frame;
/**
* Generates a custom disclosure indicator image
*
* @param frame The frame size of the image
* @param color The color for the disclosure indicator
*
* @return A disclusore indicator image
*/
+ (UIImage*)imageOfDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)color;
/**
* Generates a close button image for the product view's navigation bar
*
* @param frame The frame size of the image
* @param color The color for the close button image
* @param hasShadow True if the X should have a drop shadow
*
* @return A close button image
*/
+ (UIImage*)imageOfProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor*)color hasShadow:(BOOL)hasShadow;
/**
* Generates a custom back button image for the variant selection navigation bar
*
* @param frame The frame size of the image
*
* @return A custom back button image
*/
+ (UIImage*)imageOfVariantBackImageWithFrame: (CGRect)frame;
@end
//
// ImageKit.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "ImageKit.h"
@implementation ImageKit
#pragma mark Drawing Methods
+ (void)drawVariantCloseImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* closeColor = [UIColor colorWithRed: 0.596f green: 0.596f blue: 0.596f alpha: 1];
//// Variant Close Icon Drawing
UIBezierPath* variantCloseIconPath = UIBezierPath.bezierPath;
[variantCloseIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93886f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.87988f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.95000f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.06114f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.23681f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath closePath];
[variantCloseIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93886f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.23681f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.95000f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.06114f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.87988f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath closePath];
[closeColor setFill];
[variantCloseIconPath fill];
}
+ (void)drawPreviousSelectionIndicatorImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* indicatorColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
//// Previous Selection Indicator Drawing
UIBezierPath* previousSelectionIndicatorPath = UIBezierPath.bezierPath;
[previousSelectionIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.22386f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.77614f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.22386f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.22386f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.77614f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.22386f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.77614f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.77614f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath closePath];
[previousSelectionIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.28003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.62929f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25074f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.48003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.18002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.55074f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.39926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76997f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76924f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40073f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76997f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.81997f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.35074f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.28003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath closePath];
[indicatorColor setFill];
[previousSelectionIndicatorPath fill];
}
+ (void)drawDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)arrowColor
{
//// Disclosure Indicator Drawing
UIBezierPath* disclosureIndicatorPath = UIBezierPath.bezierPath;
[disclosureIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06878f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93995f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.49908f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.58746f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11004f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15717f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06878f * CGRectGetHeight(frame))];
[disclosureIndicatorPath closePath];
[disclosureIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.41253f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93995f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50092f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.93121f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11004f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84282f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.41253f * CGRectGetHeight(frame))];
[disclosureIndicatorPath closePath];
[arrowColor setFill];
[disclosureIndicatorPath fill];
}
+ (void)drawProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor *)closeColor2 hasShadow:(BOOL)hasShadow
{
//// General Declarations
CGContextRef context = UIGraphicsGetCurrentContext();
//// Color Declarations
UIColor* closeShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
//// Shadow Declarations
NSShadow* closeDropShadow = [[NSShadow alloc] init];
[closeDropShadow setShadowColor: [closeShadowColor colorWithAlphaComponent: 0.15f]];
[closeDropShadow setShadowOffset: CGSizeMake(0.1f, 1.1f)];
[closeDropShadow setShadowBlurRadius: 2];
//// Close Icon Drawing
UIBezierPath* closeIconPath = UIBezierPath.bezierPath;
[closeIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.85907f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84024f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.90452f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.05002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15976f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath closePath];
[closeIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.85907f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15976f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.90452f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.05002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84024f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath closePath];
CGContextSaveGState(context);
if (hasShadow) {
CGContextSetShadowWithColor(context, closeDropShadow.shadowOffset, closeDropShadow.shadowBlurRadius, [closeDropShadow.shadowColor CGColor]);
}
[closeColor2 setFill];
[closeIconPath fill];
CGContextRestoreGState(context);
}
+ (void)drawVariantBackImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* indicatorColor3 = [UIColor colorWithRed: 0.596f green: 0.596f blue: 0.596f alpha: 1];
//// Variant Back Indicator Drawing
UIBezierPath* variantBackIndicatorPath = UIBezierPath.bezierPath;
[variantBackIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.42225f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86663f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.86029f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.93886f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.09171f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50082f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.42225f * CGRectGetHeight(frame))];
[variantBackIndicatorPath closePath];
[variantBackIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06114f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86663f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.13971f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.57775f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.09171f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.49918f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06114f * CGRectGetHeight(frame))];
[variantBackIndicatorPath closePath];
[indicatorColor3 setFill];
[variantBackIndicatorPath fill];
}
#pragma mark Generated Images
+ (UIImage*)imageOfVariantCloseImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[ImageKit drawVariantCloseImageWithFrame: frame];
UIImage* imageOfVariantCloseImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfVariantCloseImage;
}
+ (UIImage*)imageOfPreviousSelectionIndicatorImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[ImageKit drawPreviousSelectionIndicatorImageWithFrame: frame];
UIImage* imageOfPreviousSelectionIndicatorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfPreviousSelectionIndicatorImage;
}
+ (UIImage*)imageOfDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)color;
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[ImageKit drawDisclosureIndicatorImageWithFrame: frame color:color];
UIImage* imageOfDisclosureIndicatorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfDisclosureIndicatorImage;
}
+ (UIImage*)imageOfProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor*)color hasShadow:(BOOL)hasShadow;
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[ImageKit drawProductViewCloseImageWithFrame: frame color:color hasShadow:hasShadow];
UIImage* imageOfProductViewCloseImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfProductViewCloseImage;
}
+ (UIImage*)imageOfVariantBackImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[ImageKit drawVariantBackImageWithFrame: frame];
UIImage* imageOfVariantBackImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfVariantBackImage;
}
@end
//
// UIButton+PaymentButton.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
typedef NS_ENUM(NSInteger, PaymentButtonStyle) {
PaymentButtonStyleWhite = 0,
PaymentButtonStyleWhiteOutline,
PaymentButtonStyleBlack
};
typedef NS_ENUM(NSInteger, PaymentButtonType) {
PaymentButtonTypePlain = 0,
PaymentButtonTypeBuy,
PaymentButtonTypeSetup NS_ENUM_AVAILABLE_IOS(9_0)
};
@interface UIButton (PaymentButton)
+ (UIButton *)paymentButtonWithType:(PaymentButtonType)buttonType style:(PaymentButtonStyle)buttonStyle;
@end
//
// UIButton+PaymentButton.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import PassKit;
#import "CheckoutButton.h"
#import "UIImage+BUYAdditions.h"
#import "UIImage+PaymentButton.h"
#import "UIButton+PaymentButton.h"
@implementation UIButton (PaymentButton)
+ (UIButton *)paymentButtonWithType:(PaymentButtonType)buttonType style:(PaymentButtonStyle)buttonStyle
{
if ([PKPaymentButton class]) {
return [PKPaymentButton buttonWithType:(PKPaymentButtonType)buttonType style:(PKPaymentButtonStyle)buttonStyle];
}
UIButton *button = [CheckoutButton new];
UIColor *fillColor;
UIColor *strokeColor;
switch (buttonStyle) {
case PaymentButtonStyleBlack:
fillColor = [UIColor blackColor];
break;
case PaymentButtonStyleWhite:
fillColor = [UIColor whiteColor];
break;
case PaymentButtonStyleWhiteOutline:
fillColor = [UIColor whiteColor];
strokeColor = [UIColor blackColor];
break;
}
UIImage *backgroundImage = [[UIImage templateImageWithFill:fillColor stroke:strokeColor edgeInsets:UIEdgeInsetsMake(4.0f, 4.0f, 4.0f, 4.0f)] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
UIImage *image = [UIImage paymentButtonImageWithFrame:CGRectMake(0, 0, 120.0f, 44.0f) style:buttonStyle type:buttonType];
[button setImage:image forState:UIControlStateNormal];
return button;
}
@end
//
// UIImage+PaymentButton.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <UIKit/UIKit.h>
#import "UIButton+PaymentButton.h"
@interface UIImage (PaymentButton)
+ (UIImage *)paymentButtonImageWithFrame:(CGRect)originalFrame style:(PaymentButtonStyle)style type:(PaymentButtonType)type;
@end
......@@ -53,7 +53,7 @@ typedef NS_ENUM(NSInteger, UITableViewDiscountGiftCardSection) {
@implementation PreCheckoutViewController
- (instancetype)initWithClient:(BUYClient *)client checkout:(BUYCheckout *)checkout;
- (instancetype)initWithClient:(BUYClient *)client checkout:(BUYCheckout *)checkout
{
NSParameterAssert(client);
NSParameterAssert(checkout);
......@@ -68,7 +68,8 @@ typedef NS_ENUM(NSInteger, UITableViewDiscountGiftCardSection) {
return self;
}
- (void)viewDidLoad {
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Add Discount or Gift Card(s)";
......@@ -192,7 +193,7 @@ typedef NS_ENUM(NSInteger, UITableViewDiscountGiftCardSection) {
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
BUYDiscount *discount = [[BUYDiscount alloc] initWithCode:[alertController.textFields[0] text]];
BUYDiscount *discount = [self.client.modelManager discountWithCode:[alertController.textFields[0] text]];
self.checkout.discount = discount;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
......
//
// ActionableFooterView.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
#import "CheckoutButton.h"
#import "UIButton+PaymentButton.h"
@interface ActionableFooterView : UIView
- (void)setApplePayAvailable:(BOOL)applePayAvailable requiresSetup:(BOOL)requiresSetup;
@property (nonatomic, readonly) CheckoutButton *actionButton;
/**
* On iOS 8.3+ this will be a PKPaymentButton
*/
@property (nonatomic, readonly) UIButton *paymentButton;
@property (nonatomic) BOOL buttonsEnabled;
/**
* A view which sits above the buttons.
* Can be used to add a description or other content to the footer.
*/
@property (nonatomic, readonly) UIView *extensionView;
@property (nonatomic) PaymentButtonStyle paymentButtonStyle UI_APPEARANCE_SELECTOR;
@property (nonatomic) UIColor *separatorColor UI_APPEARANCE_SELECTOR;
@end
//
// ActionableFooterView.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "ActionableFooterView.h"
@interface ActionableFooterView()
@property (nonatomic) BOOL applePayAvailable;
@property (nonatomic) BOOL applePayRequiresSetup;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *applePayLeadingConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *firstButtonTrailingConstraint;
@property (strong, nonatomic) IBOutlet CheckoutButton *actionButton;
@property (strong, nonatomic) IBOutlet UIView *paymentButtonContainer;
@property (strong, nonatomic) IBOutlet UIView *extensionView;
@property (strong, nonatomic) UIButton *paymentButton;
@end
@implementation ActionableFooterView
- (instancetype)init
{
return [[NSBundle bundleForClass:self.class] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil].firstObject;
}
- (void)awakeFromNib
{
[super awakeFromNib];
self.actionButton.backgroundColor = nil;
[self.actionButton setTitle:nil forState:UIControlStateNormal];
self.paymentButtonStyle = PaymentButtonStyleBlack;
self.paymentButtonContainer.backgroundColor = nil;
}
- (void)setApplePayAvailable:(BOOL)applePayAvailable requiresSetup:(BOOL)requiresSetup
{
_applePayAvailable = applePayAvailable;
_applePayRequiresSetup = requiresSetup;
self.paymentButtonContainer.hidden = !applePayAvailable;
PaymentButtonType type = self.applePayRequiresSetup ? PaymentButtonTypeSetup : PaymentButtonTypeBuy;
if (!self.paymentButton) {
_paymentButton = [UIButton paymentButtonWithType:type style:self.paymentButtonStyle];
[self.paymentButtonContainer addSubview:self.paymentButton];
self.paymentButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.paymentButtonContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_paymentButton]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_paymentButton)]];
[self.paymentButtonContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_paymentButton]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_paymentButton)]];
}
[self setNeedsUpdateConstraints];
}
- (void)setLayoutMargins:(UIEdgeInsets)layoutMargins
{
[super setLayoutMargins:layoutMargins];
self.applePayLeadingConstraint.constant = self.layoutMargins.left;
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self setNeedsUpdateConstraints];
}
- (void)setButtonsEnabled:(BOOL)buttonsEnabled
{
self.actionButton.enabled = buttonsEnabled;
self.paymentButton.enabled = buttonsEnabled;
self.paymentButton.alpha = buttonsEnabled ? 1.0f : 0.5f;
}
- (void)updateConstraints
{
if (self.applePayAvailable) {
CGFloat trailingConstant = (CGRectGetWidth(self.bounds) - self.layoutMargins.right) * 0.5f;
self.firstButtonTrailingConstraint.constant = trailingConstant;
} else {
self.firstButtonTrailingConstraint.constant = 0.0f;
}
[super updateConstraints];
}
- (void)setSeparatorColor:(UIColor *)separatorColor
{
self.layer.shadowColor = separatorColor.CGColor;
self.layer.shadowOffset = CGSizeMake(0, - 1 / [UIScreen mainScreen].scale);
self.layer.shadowRadius = 0.0f;
self.layer.shadowOpacity = 1.0f;
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ActionableFooterView">
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<visualEffectView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2he-LW-1Mz">
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" id="tOf-FE-2kG">
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jjm-5z-kCD" userLabel="paymentContainer">
<rect key="frame" x="165" y="46" width="145" height="44"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Eoe-n5-0iT" customClass="CheckoutButton">
<rect key="frame" x="10" y="46" width="145" height="44"/>
<color key="backgroundColor" red="0.00059560901718214154" green="0.70855957269668579" blue="0.99971479177474976" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="Yod-FN-PBJ"/>
</constraints>
<state key="normal" title="Add to Cart">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QbM-Nc-TSH">
<rect key="frame" x="0.0" y="10" width="320" height="36"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="Eoe-n5-0iT" secondAttribute="trailing" constant="155" id="4jE-2h-gr6"/>
<constraint firstItem="Eoe-n5-0iT" firstAttribute="leading" secondItem="tOf-FE-2kG" secondAttribute="leadingMargin" id="ACp-Cb-o3A"/>
<constraint firstItem="jjm-5z-kCD" firstAttribute="height" secondItem="Eoe-n5-0iT" secondAttribute="height" id="DoE-w1-naR"/>
<constraint firstItem="QbM-Nc-TSH" firstAttribute="leading" secondItem="tOf-FE-2kG" secondAttribute="leading" id="Q7m-41-SnI"/>
<constraint firstItem="QbM-Nc-TSH" firstAttribute="top" secondItem="tOf-FE-2kG" secondAttribute="topMargin" id="Tbz-Z9-Xyu"/>
<constraint firstItem="jjm-5z-kCD" firstAttribute="leading" secondItem="Eoe-n5-0iT" secondAttribute="trailing" constant="10" id="UrY-kJ-C6C"/>
<constraint firstAttribute="bottomMargin" secondItem="Eoe-n5-0iT" secondAttribute="bottom" id="WHF-0k-ScU"/>
<constraint firstItem="jjm-5z-kCD" firstAttribute="width" secondItem="Eoe-n5-0iT" secondAttribute="width" id="fop-kv-C9D"/>
<constraint firstItem="jjm-5z-kCD" firstAttribute="centerY" secondItem="Eoe-n5-0iT" secondAttribute="centerY" id="g86-Vu-ZpD"/>
<constraint firstItem="Eoe-n5-0iT" firstAttribute="top" secondItem="QbM-Nc-TSH" secondAttribute="bottom" id="pwX-zC-1fR"/>
<constraint firstAttribute="trailing" secondItem="QbM-Nc-TSH" secondAttribute="trailing" id="yYy-IX-gUN"/>
</constraints>
</view>
<blurEffect style="extraLight"/>
</visualEffectView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="2he-LW-1Mz" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="9VD-ID-fkE"/>
<constraint firstItem="2he-LW-1Mz" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="EFC-N3-UwK"/>
<constraint firstItem="2he-LW-1Mz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="nzn-ri-Fq0"/>
<constraint firstItem="2he-LW-1Mz" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="xUR-8Z-blk"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
<connections>
<outlet property="actionButton" destination="Eoe-n5-0iT" id="slV-do-iC5"/>
<outlet property="applePayLeadingConstraint" destination="UrY-kJ-C6C" id="CBg-TA-i3I"/>
<outlet property="extensionView" destination="QbM-Nc-TSH" id="1rQ-Kd-AvH"/>
<outlet property="firstButtonTrailingConstraint" destination="4jE-2h-gr6" id="kTF-KV-LGT"/>
<outlet property="paymentButtonContainer" destination="jjm-5z-kCD" id="tgu-5h-QO3"/>
</connections>
<point key="canvasLocation" x="142" y="525"/>
</view>
</objects>
</document>
//
// BUYImageView.h
// AsyncImageView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,14 +25,14 @@
//
@import UIKit;
#import "BUYTheme.h"
@import Buy;
extern float const imageDuration;
/**
* Provides an easy way to asynchronously load images from a URL
*/
@interface BUYImageView : UIImageView <BUYThemeable>
@interface AsyncImageView : UIImageView
@property (nonatomic, assign) BOOL showsActivityIndicator;
......@@ -65,4 +65,13 @@ extern float const imageDuration;
*/
- (BOOL)isPortraitOrSquare;
/**
* Load an image asynchronously from an BUYImageLink and animate the transition. Will use the optimal image size for the ImageView
*
* @param imageLink the BUYImageLink that points to the image asset to use
* @param animateChange YES to animation the image transition
* @param completion Completion block returning the image or an error
*/
- (void)loadImageLink:(BUYImageLink *)imageLink animateChange:(BOOL)animateChange completion:(void (^)(UIImage *image, NSError *error))completion;
@end
//
// BUYImageView.m
// AsyncImageView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,19 +24,47 @@
// THE SOFTWARE.
//
#import "BUYImageView.h"
#import "BUYTheme+Additions.h"
#import "AsyncImageView.h"
float const imageDuration = 0.1f;
@interface BUYImageView ()
static NSUInteger const memoryCacheSize = 10 * 1024 * 1024; // 10 MB
static NSUInteger const diskCacheSize = 50 * 1024 * 1024; // 50 MB
@interface NSURLSession (BUYImageSession)
+ (instancetype)buy_sharedImageSession;
@end
@implementation NSURLSession (BUYImageSession)
+ (instancetype)buy_sharedImageSession
{
static NSURLSession *_sharedSession = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.URLCache = [[NSURLCache alloc] initWithMemoryCapacity:memoryCacheSize diskCapacity:diskCacheSize diskPath:nil];
_sharedSession = [NSURLSession sessionWithConfiguration:config];
});
return _sharedSession;
}
@end
@interface AsyncImageView ()
@property (nonatomic, strong) NSURLSessionDataTask *task;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
@end
@implementation BUYImageView
@implementation AsyncImageView
- (instancetype)init
{
......@@ -104,7 +132,7 @@ float const imageDuration = 0.1f;
if (self.showsActivityIndicator) {
[self.activityIndicatorView startAnimating];
}
self.task = [[NSURLSession sharedSession] dataTaskWithURL:imageURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
self.task = [[NSURLSession buy_sharedImageSession] dataTaskWithURL:imageURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
if (setImage) {
......@@ -119,19 +147,23 @@ float const imageDuration = 0.1f;
[self.task resume];
}
- (void)cancelImageTask {
- (void)cancelImageTask
{
[self.task cancel];
self.task = nil;
}
- (void)setTheme:(BUYTheme *)theme
- (BOOL)isPortraitOrSquare
{
self.activityIndicatorView.activityIndicatorViewStyle = [theme activityIndicatorViewStyle];
return self.image.size.height >= self.image.size.width;
}
- (BOOL)isPortraitOrSquare
- (void)loadImageLink:(BUYImageLink *)imageLink animateChange:(BOOL)animateChange completion:(void (^)(UIImage *image, NSError *error))completion;
{
return self.image.size.height >= self.image.size.width;
BUYImageURLSize size = [self buy_imageSize];
NSURL *url = [imageLink imageURLWithSize:size];
[self loadImageWithURL:url animateChange:animateChange completion:completion];
}
@end
//
// BUYProductViewFooter.h
// CheckoutButton.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,49 +25,31 @@
//
@import UIKit;
@class BUYProductVariant;
@class BUYTheme;
#import "BUYPaymentButton.h"
#import "BUYCheckoutButton.h"
@interface BUYProductViewFooter : UIView
/**
* A footer view for the BUYProductView that includes a checkout button and an Apple Pay button (if available)
*
* @param theme The theme for the footer view
* @param showApplePaySetup Show Apple Pay button with 'Set Up Apple Pay' text as determined by the presenter
*
* @return A footer view with a checkout and Apple Pay button
* A themed UIButton that includes a UIActivityIndicator
*/
- (instancetype)initWithTheme:(BUYTheme *)theme showApplePaySetup:(BOOL)showApplePaySetup;
@interface CheckoutButton : UIButton
/**
* A checkout button themed with the BUYTheme tintColor.
* This button is used for web checkout
*/
@property (nonatomic, strong) BUYCheckoutButton *checkoutButton;
/**
* An Apple Pay button, shown if Apple Pay is enabled and available on the device.
* The BUYPaymentButton is a PKPaymentButton on iOS 8.3 and greater.
* Styled to match the given theme.
* Creates a checkout button with UIButtonTypeSystem which inherits its color from the superview's tintColor
*
* @return A CheckoutButton with UIButtonTypeSystem
*/
@property (nonatomic, strong) BUYPaymentButton *buyPaymentButton;
+(instancetype)checkoutButton;
/**
* Sets the Apple Pay visible (or hides it). This updates the layout for the buttons.
* Show a UIActivityIndicator in place of text while loading
*
* @param isApplePayAvailable True when the Apple Pay button is visible
* @param show Show or hide the UIActivityIndicator
*/
- (void)setApplePayButtonVisible:(BOOL)isApplePayAvailable;
- (void)showActivityIndicator:(BOOL)show;
/**
* Lowers the alpha and disable the buttons if the `available` property on the
* BUYProductVariant is false.
* Sets the button text color
*
* @param productVariant The selected product variant that determines availability and functionality of the buttons.
* @param color The color for the button
*/
- (void)updateButtonsForProductVariant:(BUYProductVariant *)productVariant;
- (void)setTextColor:(UIColor*)color UI_APPEARANCE_SELECTOR;
@end
//
// BUYCheckoutButton.m
// CheckoutButton.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,39 +24,61 @@
// THE SOFTWARE.
//
#import "BUYCheckoutButton.h"
#import "BUYTheme+Additions.h"
#import "CheckoutButton.h"
#import "UIColor+BUYAdditions.h"
#import "UIImage+BUYAdditions.h"
@interface BUYCheckoutButton ()
@interface CheckoutButton ()
@property (nonatomic, weak) BUYTheme *theme;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
@property (nonatomic, strong) UIColor *textColor;
@end
@implementation BUYCheckoutButton
@implementation CheckoutButton
- (void)setHighlighted:(BOOL)highlighted
+ (instancetype)checkoutButton
{
[super setHighlighted:highlighted];
self.backgroundColor = highlighted ? [self.theme.tintColor colorWithAlphaComponent:0.4f] : self.theme.tintColor;
CheckoutButton *checkoutButton = [super buttonWithType:UIButtonTypeSystem];
[checkoutButton commonInit];
return checkoutButton;
}
- (void)setTheme:(BUYTheme *)theme
- (instancetype)initWithFrame:(CGRect)frame
{
_theme = theme;
self.tintColor = theme.tintColor;
self.backgroundColor = self.tintColor;
UIColor *textColor = [theme checkoutButtonTextColor];
[self setTitleColor:textColor forState:UIControlStateNormal];
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit
{
[self setBackgroundImage:[UIImage templateButtonBackgroundImage] forState:UIControlStateNormal];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.5f] forState:UIControlStateDisabled];
}
- (void)setTextColor:(UIColor*)color
{
_textColor = color;
[self setTitleColor:color forState:UIControlStateNormal];
}
- (UIActivityIndicatorView *)activityIndicator
{
if (_activityIndicator == nil) {
UIActivityIndicatorViewStyle style = self.theme.style == BUYThemeStyleLight ? UIActivityIndicatorViewStyleWhite : UIActivityIndicatorViewStyleGray;
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:style];
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
_activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
_activityIndicator.hidesWhenStopped = YES;
[self addSubview:_activityIndicator];
......@@ -77,7 +99,7 @@
}
else {
[self.activityIndicator stopAnimating];
[self setTheme:self.theme];
[self setTitleColor:self.textColor forState:UIControlStateNormal];
}
}
......
//
// DisclosureIndicatorView.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
@interface DisclosureIndicatorView : UIImageView
@end
//
// BUYTheme.m
// DisclosureIndicatorView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,20 +24,17 @@
// THE SOFTWARE.
//
#import "BUYTheme.h"
#import "DisclosureIndicatorView.h"
#import "ImageKit.h"
@implementation BUYTheme
@implementation DisclosureIndicatorView
- (instancetype)init
{
self = [super init];
if (self) {
self.tintColor = [UIColor colorWithRed:0.48f green:0.71f blue:0.36f alpha:1.0f];
self.style = BUYThemeStyleLight;
self.showsProductImageBackground = YES;
self.image = [[ImageKit imageOfDisclosureIndicatorImageWithFrame:CGRectMake(0, 0, 10, 16) color:[UIColor blackColor]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}
return self;
}
......
//
// BUYProductViewErrorView.h
// ErrorView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,12 +25,11 @@
//
@import UIKit;
@class BUYTheme;
/**
* A customer toast error view to use in the BUYProductView.
* A customer toast error view to use in the ProductView.
*/
@interface BUYProductViewErrorView : UIView
@interface ErrorView : UIView
/**
* The label containing the error message.
......@@ -47,13 +46,8 @@
*/
@property (nonatomic, strong) NSLayoutConstraint *visibleConstraint;
/**
* Initializer that create an error view with a theme.
*
* @param theme The theme for the error view.
*
* @return An error view.
*/
- (instancetype)initWithTheme:(BUYTheme*)theme;
- (void)setOverlayColor:(UIColor*)color UI_APPEARANCE_SELECTOR;
- (void)presentErrorViewWithMessage:(NSString *)errorMessage completion:(void (^)(void))callback;
@end
//
// BUYProductViewErrorView.m
// ErrorView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,18 +24,24 @@
// THE SOFTWARE.
//
#import "BUYProductViewErrorView.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "ErrorView.h"
@implementation BUYProductViewErrorView
static CGFloat const kPaddingMedium = 12.0f;
static CGFloat const kPaddingExtraLarge = 16.0f;
- (instancetype)initWithTheme:(BUYTheme*)theme
@interface ErrorView ()
@property (nonatomic, strong) UIView *overlayView;
@end
@implementation ErrorView
- (instancetype)init
{
self = [super init];
if (self) {
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] init];
visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:visualEffectView];
......@@ -48,29 +54,28 @@
metrics:nil
views:NSDictionaryOfVariableBindings(visualEffectView)]];
UIView *redTintOverlayView = [[UIView alloc] init];
redTintOverlayView.translatesAutoresizingMaskIntoConstraints = NO;
redTintOverlayView.backgroundColor = [theme errorTintOverlayColor];
[visualEffectView.contentView addSubview:redTintOverlayView];
[visualEffectView.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[redTintOverlayView]|"
_overlayView = [[UIView alloc] init];
_overlayView.translatesAutoresizingMaskIntoConstraints = NO;
[visualEffectView.contentView addSubview:_overlayView];
[visualEffectView.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_overlayView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(redTintOverlayView)]];
[visualEffectView.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[redTintOverlayView]|"
views:NSDictionaryOfVariableBindings(_overlayView)]];
[visualEffectView.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_overlayView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(redTintOverlayView)]];
views:NSDictionaryOfVariableBindings(_overlayView)]];
_errorLabel = [[UILabel alloc] init];
_errorLabel.translatesAutoresizingMaskIntoConstraints = NO;
_errorLabel.textAlignment = NSTextAlignmentCenter;
_errorLabel.font = [BUYTheme errorLabelFont];
_errorLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
_errorLabel.textColor = [UIColor whiteColor];
_errorLabel.backgroundColor = [UIColor clearColor];
_errorLabel.numberOfLines = 0;
[visualEffectView.contentView addSubview:_errorLabel];
NSDictionary *metricsDictionary = @{ @"paddingExtraLarge" : @(kBuyPaddingExtraLarge), @"paddingMedium" : @(kBuyPaddingMedium) };
NSDictionary *metricsDictionary = @{ @"paddingExtraLarge" : @(kPaddingExtraLarge), @"paddingMedium" : @(kPaddingMedium) };
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(paddingExtraLarge)-[_errorLabel]-(paddingExtraLarge)-|"
options:0
......@@ -84,4 +89,38 @@
return self;
}
- (void)setOverlayColor:(UIColor*)color
{
self.overlayView.backgroundColor = color;
}
- (void)presentErrorViewWithMessage:(NSString *)errorMessage completion:(void (^)(void))callback
{
self.errorLabel.text = errorMessage;
[NSLayoutConstraint deactivateConstraints:@[self.hiddenConstraint]];
[NSLayoutConstraint activateConstraints:@[self.visibleConstraint]];
[UIView animateWithDuration:0.3f
delay:0
usingSpringWithDamping:0.8f
initialSpringVelocity:10
options:0
animations:^{
self.alpha = 1;
[self layoutIfNeeded];
}
completion:^(BOOL finished) {
[NSLayoutConstraint deactivateConstraints:@[self.visibleConstraint]];
[NSLayoutConstraint activateConstraints:@[self.hiddenConstraint]];
[UIView animateWithDuration:0.3f delay:3.0f options:0 animations:^{
self.alpha = 0;
[self layoutIfNeeded];
} completion:^(BOOL finished) {
[self removeFromSuperview];
if (callback) callback();
}];
}];
}
@end
//
// BUYGradientView.h
// GradientView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -29,7 +29,7 @@
/**
* Easily create a view with a vertical gradient with two colors
*/
@interface BUYGradientView : UIView
@interface GradientView : UIView
/**
* The color of the top part of the gradient
......
//
// BUYGradientView.m
// GradientView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,9 +24,9 @@
// THE SOFTWARE.
//
#import "BUYGradientView.h"
#import "GradientView.h"
@implementation BUYGradientView
@implementation GradientView
- (instancetype)init
{
......@@ -34,14 +34,16 @@
if (self) {
self.backgroundColor = [UIColor clearColor];
self.topColor = [UIColor colorWithWhite:0 alpha:0.5f];
self.bottomColor = [UIColor clearColor];
self.bottomColor = [UIColor colorWithWhite:0 alpha:0];
}
return self;
}
- (void)drawRect:(CGRect)rect {
- (void)drawRect:(CGRect)rect
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
NSArray *gradientColors = [NSArray arrayWithObjects:(id)self.topColor.CGColor, (id)self.bottomColor.CGColor, nil];
CGFloat gradientLocations[] = {0, 1};
......
//
// BUYProductViewHeaderBackgroundImageView.h
// HeaderBackgroundView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,24 +25,14 @@
//
@import UIKit;
@class BUYImageView;
@class BUYTheme;
@class AsyncImageView;
@class BUYImageLink;
/**
* A background for the product view that displays the currently displayed
* product or variant image behind a blurry UIVisualEffectView.
*/
@interface BUYProductViewHeaderBackgroundImageView : UIView
/**
* Initializer that takes a BUYTheme
*
* @param theme The product view theme
*
* @return An instance of BUYProductViewHeaderBackgroundImageView
*/
- (instancetype)initWithTheme:(BUYTheme*)theme;
@interface HeaderBackgroundView : UIView
/**
* Set the product image on the image view
......
//
// BUYProductViewHeaderBackgroundImageView.m
// HeaderBackgroundView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,25 +24,23 @@
// THE SOFTWARE.
//
#import "BUYProductViewHeaderBackgroundImageView.h"
#import "BUYTheme.h"
#import "BUYImageView.h"
#import "BUYImageLink.h"
#import "BUYTheme+Additions.h"
#import "AsyncImageView.h"
#import "HeaderBackgroundView.h"
#import "VisualEffectView.h"
@interface BUYProductViewHeaderBackgroundImageView ()
@interface HeaderBackgroundView ()
@property (nonatomic, strong) BUYImageView *productImageView;
@property (nonatomic, strong) AsyncImageView *productImageView;
@end
@implementation BUYProductViewHeaderBackgroundImageView
@implementation HeaderBackgroundView
- (instancetype)initWithTheme:(BUYTheme*)theme
- (instancetype)init
{
self = [super init];
if (self) {
self.productImageView = [[BUYImageView alloc] init];
self.productImageView = [[AsyncImageView alloc] init];
self.productImageView.clipsToBounds = YES;
self.productImageView.translatesAutoresizingMaskIntoConstraints = NO;
self.productImageView.backgroundColor = [UIColor clearColor];
......@@ -64,7 +62,7 @@
multiplier:1.0
constant:0.0]];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[theme blurEffect]];
VisualEffectView *visualEffectView = [[VisualEffectView alloc] init];
visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:visualEffectView];
......@@ -88,8 +86,7 @@
- (void)setBackgroundProductImage:(BUYImageLink *)image
{
NSString *string = [image.src stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@".%@", [image.src pathExtension]] withString:[NSString stringWithFormat:@"_small.%@", [image.src pathExtension]]];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", string]];
NSURL *url = [image imageURLWithSize:BUYImageURLSize100x100];
[self.productImageView loadImageWithURL:url animateChange:YES completion:NULL];
}
......
//
// BUYProductViewHeaderOverlay.h
// HeaderOverlayView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,23 +25,15 @@
//
@import UIKit;
@class BUYTheme;
/**
* An overlay + blur effect when the product view scrolls up
* to hide the image view and create a nice transition into
* the navigation bar.
*/
@interface BUYProductViewHeaderOverlay : UIView
@interface HeaderOverlayView : UIView
/**
* Initializer that takes a BUYTheme
*
* @param theme The product view theme
*
* @return An instance of BUYProductViewHeaderOverlay
*/
- (instancetype)initWithTheme:(BUYTheme*)theme;
@property (nonatomic) UIColor *overlayBackgroundColor UI_APPEARANCE_SELECTOR;
/**
* Used to determine the current visibility of the effect based on content offset and the navigationbar height.
......
//
// BUYProductViewHeaderOverlay.m
// HeaderOverlayView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,20 +24,19 @@
// THE SOFTWARE.
//
#import "BUYProductViewHeaderOverlay.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "HeaderOverlayView.h"
#import "VisualEffectView.h"
@interface BUYProductViewHeaderOverlay ()
@interface HeaderOverlayView ()
@property (nonatomic, strong) UIView *overlayView;
@property (nonatomic, strong) UIView *visualEffectContainerView;
@end
@implementation BUYProductViewHeaderOverlay
@implementation HeaderOverlayView
- (instancetype)initWithTheme:(BUYTheme*)theme
- (instancetype)init
{
self = [super init];
if (self) {
......@@ -51,7 +50,7 @@
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_visualEffectContainerView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_visualEffectContainerView)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_visualEffectContainerView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_visualEffectContainerView)]];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[theme blurEffect]];
VisualEffectView *visualEffectView = [[VisualEffectView alloc] init];
visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
[_visualEffectContainerView addSubview:visualEffectView];
......@@ -60,7 +59,6 @@
_overlayView = [[UIView alloc] init];
_overlayView.alpha = 0;
_overlayView.backgroundColor = [theme backgroundColor];
_overlayView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_overlayView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_overlayView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_overlayView)]];
......@@ -69,6 +67,11 @@
return self;
}
-(void)setOverlayBackgroundColor:(UIColor *)overlayBackgroundColor
{
_overlayView.backgroundColor = overlayBackgroundColor;
}
static CGFloat visualEffectViewThreshold = 200.0f;
static CGFloat overlayViewThreshold = 100.0f;
......
//
// BUYProductDescriptionCell.h
// ProductDescriptionCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,12 +25,11 @@
//
@import UIKit;
#import "BUYTheme.h"
/**
* Table view cell containing the product description
*/
@interface BUYProductDescriptionCell : UITableViewCell <BUYThemeable>
@interface ProductDescriptionCell : UITableViewCell
/**
* Converts the product description from HTML to an attributed string
......
//
// BUYProductDescriptionCell.m
// ProductDescriptionCell.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,18 +24,16 @@
// THE SOFTWARE.
//
#import "BUYProductDescriptionCell.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "ProductDescriptionCell.h"
#import "Theme+Additions.h"
@interface BUYProductDescriptionCell ()
@interface ProductDescriptionCell ()
@property (nonatomic, strong) UIColor *textColor;
@property (nonatomic, strong) UILabel *descriptionLabel;
@property (nonatomic, strong) BUYTheme *theme;
@end
@implementation BUYProductDescriptionCell
@implementation ProductDescriptionCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
......@@ -54,7 +52,7 @@
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_descriptionLabel]-|" options:0 metrics:nil views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_descriptionLabel]-|" options:0 metrics:nil views:views]];
_textColor = [BUYTheme descriptionTextColor];
_textColor = [Theme descriptionTextColor];
}
return self;
......@@ -85,10 +83,9 @@
return self.descriptionLabel.attributedText.string;
}
- (void)setTheme:(BUYTheme *)theme
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
_theme = theme;
self.backgroundColor = [theme backgroundColor];
[super setBackgroundColor:backgroundColor];
self.descriptionLabel.backgroundColor = self.backgroundColor;
}
......
//
// BUYProductHeaderCell.h
// ProductHeaderCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,13 +25,12 @@
//
@import UIKit;
#import "BUYTheme.h"
@class BUYProductVariant;
@import Buy;
/**
* Table view cell containing the product title, price and compare-at/sold out text
*/
@interface BUYProductHeaderCell : UITableViewCell <BUYThemeable>
@interface ProductHeaderCell : UITableViewCell
/**
* Sets the title, price and optionally compare-at/sold out texts
......@@ -41,4 +40,6 @@
*/
- (void)setProductVariant:(BUYProductVariant *)productVariant withCurrencyFormatter:(NSNumberFormatter*)currencyFormatter;
- (void)setProductTitleColor:(UIColor*)color UI_APPEARANCE_SELECTOR;
@end
//
// BUYProductHeaderCell.m
// ProductHeaderCell.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,23 +24,20 @@
// THE SOFTWARE.
//
#import "BUYProductHeaderCell.h"
#import "BUYProductVariant.h"
#import "BUYProduct.h"
#import "ProductHeaderCell.h"
#import "UIFont+BUYAdditions.h"
#import "BUYTheme+Additions.h"
#import "Theme+Additions.h"
@interface BUYProductHeaderCell ()
@interface ProductHeaderCell ()
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *priceLabel;
@property (nonatomic, strong) UILabel *comparePriceLabel;
@property (nonatomic, strong) BUYTheme *theme;
@property (nonatomic, strong) BUYProductVariant *productVariant;
@end
@implementation BUYProductHeaderCell
@implementation ProductHeaderCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
......@@ -52,7 +49,7 @@
_titleLabel = [[UILabel alloc] init];
_titleLabel.textColor = [UIColor blackColor];
_titleLabel.font = [BUYTheme productTitleFont];
_titleLabel.font = [Theme productTitleFont];
_titleLabel.numberOfLines = 0;
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_titleLabel];
......@@ -62,7 +59,7 @@
[self.contentView addSubview:priceView];
_priceLabel = [[UILabel alloc] init];
_priceLabel.font = [BUYTheme productPriceFont];
_priceLabel.font = [Theme productPriceFont];
_priceLabel.translatesAutoresizingMaskIntoConstraints = NO;
_priceLabel.textAlignment = NSTextAlignmentRight;
[_priceLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
......@@ -70,9 +67,9 @@
[priceView addSubview:_priceLabel];
_comparePriceLabel = [[UILabel alloc] init];
_comparePriceLabel.textColor = [BUYTheme comparePriceTextColor];
_comparePriceLabel.textColor = [Theme comparePriceTextColor];
_comparePriceLabel.textAlignment = NSTextAlignmentRight;
_comparePriceLabel.font = [BUYTheme productComparePriceFont];
_comparePriceLabel.font = [Theme productComparePriceFont];
_comparePriceLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_comparePriceLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[_comparePriceLabel setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
......@@ -105,14 +102,14 @@
self.priceLabel.text = [currencyFormatter stringFromNumber:productVariant.price];
}
if (productVariant.available.boolValue && productVariant.compareAtPrice) {
if (productVariant.availableValue == YES && productVariant.compareAtPrice) {
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[currencyFormatter stringFromNumber:productVariant.compareAtPrice]
attributes:@{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)}];
self.comparePriceLabel.attributedText = attributedString;
self.comparePriceLabel.textColor = [BUYTheme comparePriceTextColor];
self.comparePriceLabel.textColor = [Theme comparePriceTextColor];
} else if (productVariant.available == NO) {
self.comparePriceLabel.text = @"Sold Out";
self.comparePriceLabel.textColor = [BUYTheme variantSoldOutTextColor];
self.comparePriceLabel.text = NSLocalizedString(@"Sold Out", @"Sold out text displayed on product view");
self.comparePriceLabel.textColor = [Theme variantSoldOutTextColor];
} else {
self.comparePriceLabel.attributedText = nil;
}
......@@ -121,12 +118,10 @@
[self layoutIfNeeded];
}
- (void)setTheme:(BUYTheme *)theme
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
_theme = theme;
self.backgroundColor = [theme backgroundColor];
[super setBackgroundColor:backgroundColor];
self.titleLabel.backgroundColor = self.priceLabel.backgroundColor = self.comparePriceLabel.backgroundColor = self.backgroundColor;
self.titleLabel.textColor = [theme productTitleColor];
}
- (void)tintColorDidChange
......@@ -135,4 +130,9 @@
self.priceLabel.textColor = self.tintColor;
}
- (void)setProductTitleColor:(UIColor*)color
{
self.titleLabel.textColor = color;
}
@end
//
// BUYProductImageCollectionViewCell.h
// ProductImageCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,17 +25,17 @@
//
@import UIKit;
@class BUYImageView;
@class AsyncImageView;
/**
* A custom collection view cell for the BUYProductViewController's product image(s)
*/
@interface BUYProductImageCollectionViewCell : UICollectionViewCell
@interface ProductImageCell : UICollectionViewCell
/**
* The image view containing a product image
*/
@property (nonatomic, strong) BUYImageView *productImageView;
@property (nonatomic, strong) AsyncImageView *productImageView;
/**
* The height to display the product image
......
//
// BUYProductImageCollectionViewCell.m
// ProductImageCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,10 +24,10 @@
// THE SOFTWARE.
//
#import "BUYProductImageCollectionViewCell.h"
#import "BUYImageView.h"
#import "ProductImageCell.h"
#import "AsyncImageView.h"
@implementation BUYProductImageCollectionViewCell
@implementation ProductImageCell
- (instancetype)initWithFrame:(CGRect)frame
{
......@@ -38,7 +38,7 @@
self.contentView.backgroundColor = [UIColor clearColor];
_productImageView = [[BUYImageView alloc] init];
_productImageView = [[AsyncImageView alloc] init];
_productImageView.clipsToBounds = YES;
_productImageView.translatesAutoresizingMaskIntoConstraints = NO;
_productImageView.backgroundColor = [UIColor clearColor];
......
//
// BUYProductVariantCell.h
// ProductVariantCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,13 +25,12 @@
//
@import UIKit;
#import "BUYTheme.h"
@class BUYProductVariant;
@import Buy;
/**
* Table view cell containing the product's variant options
*/
@interface BUYProductVariantCell : UITableViewCell <BUYThemeable>
@interface ProductVariantCell : UITableViewCell
/**
* Set the options for a product variant
......@@ -40,4 +39,6 @@
*/
- (void)setOptionsForProductVariant:(BUYProductVariant *)productVariant;
- (void)setSelectedBackgroundViewBackgroundColor:(UIColor *)selectedBackgroundViewBackgroundColor UI_APPEARANCE_SELECTOR;
@end
//
// BUYProductVariantCell.m
// ProductVariantCell.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,23 +24,24 @@
// THE SOFTWARE.
//
#import "BUYProductVariantCell.h"
#import "BUYVariantOptionView.h"
#import "BUYProductVariant.h"
#import "BUYOptionValue.h"
#import "BUYImageKit.h"
#import "DisclosureIndicatorView.h"
#import "ImageKit.h"
#import "ProductVariantCell.h"
#import "Theme+Additions.h"
#import "VariantOptionView.h"
@interface BUYProductVariantCell ()
@property (nonatomic, strong) BUYVariantOptionView *optionView1;
@property (nonatomic, strong) BUYVariantOptionView *optionView2;
@property (nonatomic, strong) BUYVariantOptionView *optionView3;
@interface ProductVariantCell ()
@property (nonatomic, strong) VariantOptionView *optionView1;
@property (nonatomic, strong) VariantOptionView *optionView2;
@property (nonatomic, strong) VariantOptionView *optionView3;
@property (nonatomic, strong) NSArray *disclosureConstraints;
@property (nonatomic, strong) NSArray *noDisclosureConstraints;
@property (nonatomic, strong) UIImageView *disclosureIndicatorImageView;
@property (nonatomic, strong) BUYTheme *theme;
@property (nonatomic, strong) DisclosureIndicatorView *disclosureIndicatorImageView;
@end
@implementation BUYProductVariantCell
@implementation ProductVariantCell
CGFloat const buttonWidth = 10.0f;
......@@ -53,22 +54,22 @@ CGFloat const buttonWidth = 10.0f;
UIView *backgroundView = [[UIView alloc] init];
[self setSelectedBackgroundView:backgroundView];
_optionView1 = [[BUYVariantOptionView alloc] init];
_optionView1 = [[VariantOptionView alloc] init];
_optionView1.translatesAutoresizingMaskIntoConstraints = NO;
[_optionView1 setContentCompressionResistancePriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
[self.contentView addSubview:_optionView1];
_optionView2 = [[BUYVariantOptionView alloc] init];
_optionView2 = [[VariantOptionView alloc] init];
_optionView2.translatesAutoresizingMaskIntoConstraints = NO;
[_optionView3 setContentCompressionResistancePriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
[self.contentView addSubview:_optionView2];
_optionView3 = [[BUYVariantOptionView alloc] init];
_optionView3 = [[VariantOptionView alloc] init];
_optionView3.translatesAutoresizingMaskIntoConstraints = NO;
[_optionView3 setContentCompressionResistancePriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
[self.contentView addSubview:_optionView3];
_disclosureIndicatorImageView = [[UIImageView alloc] init];
_disclosureIndicatorImageView = [[DisclosureIndicatorView alloc] init];
_disclosureIndicatorImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_disclosureIndicatorImageView];
......@@ -97,7 +98,7 @@ CGFloat const buttonWidth = 10.0f;
- (void)setOptionsForProductVariant:(BUYProductVariant *)productVariant
{
NSArray *productOptions = productVariant.options.allObjects;
NSArray *productOptions = [productVariant.options allObjects];
switch (productVariant.options.count) {
case 3:
......@@ -137,16 +138,9 @@ CGFloat const buttonWidth = 10.0f;
}
}
- (void)setTheme:(BUYTheme *)theme
- (void)setSelectedBackgroundViewBackgroundColor:(UIColor *)selectedBackgroundViewBackgroundColor
{
_theme = theme;
self.backgroundColor = [theme backgroundColor];
self.selectedBackgroundView.backgroundColor = [theme selectedBackgroundColor];
self.disclosureIndicatorImageView.image = [BUYImageKit imageOfDisclosureIndicatorImageWithFrame:CGRectMake(0, 0, buttonWidth, 16) color:[theme disclosureIndicatorColor]];
[self.optionView1 setTheme:theme];
[self.optionView2 setTheme:theme];
[self.optionView3 setTheme:theme];
self.selectedBackgroundView.backgroundColor = selectedBackgroundViewBackgroundColor;
}
@end
//
// BUYProductView.h
// ProductView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,18 +25,16 @@
//
@import UIKit;
@class BUYProductViewHeader;
@class BUYProductViewHeaderBackgroundImageView;
@class BUYProductViewFooter;
@class BUYGradientView;
@class BUYTheme;
@class BUYImageLink;
@class BUYProduct;
@import Buy;
@class ActionableFooterView;
@class GradientView;
@class ProductViewHeader;
@class HeaderBackgroundView;
/**
* The BUYProductViewController's main view, containing everything needed to display the UI for the product
*/
@interface BUYProductView : UIView
@interface ProductView : UIView
/**
* The table view containg the product's image(s) in the tableHeaderView, title, price,
......@@ -64,24 +62,19 @@
/**
* The tableHeaderView containting the product image(s) (if available)
*/
@property (nonatomic, strong) BUYProductViewHeader *productViewHeader;
@property (nonatomic, strong) BUYProductViewHeaderBackgroundImageView *backgroundImageView;
@property (nonatomic, strong) ProductViewHeader *productViewHeader;
@property (nonatomic, strong) HeaderBackgroundView *backgroundImageView;
/**
* The footer view containing the Checkout button, and - if enabled - Apple Pay button.
*/
@property (nonatomic, strong) BUYProductViewFooter *productViewFooter;
@property (nonatomic, strong) ActionableFooterView *productViewFooter;
/**
* A gradient view that sits at the top of the product images (if available).
* This view is invisible when the navigation bar is visible.
*/
@property (nonatomic, strong) BUYGradientView *topGradientView;
/**
* The theme of the product view.
*/
@property (nonatomic, weak) BUYTheme *theme;
@property (nonatomic, strong) GradientView *topGradientView;
/**
* Helps determine logic for setting up product images in the BUYProductViewController
......@@ -91,14 +84,14 @@
/**
* Initializer for the product view using a rect, product to display and theme
*
* @param rect The rect is needed for the UICollectionView in the BUYProductViewHeader to setup the cell's bounds
* @param rect The rect is needed for the UICollectionView in the ProductViewHeader to setup the cell's bounds
* @param product The product to display in the product view. Only used in the initializer to
* @param theme The theme for the product view
* @param showApplePaySetup Show Apple Pay button with 'Set Up Apple Pay' text as determined by the presenter
*
* @return An instance of the BUYProductView
* @return An instance of the ProductView
*/
- (instancetype)initWithFrame:(CGRect)rect product:(BUYProduct*)product theme:(BUYTheme*)theme shouldShowApplePaySetup:(BOOL)showApplePaySetup;
- (instancetype)initWithFrame:(CGRect)rect product:(BUYProduct*)product shouldShowApplePaySetup:(BOOL)showApplePaySetup;
/**
* The BUYProductViewController is the UITableViewDelegate, so it receives the UIScrollView delegate method calls.
......@@ -138,4 +131,6 @@
*/
- (void)setTopInset:(CGFloat)topInset;
- (void)setShowsProductImageBackground:(BOOL)showsProductImageBackground UI_APPEARANCE_SELECTOR;
@end
//
// BUYProductView.m
// ProductView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,38 +24,32 @@
// THE SOFTWARE.
//
#import "BUYProductView.h"
#import "BUYProductViewHeader.h"
#import "BUYProductViewHeaderBackgroundImageView.h"
#import "BUYProductViewFooter.h"
#import "BUYGradientView.h"
#import "BUYProductVariantCell.h"
#import "BUYProductDescriptionCell.h"
#import "BUYProductHeaderCell.h"
#import "BUYImageLink.h"
#import "BUYImageView.h"
#import "BUYProduct.h"
#import "BUYProductViewErrorView.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "ProductView.h"
#import "ProductViewHeader.h"
#import "HeaderBackgroundView.h"
#import "ActionableFooterView.h"
#import "GradientView.h"
#import "ProductVariantCell.h"
#import "ProductDescriptionCell.h"
#import "ProductHeaderCell.h"
#import "AsyncImageView.h"
#import "ErrorView.h"
#import "Theme+Additions.h"
@interface BUYProductView ()
@interface ProductView ()
@property (nonatomic, strong) UILabel *poweredByShopifyLabel;
@property (nonatomic, strong) NSLayoutConstraint *poweredByShopifyLabelConstraint;
@property (nonatomic, strong) BUYProductViewErrorView *errorView;
@property (nonatomic, strong) ErrorView *errorView;
@property (nonatomic, strong) NSLayoutConstraint *topInsetConstraint;
@end
@implementation BUYProductView
@implementation ProductView
- (instancetype)initWithFrame:(CGRect)rect product:(BUYProduct*)product theme:(BUYTheme*)theme shouldShowApplePaySetup:(BOOL)showApplePaySetup
- (instancetype)initWithFrame:(CGRect)rect product:(BUYProduct*)product shouldShowApplePaySetup:(BOOL)showApplePaySetup
{
self = [super initWithFrame:rect];
if (self) {
_backgroundImageView = [[BUYProductViewHeaderBackgroundImageView alloc] initWithTheme:theme];
_backgroundImageView.hidden = theme.showsProductImageBackground == NO;
_backgroundImageView = [[HeaderBackgroundView alloc] init];
_backgroundImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_backgroundImageView];
......@@ -75,7 +69,6 @@
constant:0.0]];
_stickyFooterView = [UIView new];
_stickyFooterView.backgroundColor = [theme backgroundColor];
_stickyFooterView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_stickyFooterView];
......@@ -114,9 +107,9 @@
_tableView.layoutMargins = UIEdgeInsetsMake(_tableView.layoutMargins.top, kBuyPaddingExtraLarge, _tableView.layoutMargins.bottom, kBuyPaddingMedium);
[self addSubview:_tableView];
[_tableView registerClass:[BUYProductHeaderCell class] forCellReuseIdentifier:@"headerCell"];
[_tableView registerClass:[BUYProductVariantCell class] forCellReuseIdentifier:@"variantCell"];
[_tableView registerClass:[BUYProductDescriptionCell class] forCellReuseIdentifier:@"descriptionCell"];
[_tableView registerClass:[ProductHeaderCell class] forCellReuseIdentifier:@"headerCell"];
[_tableView registerClass:[ProductVariantCell class] forCellReuseIdentifier:@"variantCell"];
[_tableView registerClass:[ProductDescriptionCell class] forCellReuseIdentifier:@"descriptionCell"];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_tableView]|"
options:0
......@@ -138,35 +131,13 @@
CGFloat size = MIN(CGRectGetWidth(rect), CGRectGetHeight(rect));
if ([product.images count] > 0) {
_productViewHeader = [[BUYProductViewHeader alloc] initWithFrame:CGRectMake(0, 0, size, size) theme:theme];
_productViewHeader = [[ProductViewHeader alloc] initWithFrame:CGRectMake(0, 0, size, size)];
_tableView.tableHeaderView = self.productViewHeader;
} else {
_tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)];
}
_poweredByShopifyLabel = [[UILabel alloc] init];
_poweredByShopifyLabel.translatesAutoresizingMaskIntoConstraints = NO;
_poweredByShopifyLabel.backgroundColor = [UIColor clearColor];
_poweredByShopifyLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
_poweredByShopifyLabel.text = @"Powered by Shopify";
_poweredByShopifyLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_poweredByShopifyLabel];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_poweredByShopifyLabel]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_poweredByShopifyLabel)]];
_poweredByShopifyLabelConstraint = [NSLayoutConstraint constraintWithItem:_poweredByShopifyLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0];
[self addConstraint:_poweredByShopifyLabelConstraint];
_productViewFooter = [[BUYProductViewFooter alloc] initWithTheme:theme showApplePaySetup:showApplePaySetup];
_productViewFooter = [ActionableFooterView new];
_productViewFooter.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_productViewFooter];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_productViewFooter]|"
......@@ -179,8 +150,8 @@
views:NSDictionaryOfVariableBindings(_productViewFooter)]];
if (_productViewHeader) {
_topGradientView = [[BUYGradientView alloc] init];
_topGradientView.topColor = [BUYTheme topGradientViewTopColor];
_topGradientView = [[GradientView alloc] init];
_topGradientView.topColor = [Theme topGradientViewTopColor];
_topGradientView.translatesAutoresizingMaskIntoConstraints = NO;
_topGradientView.userInteractionEnabled = NO;
[self addSubview:_topGradientView];
......@@ -194,8 +165,6 @@
metrics:@{ @"height" : @(kBuyTopGradientViewHeight) }
views:NSDictionaryOfVariableBindings(_topGradientView)]];
}
self.theme = theme;
}
return self;
}
......@@ -206,17 +175,6 @@
[self setInsets:UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, CGRectGetHeight(self.bounds) - CGRectGetMinY(self.productViewFooter.frame), self.tableView.contentInset.right) appendToCurrentInset:NO];
}
- (void)setTheme:(BUYTheme *)theme
{
_theme = theme;
self.tintColor = _theme.tintColor;
self.tableView.separatorColor = [theme separatorColor];
self.backgroundColor = [theme backgroundColor];
self.stickyFooterView.backgroundColor = self.backgroundColor;
self.backgroundImageView.hidden = theme.showsProductImageBackground == NO;
self.poweredByShopifyLabel.textColor = self.tableView.separatorColor;
}
- (void)updateBackgroundImage:(NSArray *)images
{
if ([images count] > 0) {
......@@ -253,17 +211,14 @@
CGFloat opaqueOffset = CGRectGetHeight(self.productViewHeader.bounds);
CGFloat whiteStartingOffset = opaqueOffset - CGRectGetHeight(self.topGradientView.bounds);
self.topGradientView.alpha = -(scrollView.contentOffset.y - whiteStartingOffset) / (opaqueOffset - whiteStartingOffset);
CGFloat labelOffset = scrollView.contentSize.height - (scrollView.contentOffset.y + CGRectGetHeight(scrollView.bounds));
self.poweredByShopifyLabelConstraint.constant = (CGRectGetHeight(scrollView.bounds) / 3) + labelOffset;
}
#pragma mark - Error Handling
- (BUYProductViewErrorView *)errorView
- (ErrorView *)errorView
{
if (_errorView == nil) {
_errorView = [[BUYProductViewErrorView alloc] initWithTheme:self.theme];
_errorView = [[ErrorView alloc] init];
_errorView.alpha = 0;
_errorView.translatesAutoresizingMaskIntoConstraints = NO;
[self insertSubview:_errorView belowSubview:self.productViewFooter];
......@@ -298,36 +253,9 @@
- (void)showErrorWithMessage:(NSString*)errorMessage
{
self.errorView.errorLabel.text = errorMessage;
[NSLayoutConstraint deactivateConstraints:@[self.errorView.hiddenConstraint]];
[NSLayoutConstraint activateConstraints:@[self.errorView.visibleConstraint]];
[UIView animateWithDuration:0.3f
delay:0
usingSpringWithDamping:0.8f
initialSpringVelocity:10
options:0
animations:^{
self.errorView.alpha = 1;
[self.errorView layoutIfNeeded];
}
completion:^(BOOL finished) {
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(removeErrorView) userInfo:nil repeats:NO];
}];
}
- (void)removeErrorView
{
[NSLayoutConstraint deactivateConstraints:@[self.errorView.visibleConstraint]];
[NSLayoutConstraint activateConstraints:@[self.errorView.hiddenConstraint]];
[UIView animateWithDuration:0.3f
animations:^{
self.errorView.alpha = 0;
[self.errorView layoutIfNeeded];
}
completion:^(BOOL finished) {
[self.errorView removeFromSuperview];
self.errorView = nil;
}];
[self.errorView presentErrorViewWithMessage:errorMessage completion:^{
self.errorView = nil;
}];
}
- (void)setInsets:(UIEdgeInsets)edgeInsets appendToCurrentInset:(BOOL)appendToCurrentInset
......@@ -344,4 +272,16 @@
self.topInsetConstraint.constant = topInset;
}
#pragma mark - Appearance
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
_stickyFooterView.backgroundColor = backgroundColor;
}
- (void)setShowsProductImageBackground:(BOOL)showsProductImageBackground
{
_backgroundImageView.hidden = showsProductImageBackground == NO;
}
@end
//
// BUYProductViewController.h
// ProductViewController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,11 +24,13 @@
// THE SOFTWARE.
//
#import "BUYTheme.h"
#import "BUYViewController.h"
#import "BUYClient.h"
@import UIKit;
@import Buy;
@interface BUYProductViewController : BUYViewController <BUYThemeable>
#import "Theme.h"
#import "PaymentViewController.h"
@interface ProductViewController : PaymentViewController
/**
* Creates a BUYProductViewController with a BUYClient and a theme
......@@ -37,11 +39,21 @@
* use `initWithClient:`
*
* @param client A BUYClient configured to your shop
* @param theme A BUYTheme
* @param theme A Theme
*
* @return A PaymentViewController
*/
- (instancetype)initWithClient:(BUYClient *)client theme:(Theme *)theme;
/**
* Creates a BUYProductViewController with a BUYClient and a cart
*
* @param client A BUYClient configured to your shop
* @param cart A cart that enables a "Add to cart" button instead of the web checout button
*
* @return A BUYViewController
* @return A PaymentViewController with an "Add to cart" button
*/
- (instancetype)initWithClient:(BUYClient *)client theme:(BUYTheme *)theme;
- (instancetype)initWithClient:(BUYClient *)client cart:(BUYCart *)cart;
/**
* Loads the product details
......
//
// ProductViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "ProductViewController.h"
#import "GradientView.h"
#import "AsyncImageView.h"
#import "OptionSelectionNavigationController.h"
#import "ProductViewPresentationController.h"
#import "ImageKit.h"
#import "ProductView.h"
#import "ProductHeaderCell.h"
#import "ProductVariantCell.h"
#import "ProductDescriptionCell.h"
#import "ProductViewHeader.h"
#import "ProductImageCell.h"
#import "HeaderBackgroundView.h"
#import "HeaderOverlayView.h"
#import "ProductViewNavigationController.h"
#import "Theme+Additions.h"
#import "VariantSelectionViewController.h"
#import "CheckoutButton.h"
#import "ActionableFooterView.h"
CGFloat const BUYMaxProductViewWidth = 414.0; // We max out to the width of the iPhone 6+
CGFloat const BUYMaxProductViewHeight = 640.0;
@interface ProductViewController (Private)
@property (nonatomic, strong) BUYWebCheckoutPaymentProvider *webPaymentProvider;
@property (nonatomic, strong) BUYApplePayPaymentProvider *applePayPaymentProvider;
@end
@interface ProductViewController () <UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate, VariantSelectionDelegate, ProductViewNavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) NSString *productId;
@property (nonatomic, strong) BUYProductVariant *selectedProductVariant;
@property (nonatomic, strong) Theme *theme;
@property (nonatomic, assign) BOOL shouldShowVariantSelector;
@property (nonatomic, assign) BOOL shouldEnableVariantSelection;
@property (nonatomic, assign) BOOL shouldShowDescription;
@property (nonatomic, strong) BUYProduct *product;
@property (nonatomic, assign) BOOL isLoading;
@property (nonatomic, strong) NSNumberFormatter *currencyFormatter;
@property (nonatomic, weak) BUYCart *cart;
@property (nonatomic, assign) BOOL isLoadingShop;
// views
@property (nonatomic, strong) ProductView *productView;
@property (nonatomic, weak) UIView *navigationBar;
@property (nonatomic, weak) UILabel *navigationBarTitle;
@property (nonatomic, strong) ProductHeaderCell *headerCell;
@property (nonatomic, strong) ProductVariantCell *variantCell;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
// Share items
@property (nonatomic, strong, readonly) NSString *titleForSharing;
@property (nonatomic, strong, readonly) NSURL *URLForSharing;
@property (nonatomic, strong, readonly) UIImage *imageForSharing;
@property (nonatomic, strong, readonly) NSArray *itemsForSharing;
@end
@implementation ProductViewController
- (instancetype)initWithClient:(BUYClient *)client
{
self = [super initWithClient:client];
if (self) {
self.modalPresentationStyle = UIModalPresentationCustom;
self.transitioningDelegate = self;
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
_activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO;
_activityIndicatorView.hidesWhenStopped = YES;
[_activityIndicatorView startAnimating];
[self.view addSubview:_activityIndicatorView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicatorView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicatorView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
}
return self;
}
- (instancetype)initWithClient:(BUYClient *)client theme:(Theme *)theme
{
NSParameterAssert(client);
self = [self initWithClient:client];
if (self) {
if (theme == nil) {
theme = [Theme new];
}
[theme styleProductViewController];
}
return self;
}
- (instancetype)initWithClient:(BUYClient *)client cart:(BUYCart *)cart
{
NSParameterAssert(cart);
self = [self initWithClient:client];
if (self) {
self.cart = cart;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
}
- (ProductView *)productView
{
if (_productView == nil && self.product != nil && self.shop != nil) {
_productView = [[ProductView alloc] initWithFrame:CGRectMake(0, 0, self.preferredContentSize.width, self.preferredContentSize.height) product:self.product shouldShowApplePaySetup:self.shouldShowApplePaySetup];
_productView.translatesAutoresizingMaskIntoConstraints = NO;
_productView.hidden = YES;
[self.view addSubview:_productView];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_productView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_productView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_productView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_productView)]];
_productView.tableView.delegate = self;
_productView.tableView.dataSource = self;
[_productView.productViewFooter setApplePayAvailable:self.shouldShowApplePayButton requiresSetup:self.shouldShowApplePaySetup];
[_productView.productViewFooter.paymentButton addTarget:self action:@selector(checkoutWithApplePay) forControlEvents:UIControlEventTouchUpInside];
if (self.cart) {
[_productView.productViewFooter.actionButton setTitle:NSLocalizedString(@"Add to Cart", nil) forState:UIControlStateNormal];
[_productView.productViewFooter.actionButton addTarget:self action:@selector(addSelectedVariantToCart) forControlEvents:UIControlEventTouchUpInside];
}
else {
[_productView.productViewFooter.actionButton addTarget:self action:@selector(checkoutWithShopify) forControlEvents:UIControlEventTouchUpInside];
}
_productView.productViewHeader.collectionView.delegate = self;
_productView.productViewHeader.collectionView.dataSource = self;
_productView.layoutMargins = UIEdgeInsetsMake(self.productView.layoutMargins.top, self.productView.layoutMargins.left, self.bottomLayoutGuide.length, self.productView.layoutMargins.right);
}
return _productView;
}
- (CGSize)preferredContentSize
{
return CGSizeMake(MIN(BUYMaxProductViewWidth, self.view.bounds.size.width),
MIN(BUYMaxProductViewHeight, self.view.bounds.size.height));
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupNavigationBarAppearance];
[self.navigationController setNavigationBarHidden:(self.presentingViewController && self.isLoading)];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (self.productView.hasSetVariantOnCollectionView == NO) {
if ([self canCollectionViewDrawProductImages] || [self.product.images count] == 0) {
[self setSelectedProductVariant:self.selectedProductVariant];
self.productView.hasSetVariantOnCollectionView = YES;
}
}
}
- (BOOL)canCollectionViewDrawProductImages
{
return [self.product.images count] > 0 && CGSizeEqualToSize(self.productView.productViewHeader.collectionView.bounds.size, CGSizeZero) == NO;
}
- (void)setupNavigationBarAppearance
{
if (self.navigationBar == nil && _productView && self.presentingViewController != nil) {
[(ProductViewNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:NO duration:0];
for (UIView *view in [self.navigationController.navigationBar subviews]) {
if (CGRectGetHeight(view.bounds) >= 44) {
// Get a reference to the UINavigationBar
self.navigationBar = view;
self.navigationBar.alpha = 0;
continue;
} else if ([view.subviews count] == 1 && [view.subviews[0] isKindOfClass:[UILabel class]]) {
// Get a reference to the UINavigationBar's title
self.navigationBarTitle = view.subviews[0];
self.navigationBarTitle.alpha = 0;
continue;
}
}
// Hide the navigation bar
[self scrollViewDidScroll:self.productView.tableView];
} else if (self.navigationController && _productView && self.presentingViewController == nil) {
[self.productView setTopInset:CGRectGetHeight(self.navigationController.navigationBar.bounds) + self.navigationController.topLayoutGuide.length];
}
}
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
{
ProductViewPresentationController *presentationController = [[ProductViewPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
presentationController.delegate = presentationController;
presentationController.navigationDelegate = self;
return presentationController;
}
- (void)loadProduct:(NSString *)productId completion:(void (^)(BOOL success, NSError *error))completion
{
if (productId == nil) {
if (completion) {
completion(NO, [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoProductSpecified userInfo:nil]);
}
} else {
self.isLoading = YES;
[self getShopWithCallback:^(BOOL success, NSError *error) {
if (success) {
self.productId = productId;
[self.client getProductById:productId completion:^(BUYProduct *product, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
if (completion) {
completion(NO, error);
}
} else {
self.product = product;
if (completion) {
completion(YES, nil);
}
}
});
}];
} else {
self.isLoading = NO;
if (completion) {
completion(success, error);
}
}
}];
}
}
- (void)loadWithProduct:(BUYProduct *)product completion:(void (^)(BOOL success, NSError *error))completion;
{
if (product == nil) {
completion(NO, [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoProductSpecified userInfo:nil]);
} else {
self.isLoading = YES;
if (self.shop == nil) {
[self getShopWithCallback:^(BOOL success, NSError *error) {
if (success) {
self.product = product;
}
if (completion) {
completion(success, error);
}
}];
} else {
self.product = product;
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion(YES, nil);
}
});
}
}
}
- (void)getShopWithCallback:(void (^)(BOOL, NSError *))block
{
// fetch shop details for the currency and country codes
self.isLoadingShop = YES;
[self.client getShop:^(BUYShop *shop, NSError *error) {
if (error == nil) {
self.shop = shop;
}
else {
if ([self.delegate respondsToSelector:@selector(controllerFailedToStartApplePayProcess:)]) {
[self.delegate controllerFailedToStartApplePayProcess:self];
}
}
self.isLoadingShop = NO;
if (block) block((error == nil), error);
}];
}
- (void)setProduct:(BUYProduct *)product
{
self.isLoading = NO;
_product = product;
self.navigationItem.title = _product.title;
self.selectedProductVariant = [_product.variants firstObject];
self.shouldShowVariantSelector = [_product isDefaultVariant] == NO;
self.shouldEnableVariantSelection = self.shouldShowVariantSelector && [_product.variants count] > 1;
self.shouldShowDescription = ([_product.htmlDescription length] == 0) == NO;
self.productView.hidden = NO;
[self setupNavigationBarAppearance];
[self.activityIndicatorView stopAnimating];
[self setNeedsStatusBarAppearanceUpdate];
if (self.presentingViewController) {
[self.navigationController setNavigationBarHidden:NO];
}
if (self.product.publicURL) {
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(shareLink)];
NSArray *rightButtons = [@[rightButton] arrayByAddingObjectsFromArray:self.navigationItem.rightBarButtonItems];
self.navigationItem.rightBarButtonItems = rightButtons;
}
}
- (void)setShop:(BUYShop *)shop
{
[super setShop:shop];
self.currencyFormatter = [[NSNumberFormatter alloc] init];
self.currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
self.currencyFormatter.currencyCode = shop.currency;
[self.productView.productViewFooter setApplePayAvailable:self.shouldShowApplePaySetup requiresSetup:self.shouldShowApplePaySetup];
[self.productView.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
if (self.product) {
rows += 1; // product title and price
rows += self.shouldShowVariantSelector;
rows += self.shouldShowDescription;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *theCell = nil;
if (indexPath.row == 0) {
ProductHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"headerCell"];
[cell setProductVariant:self.selectedProductVariant withCurrencyFormatter:self.currencyFormatter];
self.headerCell = cell;
theCell = cell;
} else if (indexPath.row == 1 && self.shouldShowVariantSelector) {
ProductVariantCell *cell = [tableView dequeueReusableCellWithIdentifier:@"variantCell"];
[cell setOptionsForProductVariant:self.selectedProductVariant];
cell.accessoryType = self.shouldEnableVariantSelection ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
self.variantCell = cell;
theCell = cell;
} else if ((indexPath.row == 2 && self.shouldShowDescription) || (indexPath.row == 1 && self.shouldShowVariantSelector == NO && self.shouldShowDescription)) {
ProductDescriptionCell *cell = [tableView dequeueReusableCellWithIdentifier:@"descriptionCell"];
cell.descriptionHTML = self.product.htmlDescription;
cell.separatorInset = UIEdgeInsetsMake(0, CGRectGetWidth(self.productView.tableView.bounds), 0, 0);
theCell = cell;
}
return theCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1 && self.shouldEnableVariantSelection) {
[self.productView.tableView deselectRowAtIndexPath:indexPath animated:YES];
VariantSelectionViewController *optionSelectionViewController = [[VariantSelectionViewController alloc] initWithProduct:self.product];
optionSelectionViewController.selectedProductVariant = self.selectedProductVariant;
optionSelectionViewController.delegate = self;
optionSelectionViewController.currencyFormatter = self.currencyFormatter;
OptionSelectionNavigationController *optionSelectionNavigationController = [[OptionSelectionNavigationController alloc] initWithRootViewController:optionSelectionViewController];
[self presentViewController:optionSelectionNavigationController animated:YES completion:nil];
}
}
#pragma mark - BUYVariantSelectionViewControllerDelegate
- (void)variantSelectionController:(VariantSelectionViewController *)controller didSelectVariant:(BUYProductVariant *)variant
{
if (self.selectedProductVariant != variant) {
self.selectedProductVariant = variant;
[self.productView.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[self dismissViewControllerAnimated:YES completion:^{
[self setNeedsStatusBarAppearanceUpdate];
[self scrollViewDidScroll:self.productView.tableView];
}];
}
- (void)variantSelectionControllerDidCancelVariantSelection:(VariantSelectionViewController *)controller atOptionIndex:(NSUInteger)optionIndex
{
[self dismissViewControllerAnimated:YES completion:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (void)setSelectedProductVariant:(BUYProductVariant *)selectedProductVariant {
_selectedProductVariant = selectedProductVariant;
if (self.headerCell) {
[self.headerCell setProductVariant:selectedProductVariant withCurrencyFormatter:self.currencyFormatter];
[self.variantCell setOptionsForProductVariant:self.selectedProductVariant];
}
if (self.productView.productViewHeader.collectionView) {
[self.productView.productViewHeader setImageForSelectedVariant:_selectedProductVariant withImages:[self.product.images array]];
[self.productView updateBackgroundImage:[self.product.images array]];
}
if (self.productView.productViewFooter) {
self.productView.productViewFooter.actionButton.enabled = selectedProductVariant.available.boolValue;
self.productView.productViewFooter.paymentButton.enabled = selectedProductVariant.available.boolValue;
}
if (self.productView.tableView) {
[self scrollViewDidScroll:self.productView.tableView];
}
}
#pragma mark Scroll view delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ([scrollView isKindOfClass:[UITableView class]]) {
if (self.productView.productViewHeader) {
[self.productView scrollViewDidScroll:scrollView];
if (self.navigationBar) {
CGFloat duration = 0.3f;
if (self.navigationBar.alpha != 1 && [self navigationBarThresholdReached] == YES) {
[(ProductViewNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:YES duration:duration];
[UIView animateWithDuration:duration
delay:0
options:(UIViewAnimationOptionCurveLinear | UIViewKeyframeAnimationOptionBeginFromCurrentState)
animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationBar.alpha = 1;
self.navigationBarTitle.alpha = 1;
}
completion:NULL];
} else if (self.navigationBar.alpha != 0 && [self navigationBarThresholdReached] == NO) {
duration = 0.2f;
[(ProductViewNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:NO duration:duration];
[UIView animateWithDuration:duration
delay:0
options:(UIViewAnimationOptionCurveLinear | UIViewKeyframeAnimationOptionBeginFromCurrentState)
animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationBar.alpha = 0;
self.navigationBarTitle.alpha = 0;
}
completion:NULL];
}
[self.productView.productViewHeader.productViewHeaderOverlay scrollViewDidScroll:scrollView withNavigationBarHeight:CGRectGetHeight(self.navigationBar.bounds)];
}
} else if (self.productView.productViewHeader == nil && self.navigationBar && self.navigationBar.alpha == 0) {
[(ProductViewNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:YES duration:0];
self.navigationBar.alpha = 1;
self.navigationBarTitle.alpha = 1;
CGFloat topInset = 0;
if (self.presentingViewController) {
topInset = CGRectGetHeight([[(UINavigationController*)self.presentingViewController navigationBar] bounds]) + self.presentingViewController.topLayoutGuide.length;
}
[self.productView setInsets:UIEdgeInsetsMake(topInset, 0, 0, 0) appendToCurrentInset:YES];
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if ([scrollView isKindOfClass:[UICollectionView class]]) {
[self.productView updateBackgroundImage:[self.product.images array]];
}
}
#pragma mark Checkout
- (void)addSelectedVariantToCart
{
[self.cart addVariant:self.selectedProductVariant];
}
- (void)checkoutWithApplePay
{
if (self.isApplePayAvailable) {
self.checkout = [self checkoutWithVariant:self.selectedProductVariant];
[self startApplePayCheckout:self.checkout];
} else {
[[[PKPassLibrary alloc] init] openPaymentSetup];
}
}
- (void)checkoutWithShopify
{
self.checkout = [self checkoutWithVariant:self.selectedProductVariant];
[self startWebCheckout:self.checkout];
}
- (BUYCheckout *)checkoutWithVariant:(BUYProductVariant *)variant
{
BUYModelManager *modelManager = self.client.modelManager;
BUYCart *cart = [modelManager insertCartWithJSONDictionary:nil];
[cart addVariant:variant];
return [modelManager checkoutWithCart:cart];
}
#pragma mark UIStatusBar appearance
- (UIStatusBarStyle)preferredStatusBarStyle
{
if (self.navigationController.navigationBar.barStyle == UIBarStyleBlack || ([self navigationBarThresholdReached] == NO && self.isLoading == NO && self.productView.productViewHeader)) {
return UIStatusBarStyleLightContent;
} else if (self.isLoading == YES && self.navigationController.navigationBar.barStyle == UIBarStyleBlack && self.productView.productViewHeader) {
return UIStatusBarStyleLightContent;
} else {
return UIStatusBarStyleDefault;
}
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationFade;
}
- (BOOL)navigationBarThresholdReached
{
return self.productView.tableView.contentOffset.y > CGRectGetHeight(self.productView.productViewHeader.bounds) - CGRectGetHeight(self.navigationBar.bounds);
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate {
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
}
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
{
}
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
{
if ([self.delegate respondsToSelector:@selector(didDismissViewController:)]) {
[self.delegate didDismissViewController:self];
}
_product = nil;
_productId = nil;
[_productView removeFromSuperview];
_productView = nil;
}
#pragma mark - Collection View Delegate and Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.product.images count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ProductImageCell *cell = (ProductImageCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
BUYImageLink *image = self.product.images[indexPath.row];
[cell.productImageView loadImageWithURL:image.sourceURL completion:NULL];
[cell setContentOffset:self.productView.tableView.contentOffset];
return cell;
}
- (void)presentPortraitInViewController:(UIViewController *)controller
{
ProductViewNavigationController *navController = [[ProductViewNavigationController alloc] initWithRootViewController:self];
navController.modalPresentationStyle = [ProductViewPresentationController adaptivePresentationStyle];
navController.navigationDelegate = self;
[controller presentViewController:navController animated:YES completion:nil];
}
#pragma mark - Share sheet
- (void)shareLink
{
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:self.itemsForSharing applicationActivities:nil];
[self presentViewController:activityController animated:YES completion:nil];
}
- (NSString *)titleForSharing
{
return self.product.title;
}
- (NSURL *)URLForSharing
{
return self.product.publicURL;
}
- (UIImage *)ImageForSharing
{
UICollectionView *collectionView = self.productView.productViewHeader.collectionView;
NSIndexPath *selectedIndex = collectionView.indexPathsForVisibleItems.firstObject;
ProductImageCell *cell = (ProductImageCell *)[collectionView cellForItemAtIndexPath:selectedIndex];
return cell.productImageView.image;
}
- (NSArray *)itemsForSharing
{
return [NSArray arrayWithObjects:self.titleForSharing, self.URLForSharing, self.imageForSharing, nil];
}
#pragma mark - Payment delegate methods
- (void)willStartCheckout
{
[_productView.productViewFooter.actionButton showActivityIndicator:NO];
if ([self.delegate respondsToSelector:@selector(controllerWillCheckoutViaWeb:)]) {
[self.delegate controllerWillCheckoutViaWeb:self];
}
}
- (void)didFailCheckoutWithError:(NSError *)error
{
[_productView.productViewFooter.actionButton showActivityIndicator:NO];
[self.productView showErrorWithMessage:@"Could not checkout at this time"];
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
@end
//
// BUYProductViewHeader.h
// ProductViewHeader.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,16 +25,17 @@
//
@import UIKit;
@class BUYImageView;
@import Buy;
@class AsyncImageView;
@class BUYProductVariant;
@class BUYTheme;
@class BUYProductViewHeaderOverlay;
@class HeaderOverlayView;
/**
* The tableHeaderView containing a horizontally scrolling collection view
* that display product images.
*/
@interface BUYProductViewHeader : UIView
@interface ProductViewHeader : UIView
/**
* A horiztonally scrolling collection view containing product images.
......@@ -45,7 +46,7 @@
* An overlay view containing effects views (light or dark view and a UIVisualEffectsView) that becomes
* visible as the user scrolls the contents up. This provides a more seamless transition for the navigation bar.
*/
@property (nonatomic, strong) BUYProductViewHeaderOverlay *productViewHeaderOverlay;
@property (nonatomic, strong) HeaderOverlayView *productViewHeaderOverlay;
/**
* Initializer with a frame to setup the product image collection view and theme the header
......@@ -55,11 +56,11 @@
*
* @return The product view header to display in the BUYProductViewController's table view tableHeaderView
*/
- (instancetype)initWithFrame:(CGRect)frame theme:(BUYTheme*)theme;
- (instancetype)initWithFrame:(CGRect)frame;
/**
* A method to set the content offset of the table view and calculate the height of the image
* used to set the correct height and offset for the stickyFooterView in the BUYProductView.
* used to set the correct height and offset for the stickyFooterView in the ProductView.
*
* @param scrollView The table view being scrolled
*
......
//
// BUYProductViewHeader.m
// ProductViewHeader.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,29 +24,26 @@
// THE SOFTWARE.
//
#import "BUYProductViewHeader.h"
#import "BUYImageView.h"
#import "BUYGradientView.h"
#import "BUYProductImageCollectionViewCell.h"
#import "BUYImageLink.h"
#import "BUYProductVariant.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "BUYProductViewHeaderOverlay.h"
#import "ProductViewHeader.h"
#import "AsyncImageView.h"
#import "GradientView.h"
#import "ProductImageCell.h"
#import "Theme+Additions.h"
#import "HeaderOverlayView.h"
@interface BUYProductViewHeader ()
@interface ProductViewHeader ()
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) UIView *bottomGradientContainerView;
@property (nonatomic, strong) BUYGradientView *bottomGradientView;
@property (nonatomic, strong) GradientView *bottomGradientView;
@property (nonatomic, strong) NSLayoutConstraint *bottomGradientViewLayoutConstraintHeight;
@property (nonatomic, strong) NSLayoutConstraint *bottomGradientViewBottomContraint;
@end
@implementation BUYProductViewHeader
@implementation ProductViewHeader
- (instancetype)initWithFrame:(CGRect)frame theme:(BUYTheme*)theme
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
......@@ -63,7 +60,7 @@
_collectionView.pagingEnabled = YES;
_collectionView.clipsToBounds = NO;
_collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[_collectionView registerClass:[BUYProductImageCollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
[_collectionView registerClass:[ProductImageCell class] forCellWithReuseIdentifier:@"Cell"];
[self addSubview:_collectionView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_collectionView]|"
......@@ -101,7 +98,7 @@
constant:kBuyBottomGradientHeightWithoutPageControl];
[self addConstraint:_bottomGradientViewLayoutConstraintHeight];
_bottomGradientView = [[BUYGradientView alloc] init];
_bottomGradientView = [[GradientView alloc] init];
_bottomGradientView.userInteractionEnabled = NO;
_bottomGradientView.topColor = [UIColor clearColor];
_bottomGradientView.bottomColor = [UIColor colorWithWhite:0 alpha:0.05f];
......@@ -160,7 +157,7 @@
multiplier:1.0
constant:kBuyPageControlHeight]];
_productViewHeaderOverlay = [[BUYProductViewHeaderOverlay alloc] initWithTheme:theme];
_productViewHeaderOverlay = [[HeaderOverlayView alloc] init];
_productViewHeaderOverlay.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_productViewHeaderOverlay];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_productViewHeaderOverlay]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_productViewHeaderOverlay)]];
......@@ -192,7 +189,7 @@
CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];
BUYProductImageCollectionViewCell *cell = (BUYProductImageCollectionViewCell*)[self.collectionView cellForItemAtIndexPath:visibleIndexPath];
ProductImageCell *cell = (ProductImageCell*)[self.collectionView cellForItemAtIndexPath:visibleIndexPath];
if (cell) {
[cell setContentOffset:scrollView.contentOffset];
return cell.productImageViewConstraintHeight.constant;
......
//
// BUYNavigationController.h
// ProductViewNavigationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,10 +24,9 @@
// THE SOFTWARE.
//
@import UIKit;
#import "BUYTheme.h"
#import "NavigationController.h"
@protocol BUYNavigationControllerDelegate <NSObject>
@protocol ProductViewNavigationControllerDelegate <NSObject>
/**
* Delegate callback when the BUYProductViewController will dismiss
......@@ -45,10 +44,7 @@
@end
/**
* A custom navigation controller used in the BUYProductViewController, adding a close button and the ability to theme the navigation bar
*/
@interface BUYNavigationController : UINavigationController <BUYThemeable>
@interface ProductViewNavigationController : NavigationController
/**
* The close button has two styles; white or tint color. This methods updates the button image with the preferred style.
......@@ -60,9 +56,8 @@
- (void)updateCloseButtonImageWithTintColor:(BOOL)tintColor duration:(CGFloat)duration;
/**
* The BUYNavigationControllerDelegate
* The SmoothNavigationControllerDelegate
*/
@property (nonatomic, weak) id <BUYNavigationControllerDelegate> navigationDelegate;
@property (nonatomic, weak) id <ProductViewNavigationControllerDelegate> navigationDelegate;
@end
//
// BUYNavigationController.m
// ProductViewNavigationController.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,16 +24,12 @@
// THE SOFTWARE.
//
#import "BUYNavigationController.h"
#import "BUYImageKit.h"
#import "BUYTheme+Additions.h"
#import "BUYProductViewController.h"
#import "ProductViewNavigationController.h"
#import "ImageKit.h"
#import "Theme+Additions.h"
#import "ProductViewController.h"
@interface BUYNavigationController ()
@property (nonatomic, strong) BUYTheme *theme;
@end
@implementation BUYNavigationController
@implementation ProductViewNavigationController
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController
{
......@@ -45,18 +41,23 @@
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:closeButton];
self.topViewController.navigationItem.leftBarButtonItem = barButtonItem;
if ([[UINavigationBar class] respondsToSelector:@selector(appearanceWhenContainedInInstancesOfClasses:)]) {
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[BUYNavigationController class]]] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[ProductViewNavigationController class]]] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
} else {
[[UINavigationBar appearanceWhenContainedIn:[BUYNavigationController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedIn:[ProductViewNavigationController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
}
[self updateCloseButtonImageWithTintColor:YES duration:0];
return self;
}
- (void)updateCloseButtonImageWithTintColor:(BOOL)tintColor duration:(CGFloat)duration
{
UIButton *button = (UIButton*)self.topViewController.navigationItem.leftBarButtonItem.customView;
UIImage *newButtonImage = [BUYImageKit imageOfProductViewCloseImageWithFrame:button.bounds color:tintColor ? self.theme.tintColor : [UIColor whiteColor] hasShadow:tintColor == NO];
UIImage *newButtonImage = [ImageKit imageOfProductViewCloseImageWithFrame:button.bounds color:[UIColor whiteColor] hasShadow:tintColor == NO];
if (tintColor) {
newButtonImage = [newButtonImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}
[UIView transitionWithView:button.imageView
duration:duration
options:(UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionBeginFromCurrentState)
......@@ -86,18 +87,6 @@
return self.topViewController.shouldAutorotate;
}
- (void)setTheme:(BUYTheme *)theme
{
_theme = theme;
self.navigationBar.barStyle = [theme navigationBarStyle];
[self updateCloseButtonImageWithTintColor:NO duration:0];
if ([[UINavigationBar class] respondsToSelector:@selector(appearanceWhenContainedInInstancesOfClasses:)]) {
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[BUYNavigationController class]]] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [theme navigationBarTitleColor] }];
} else {
[[UINavigationBar appearanceWhenContainedIn:[BUYNavigationController class], nil] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [theme navigationBarTitleColor] }];
}
}
-(UIViewController *)childViewControllerForStatusBarStyle
{
return [self childViewController];
......@@ -110,7 +99,7 @@
-(UIViewController*)childViewController
{
if ([self.visibleViewController isKindOfClass:[BUYProductViewController class]] == NO) {
if ([self.visibleViewController isKindOfClass:[ProductViewController class]] == NO) {
return self.viewControllers[0];
}
return self.visibleViewController;
......
//
// BUYPresentationControllerWithNavigationController.h
// ProductViewPresentationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,16 +25,15 @@
//
@import UIKit;
#import "BUYTheme.h"
@protocol BUYPresentationControllerWithNavigationControllerDelegate;
@protocol ProductViewNavigationControllerDelegate;
/**
* Initialized the BUYProductViewController inside a navigation controller (`BUYNavigationController`).
* Initialized the BUYProductViewController inside a navigation controller (`ProductViewNavigationController`).
*/
@interface BUYPresentationControllerWithNavigationController : UIPresentationController <UIAdaptivePresentationControllerDelegate, BUYThemeable>
@interface ProductViewPresentationController : UIPresentationController <UIAdaptivePresentationControllerDelegate>
@property (nonatomic, weak) id <BUYNavigationControllerDelegate> navigationDelegate;
@property (nonatomic, weak) id <ProductViewNavigationControllerDelegate> navigationDelegate;
/**
* The desired presentation style
......
//
// BUYPresentationControllerWithNavigationController.m
// ProductViewPresentationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,23 +24,16 @@
// THE SOFTWARE.
//
#import "BUYNavigationController.h"
#import "BUYOptionSelectionNavigationController.h"
#import "BUYPresentationControllerWithNavigationController.h"
#import "BUYImageKit.h"
#import "OptionSelectionNavigationController.h"
#import "ProductViewPresentationController.h"
#import "ProductViewNavigationController.h"
@interface BUYPresentationControllerWithNavigationController ()
@property (nonatomic, strong) BUYTheme *theme;
@end
@implementation BUYPresentationControllerWithNavigationController
@implementation ProductViewPresentationController
- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
{
BUYNavigationController *navigationController = [[BUYNavigationController alloc] initWithRootViewController:controller.presentedViewController];
ProductViewNavigationController *navigationController = [[ProductViewNavigationController alloc] initWithRootViewController:controller.presentedViewController];
navigationController.navigationDelegate = self.navigationDelegate;
[navigationController setTheme:self.theme];
return navigationController;
}
......@@ -59,11 +52,4 @@
return (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) ? UIModalPresentationFullScreen : UIModalPresentationFormSheet;
}
- (void)setTheme:(BUYTheme *)theme
{
_theme = theme;
BUYNavigationController *navigationController = (BUYNavigationController*)self.presentedViewController;
[navigationController setTheme:theme];
}
@end
//
// BUYVariantOptionBreadCrumbsView.h
// OptionBreadCrumbsView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,12 +25,11 @@
//
@import UIKit;
#import "BUYTheme.h"
/**
* A view containing the current selection of variant option values that sits below the navigation controller for the variant selection.
*/
@interface BUYVariantOptionBreadCrumbsView : UIView <BUYThemeable>
@interface OptionBreadCrumbsView : UIView
/**
* Auto Layout constraint for setting the bread crumbs as hidden
......@@ -49,4 +48,9 @@
*/
- (void)setSelectedBuyOptionValues:(NSArray*)optionValues;
/**
* The color of the labels
*/
-(void)setVariantOptionTextColor:(UIColor*)color UI_APPEARANCE_SELECTOR;
@end
//
// BUYVariantOptionBreadCrumbsView.m
// OptionBreadCrumbsView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,10 +24,10 @@
// THE SOFTWARE.
//
#import "BUYVariantOptionBreadCrumbsView.h"
#import "BUYTheme+Additions.h"
#import "OptionBreadCrumbsView.h"
#import "Theme+Additions.h"
@interface BUYVariantOptionBreadCrumbsView ()
@interface OptionBreadCrumbsView ()
@property (nonatomic, strong) UILabel *optionOneLabel;
@property (nonatomic, strong) UILabel *optionTwoLabel;
......@@ -37,7 +37,7 @@
@end
@implementation BUYVariantOptionBreadCrumbsView
@implementation OptionBreadCrumbsView
- (instancetype)init
{
......@@ -47,15 +47,13 @@
_optionOneLabel = [UILabel new];
_optionOneLabel.translatesAutoresizingMaskIntoConstraints = NO;
_optionOneLabel.font = [BUYTheme variantBreadcrumbsFont];
_optionOneLabel.textColor = [BUYTheme variantBreadcrumbsTextColor];
_optionOneLabel.text = @"Selected: ";
_optionOneLabel.font = [Theme variantBreadcrumbsFont];
_optionOneLabel.text = NSLocalizedString(@"Selected: ", @"Prefix for selected option value in variant selector");
[self addSubview:_optionOneLabel];
_optionTwoLabel = [UILabel new];
_optionTwoLabel.translatesAutoresizingMaskIntoConstraints = NO;
_optionTwoLabel.font = [BUYTheme variantBreadcrumbsFont];
_optionTwoLabel.textColor = [BUYTheme variantBreadcrumbsTextColor];
_optionTwoLabel.font = [Theme variantBreadcrumbsFont];
_optionTwoLabel.alpha = 0;
[_optionTwoLabel setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
[self addSubview:_optionTwoLabel];
......@@ -78,11 +76,6 @@
return self;
}
- (void)setTheme:(BUYTheme *)theme
{
self.backgroundColor = [theme variantBreadcrumbsBackground];
}
- (void)setSelectedBuyOptionValues:(NSArray*)optionValues
{
if ([optionValues count] == 1) {
......@@ -128,4 +121,16 @@
}];
}
-(void)setBackgroundColor:(UIColor *)backgroundColor
{
[super setBackgroundColor:backgroundColor];
self.optionOneLabel.backgroundColor = self.optionTwoLabel.backgroundColor = self.backgroundColor;
}
-(void)setVariantOptionTextColor:(UIColor*)color
{
self.optionOneLabel.textColor = self.optionTwoLabel.textColor = color;
}
@end
//
// BUYNavigationController.h
// OptionSelectionNavigationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,14 +25,13 @@
//
@import UIKit;
#import "BUYNavigationController.h"
#import "BUYTheme.h"
#import "BUYVariantOptionBreadCrumbsView.h"
#import "NavigationController.h"
#import "OptionBreadCrumbsView.h"
/**
* Custom navigation controller for variant option selection
*/
@interface BUYOptionSelectionNavigationController : BUYNavigationController <BUYThemeable>
@interface OptionSelectionNavigationController : NavigationController
/**
* Used to set whether to dismiss with dropping animation when variant selection is cancelled instead of confirmed
......@@ -42,6 +41,6 @@
/**
* The bread crumbs view for variant option selections
*/
@property (nonatomic, strong) BUYVariantOptionBreadCrumbsView *breadsCrumbsView;
@property (nonatomic, strong) OptionBreadCrumbsView *breadsCrumbsView;
@end
//
// BUYNavigationController.m
// OptionSelectionNavigationController.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,16 +24,15 @@
// THE SOFTWARE.
//
#import "BUYOptionSelectionNavigationController.h"
#import "BUYPresentationControllerForVariantSelection.h"
#import "BUYImageKit.h"
#import "BUYTheme+Additions.h"
#import "OptionSelectionNavigationController.h"
#import "VariantSelectionPresentationController.h"
#import "ImageKit.h"
@interface BUYOptionSelectionNavigationController () <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
@interface OptionSelectionNavigationController () <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
@end
@implementation BUYOptionSelectionNavigationController
@implementation OptionSelectionNavigationController
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController
{
......@@ -46,18 +45,18 @@
self.view.clipsToBounds = YES;
// Add custom back button
UIImage *buttonImage = [[BUYImageKit imageOfVariantBackImageWithFrame:CGRectMake(0, 0, 12, 18)] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *buttonImage = [[ImageKit imageOfVariantBackImageWithFrame:CGRectMake(0, 0, 12, 18)] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
if ([[UIBarButtonItem class] respondsToSelector:@selector(appearanceWhenContainedInInstancesOfClasses:)]) {
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[BUYNavigationController class]]] setBackButtonBackgroundImage:[buttonImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 0)]
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[NavigationController class]]] setBackButtonBackgroundImage:[buttonImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 0)]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
} else {
[[UIBarButtonItem appearanceWhenContainedIn:[BUYNavigationController class], nil] setBackButtonBackgroundImage:[buttonImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 0)]
[[UIBarButtonItem appearanceWhenContainedIn:[NavigationController class], nil] setBackButtonBackgroundImage:[buttonImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 0)]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
}
_breadsCrumbsView = [BUYVariantOptionBreadCrumbsView new];
_breadsCrumbsView = [OptionBreadCrumbsView new];
_breadsCrumbsView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_breadsCrumbsView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_breadsCrumbsView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
......@@ -71,19 +70,11 @@
return self;
}
- (void)setTheme:(BUYTheme *)theme
{
[self.breadsCrumbsView setTheme:theme];
self.navigationBar.barStyle = [theme navigationBarStyle];
[self.navigationBar setTitleTextAttributes:@{ NSForegroundColorAttributeName : [theme navigationBarTitleVariantSelectionColor] }];
self.navigationBar.tintColor = theme.tintColor;
}
#pragma mark - Transitioning Delegate Methods
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
{
BUYPresentationControllerForVariantSelection *presentationController = [[BUYPresentationControllerForVariantSelection alloc] initWithPresentedViewController:presented presentingViewController:presenting];
VariantSelectionPresentationController *presentationController = [[VariantSelectionPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
return presentationController;
}
......@@ -126,7 +117,7 @@
UIView *dismissedView = [transitionContext viewForKey:UITransitionContextFromViewKey];
CGRect frame = dismissedView.frame;
CGAffineTransform transform;
BUYOptionSelectionNavigationController *optionSelectionNavigationController = (BUYOptionSelectionNavigationController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
OptionSelectionNavigationController *optionSelectionNavigationController = (OptionSelectionNavigationController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
if (optionSelectionNavigationController.dismissWithCancelAnimation) {
frame.origin.y += 150;
int angle = arc4random_uniform(20) - 10;
......
//
// BUYOptionSelectionViewController.h
// OptionSelectionViewController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,12 +25,10 @@
//
@import UIKit;
#import "BUYTheme.h"
@import Buy;
@class OptionSelectionViewController;
@class BUYOptionValue;
@class BUYOptionSelectionViewController;
@protocol BUYOptionSelectionDelegate <NSObject>
@protocol OptionSelectionDelegate <NSObject>
/**
* Called when a user selected an option value
......@@ -38,21 +36,21 @@
* @param controller The BUYOptionSelectionViewController
* @param optionValue The selected BUYOptionValue
*/
- (void)optionSelectionController:(BUYOptionSelectionViewController *)controller didSelectOptionValue:(BUYOptionValue *)optionValue;
- (void)optionSelectionController:(OptionSelectionViewController *)controller didSelectOptionValue:(BUYOptionValue *)optionValue;
/**
* Called when a user pops the navigation controller and backs out of the current option
*
* @param controller The BUYOptionSelectionViewController
*/
- (void)optionSelectionControllerDidBackOutOfChoosingOption:(BUYOptionSelectionViewController *)controller;
- (void)optionSelectionControllerDidBackOutOfChoosingOption:(OptionSelectionViewController *)controller;
@end
/**
* The view controller containing a table view with variant options for selection
*/
@interface BUYOptionSelectionViewController : UITableViewController <BUYThemeable>
@interface OptionSelectionViewController : UITableViewController
/**
* Initalizer for the BUYOptionSelectionViewController
......@@ -92,6 +90,6 @@
/**
* Delegate to inform about option selections and cancellations
*/
@property (nonatomic, weak) id <BUYOptionSelectionDelegate> delegate;
@property (nonatomic, weak) id <OptionSelectionDelegate> delegate;
@end
//
// BUYOptionSelectionViewController.m
// OptionSelectionViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,20 +24,19 @@
// THE SOFTWARE.
//
#import "BUYImageKit.h"
#import "BUYOptionSelectionViewController.h"
#import "BUYOptionValue.h"
#import "BUYOptionValueCell.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "ImageKit.h"
#import "OptionSelectionViewController.h"
#import "OptionValueCell.h"
#import "Theme+Additions.h"
@interface OptionSelectionViewController ()
@interface BUYOptionSelectionViewController ()
@property (nonatomic, strong) NSArray *optionValues;
@property (nonatomic, weak) BUYTheme *theme;
@property (nonatomic, strong) NSArray *filteredProductVariantsForSelectionOption;
@end
@implementation BUYOptionSelectionViewController
@implementation OptionSelectionViewController
- (instancetype)initWithOptionValues:(NSArray *)optionValues filteredProductVariantsForSelectionOption:(NSArray*)filteredProductVariantsForSelectionOption
{
......@@ -55,18 +54,10 @@
return self;
}
- (void)setTheme:(BUYTheme *)theme
{
_theme = theme;
self.view.backgroundColor = [theme backgroundColor];
self.tableView.backgroundColor = self.view.backgroundColor;
self.tableView.separatorColor = [theme separatorColor];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[BUYOptionValueCell class] forCellReuseIdentifier:@"Cell"];
[self.tableView registerClass:[OptionValueCell class] forCellReuseIdentifier:@"Cell"];
self.tableView.tableFooterView = [UIView new];
}
......@@ -97,15 +88,15 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BUYOptionValue *optionValue = self.optionValues[indexPath.row];
BUYOptionValueCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
OptionValueCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.selectedImageView.hidden = ![optionValue isEqual:self.selectedOptionValue];
if (self.isLastOption) {
cell.accessoryType = UITableViewCellAccessoryNone;
BUYProductVariant *productVariant = (BUYProductVariant*)self.filteredProductVariantsForSelectionOption[indexPath.row];
[cell setOptionValue:optionValue productVariant:productVariant currencyFormatter:self.currencyFormatter theme:self.theme];
[cell setOptionValue:optionValue productVariant:productVariant currencyFormatter:self.currencyFormatter];
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[cell setOptionValue:optionValue productVariant:nil currencyFormatter:nil theme:self.theme];
[cell setOptionValue:optionValue productVariant:nil currencyFormatter:nil];
}
[cell setNeedsLayout];
[cell layoutIfNeeded];
......
//
// BUYOptionValueCell.h
// OptionValueCell.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,14 +25,12 @@
//
@import UIKit;
@class BUYTheme;
@class BUYOptionValue;
@class BUYProductVariant;
@import Buy;
/**
* A table view cell displaying the option value
*/
@interface BUYOptionValueCell : UITableViewCell
@interface OptionValueCell : UITableViewCell
/**
* Image view containing a checkmark for current option value selection
......@@ -45,9 +43,10 @@
* @param optionValue The option value to display
* @param productVariant The product variant matching the option value
* @param currencyFormatter A formatter with the shop's currency
* @param theme The current theme
*/
- (void)setOptionValue:(BUYOptionValue *)optionValue productVariant:(BUYProductVariant*)productVariant currencyFormatter:(NSNumberFormatter*)currencyFormatter theme:(BUYTheme *)theme;
- (void)setOptionValue:(BUYOptionValue *)optionValue productVariant:(BUYProductVariant*)productVariant currencyFormatter:(NSNumberFormatter*)currencyFormatter;
- (void)setSelectedBackgroundViewBackgroundColor:(UIColor *)selectedBackgroundViewBackgroundColor UI_APPEARANCE_SELECTOR;
@end
//
// BUYOptionValueCell.m
// OptionValueCell.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,24 +24,24 @@
// THE SOFTWARE.
//
#import "BUYOptionValueCell.h"
#import "BUYImageKit.h"
#import "BUYOptionValue.h"
#import "BUYProductVariant.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "DisclosureIndicatorView.h"
#import "ImageKit.h"
#import "OptionValueCell.h"
#import "Theme+Additions.h"
@interface OptionValueCell()
@interface BUYOptionValueCell()
@property (nonatomic, strong) NSArray *priceConstraints;
@property (nonatomic, strong) NSArray *noPriceConstraints;
@property (nonatomic, strong) NSArray *disclosureConstraints;
@property (nonatomic, strong) NSArray *noDisclosureConstraints;
@property (nonatomic, strong) UIImageView *disclosureIndicatorImageView;
@property (nonatomic, strong) DisclosureIndicatorView *disclosureIndicatorImageView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *priceLabel;
@end
@implementation BUYOptionValueCell
@implementation OptionValueCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
......@@ -50,7 +50,6 @@
UIView *backgroundView = [[UIView alloc] init];
[self setSelectedBackgroundView:backgroundView];
self.textLabel.backgroundColor = [UIColor clearColor];
self.layoutMargins = UIEdgeInsetsMake(kBuyPaddingLarge, kBuyPaddingExtraLarge, kBuyPaddingLarge, kBuyPaddingLarge);
UIView *labelContainerView = [[UIView alloc] init];
......@@ -60,15 +59,15 @@
_titleLabel = [[UILabel alloc] init];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_titleLabel setFont:[BUYTheme variantOptionValueFont]];
[_titleLabel setFont:[Theme variantOptionValueFont]];
[labelContainerView addSubview:_titleLabel];
_priceLabel = [[UILabel alloc] init];
_priceLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_priceLabel setFont:[BUYTheme variantOptionPriceFont]];
[_priceLabel setFont:[Theme variantOptionPriceFont]];
[labelContainerView addSubview:_priceLabel];
UIImage *selectedImage = [BUYImageKit imageOfPreviousSelectionIndicatorImageWithFrame:CGRectMake(0, 0, 20, 20)];
UIImage *selectedImage = [ImageKit imageOfPreviousSelectionIndicatorImageWithFrame:CGRectMake(0, 0, 20, 20)];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
_selectedImageView = [[UIImageView alloc] initWithImage:selectedImage];
......@@ -77,7 +76,7 @@
[_selectedImageView setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
[self.contentView addSubview:_selectedImageView];
_disclosureIndicatorImageView = [[UIImageView alloc] init];
_disclosureIndicatorImageView = [[DisclosureIndicatorView alloc] init];
_disclosureIndicatorImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_disclosureIndicatorImageView];
......@@ -127,23 +126,28 @@
}
}
- (void)setOptionValue:(BUYOptionValue *)optionValue productVariant:(BUYProductVariant*)productVariant currencyFormatter:(NSNumberFormatter*)currencyFormatter theme:(BUYTheme *)theme
-(void)tintColorDidChange
{
[super tintColorDidChange];
self.titleLabel.textColor = self.tintColor;
}
- (void)setSelectedBackgroundViewBackgroundColor:(UIColor *)selectedBackgroundViewBackgroundColor
{
self.selectedBackgroundView.backgroundColor = selectedBackgroundViewBackgroundColor;
}
- (void)setOptionValue:(BUYOptionValue *)optionValue productVariant:(BUYProductVariant*)productVariant currencyFormatter:(NSNumberFormatter*)currencyFormatter
{
self.titleLabel.textColor = theme.tintColor;
self.selectedImageView.tintColor = theme.tintColor;
self.backgroundColor = [theme backgroundColor];
self.selectedBackgroundView.backgroundColor = [theme selectedBackgroundColor];
self.disclosureIndicatorImageView.image = [BUYImageKit imageOfDisclosureIndicatorImageWithFrame:CGRectMake(0, 0, 10, 16) color:[theme disclosureIndicatorColor]];
self.titleLabel.text = optionValue.value;
if (productVariant) {
if (productVariant.available) {
self.priceLabel.text = [currencyFormatter stringFromNumber:productVariant.price];
self.priceLabel.textColor = [BUYTheme variantPriceTextColor];
self.priceLabel.textColor = [Theme variantPriceTextColor];
} else {
self.priceLabel.text = @"Sold Out";
self.priceLabel.textColor = [BUYTheme variantSoldOutTextColor];
self.priceLabel.text = NSLocalizedString(@"Sold Out", @"Sold out string displayed on option selector");
self.priceLabel.textColor = [Theme variantSoldOutTextColor];
}
[NSLayoutConstraint activateConstraints:self.priceConstraints];
[NSLayoutConstraint deactivateConstraints:self.noPriceConstraints];
......
//
// BUYVariantOptionView.h
// VariantOptionView.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -26,13 +26,11 @@
@import UIKit;
@class BUYOptionValue;
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
/**
* A view that contains a variant option name and option value for use to display the selected product variant
*/
@interface BUYVariantOptionView : UIView <BUYThemeable>
@interface VariantOptionView : UIView
/**
* Sets the text on the labels for the option value
......@@ -41,4 +39,6 @@
*/
- (void)setTextForOptionValue:(BUYOptionValue*)optionValue;
- (void)setOptionNameTextColor:(UIColor*)color UI_APPEARANCE_SELECTOR;
@end
//
// BUYVariantOptionView.m
// VariantOptionView.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,18 +24,21 @@
// THE SOFTWARE.
//
#import "BUYVariantOptionView.h"
#import "BUYOptionValue.h"
@import UIKit;
@import Buy;
#import "Theme+Additions.h"
#import "VariantOptionView.h"
#import "UIFont+BUYAdditions.h"
@interface BUYVariantOptionView ()
@interface VariantOptionView ()
@property (nonatomic, strong) UILabel *optionNameLabel;
@property (nonatomic, strong) UILabel *optionValueLabel;
@end
@implementation BUYVariantOptionView
@implementation VariantOptionView
- (instancetype)initWithFrame:(CGRect)frame
{
......@@ -47,7 +50,7 @@
_optionNameLabel = [[UILabel alloc] init];
_optionNameLabel.textColor = [UIColor colorWithWhite:0.6f alpha:1];
_optionNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_optionNameLabel setFont:[BUYTheme variantOptionNameFont]];
[_optionNameLabel setFont:[Theme variantOptionNameFont]];
[self addSubview:_optionNameLabel];
// Configure option value label
......@@ -55,7 +58,7 @@
_optionValueLabel.textColor = self.tintColor;
_optionValueLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_optionValueLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[_optionValueLabel setFont:[BUYTheme variantOptionValueFont]];
[_optionValueLabel setFont:[Theme variantOptionValueFont]];
[self addSubview:_optionValueLabel];
NSDictionary *views = NSDictionaryOfVariableBindings(_optionNameLabel, _optionValueLabel);
......@@ -82,12 +85,16 @@
self.optionValueLabel.textColor = self.tintColor;
}
- (void)setTheme:(BUYTheme *)theme
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
self.optionNameLabel.textColor = [theme variantOptionNameTextColor];
self.backgroundColor = [theme backgroundColor];
[super setBackgroundColor:backgroundColor];
self.optionNameLabel.backgroundColor = self.backgroundColor;
self.optionValueLabel.backgroundColor = self.backgroundColor;
}
- (void)setOptionNameTextColor:(UIColor*)color
{
self.optionNameLabel.textColor = color;
}
@end
//
// PresentationController.h
// VariantSelectionPresentationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -29,7 +29,7 @@
/**
* A presentation controller containing the view controllers for variant selection
*/
@interface BUYPresentationControllerForVariantSelection : UIPresentationController
@interface VariantSelectionPresentationController : UIPresentationController
/**
* Blurred effects view that surrounds the variant selection navigation controller
......
//
// BUYPresentationController.m
// VariantSelectionPresentationController.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,9 +24,9 @@
// THE SOFTWARE.
//
#import "BUYPresentationControllerForVariantSelection.h"
#import "VariantSelectionPresentationController.h"
@implementation BUYPresentationControllerForVariantSelection
@implementation VariantSelectionPresentationController
- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
{
......
//
// BUYVariantSelectionViewController.h
// VariantSelectionViewController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,13 +25,11 @@
//
@import UIKit;
@import Buy;
@class BUYProduct;
@class BUYVariantSelectionViewController;
@class BUYProductVariant;
@class BUYTheme;
@class VariantSelectionViewController;
@protocol BUYVariantSelectionDelegate <NSObject>
@protocol VariantSelectionDelegate <NSObject>
/**
* Called when a user selects the last option for a product variant
......@@ -39,7 +37,7 @@
* @param controller The displayed variant selection view controller
* @param variant The selected product variant
*/
- (void)variantSelectionController:(BUYVariantSelectionViewController *)controller didSelectVariant:(BUYProductVariant *)variant;
- (void)variantSelectionController:(VariantSelectionViewController *)controller didSelectVariant:(BUYProductVariant *)variant;
/**
* Called when a user cancels out of the flow
......@@ -47,24 +45,23 @@
* @param controller The displayed variant selection view controller
* @param optionIndex The index matching the option value when the user cancelled selection in the flow
*/
- (void)variantSelectionControllerDidCancelVariantSelection:(BUYVariantSelectionViewController *)controller atOptionIndex:(NSUInteger)optionIndex;
- (void)variantSelectionControllerDidCancelVariantSelection:(VariantSelectionViewController *)controller atOptionIndex:(NSUInteger)optionIndex;
@end
/**
* The view controller that manages the option selection view controllers
*/
@interface BUYVariantSelectionViewController : UIViewController
@interface VariantSelectionViewController : UIViewController
/**
* Initalizer that takes a product and theme
* Initalizer that takes a product
*
* @param product The product to display variant options for selection
* @param theme The current theme
*
* @return An instance of BUYVariantSelectionViewController
*/
- (instancetype)initWithProduct:(BUYProduct *)product theme:(BUYTheme*)theme;
- (instancetype)initWithProduct:(BUYProduct *)product;
/**
* The product displaying variant option for
......@@ -84,6 +81,6 @@
/**
* The delegate that informs the product view of selection or cancellation
*/
@property (nonatomic, weak) id <BUYVariantSelectionDelegate> delegate;
@property (nonatomic, weak) id <VariantSelectionDelegate> delegate;
@end
//
// BUYVariantSelectionViewController.m
// VariantSelectionViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,23 +24,16 @@
// THE SOFTWARE.
//
#import "BUYImageKit.h"
#import "BUYOptionSelectionNavigationController.h"
#import "BUYOptionSelectionViewController.h"
#import "BUYPresentationControllerForVariantSelection.h"
#import "BUYProduct.h"
#import "BUYProductVariant.h"
#import "BUYTheme.h"
#import "BUYTheme+Additions.h"
#import "BUYVariantSelectionViewController.h"
#import "BUYVariantOptionBreadCrumbsView.h"
#import "BUYOption.h"
#import "BUYOptionValue.h"
@interface BUYVariantSelectionViewController () <BUYOptionSelectionDelegate>
#import "ImageKit.h"
#import "OptionSelectionNavigationController.h"
#import "OptionSelectionViewController.h"
#import "VariantSelectionPresentationController.h"
#import "VariantSelectionViewController.h"
#import "OptionBreadCrumbsView.h"
@interface VariantSelectionViewController () <OptionSelectionDelegate>
@property (nonatomic, strong) BUYProduct *product;
@property (nonatomic, weak) BUYTheme *theme;
@property (nonatomic, strong) NSMutableDictionary *selectedOptions;
@property (nonatomic, assign) BOOL changedOptionSelection;
@property (nonatomic, strong) NSArray *filteredProductVariantsForSelectionOption;
......@@ -48,9 +41,9 @@
@end
@implementation BUYVariantSelectionViewController
@implementation VariantSelectionViewController
- (instancetype)initWithProduct:(BUYProduct *)product theme:(BUYTheme*)theme
- (instancetype)initWithProduct:(BUYProduct *)product
{
NSParameterAssert(product);
......@@ -60,7 +53,6 @@
self.product = product;
self.selectedOptions = [NSMutableDictionary new];
self.optionValueNames = [NSMutableArray new];
self.theme = theme;
}
return self;
......@@ -70,23 +62,23 @@
{
[super viewDidLoad];
BUYOptionSelectionViewController *controller = [self nextOptionSelectionController];
OptionSelectionViewController *controller = [self nextOptionSelectionController];
// Add close button
UIImage *closeButton = [[BUYImageKit imageOfVariantCloseImageWithFrame:CGRectMake(0, 0, 18, 20)] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *closeButton = [[ImageKit imageOfVariantCloseImageWithFrame:CGRectMake(0, 0, 18, 20)] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithImage:closeButton style:UIBarButtonItemStylePlain target:self action:@selector(dismissPopover)];
controller.navigationItem.leftBarButtonItem = barButtonItem;
[self.navigationController pushViewController:controller animated:NO];
BUYOptionSelectionNavigationController *navigationController = (BUYOptionSelectionNavigationController*)self.navigationController;
UIVisualEffectView *backgroundView = [(BUYPresentationControllerForVariantSelection*)navigationController.presentationController backgroundView];
OptionSelectionNavigationController *navigationController = (OptionSelectionNavigationController*)self.navigationController;
UIVisualEffectView *backgroundView = [(VariantSelectionPresentationController*)navigationController.presentationController backgroundView];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissPopover)];
[backgroundView addGestureRecognizer:tapGestureRecognizer];
}
- (void)presentNextOption
{
BUYOptionSelectionViewController *controller = [self nextOptionSelectionController];
OptionSelectionViewController *controller = [self nextOptionSelectionController];
[self.navigationController pushViewController:controller animated:YES];
}
......@@ -107,37 +99,36 @@
return [[self.selectedOptions allKeys] count] == 1;
}
- (BUYOptionSelectionViewController *)nextOptionSelectionController
- (OptionSelectionViewController *)nextOptionSelectionController
{
NSUInteger index = [[self.selectedOptions allKeys] count];
BUYOption *option = self.product.options[index];
NSArray *options = [self.product valuesForOption:option variants:self.filteredProductVariantsForSelectionOption];
BUYOptionSelectionViewController *optionController = [[BUYOptionSelectionViewController alloc] initWithOptionValues:options filteredProductVariantsForSelectionOption:self.filteredProductVariantsForSelectionOption];
optionController.theme = self.theme;
OptionSelectionViewController *optionController = [[OptionSelectionViewController alloc] initWithOptionValues:options filteredProductVariantsForSelectionOption:self.filteredProductVariantsForSelectionOption];
optionController.delegate = self;
optionController.selectedOptionValue = self.changedOptionSelection ? nil : [self.selectedProductVariant optionValueForName:option.name];
optionController.isLastOption = [self isLastOption];
optionController.currencyFormatter = self.currencyFormatter;
optionController.title = option.name;
if (index > 0) {
[[(BUYOptionSelectionNavigationController*)self.navigationController breadsCrumbsView] setSelectedBuyOptionValues:[self.optionValueNames copy]];
optionController.tableView.contentInset = optionController.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(optionController.tableView.contentInset.top + CGRectGetHeight([[(BUYOptionSelectionNavigationController*)self.navigationController breadsCrumbsView] bounds]), optionController.tableView.contentInset.left, optionController.tableView.contentInset.bottom, optionController.tableView.contentInset.right);
[[(OptionSelectionNavigationController*)self.navigationController breadsCrumbsView] setSelectedBuyOptionValues:[self.optionValueNames copy]];
optionController.tableView.contentInset = optionController.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(optionController.tableView.contentInset.top + CGRectGetHeight([[(OptionSelectionNavigationController*)self.navigationController breadsCrumbsView] bounds]), optionController.tableView.contentInset.left, optionController.tableView.contentInset.bottom, optionController.tableView.contentInset.right);
}
return optionController;
}
- (void)dismissPopover
{
[(BUYOptionSelectionNavigationController*)self.navigationController setDismissWithCancelAnimation:YES];
[(OptionSelectionNavigationController*)self.navigationController setDismissWithCancelAnimation:YES];
if ([self.delegate respondsToSelector:@selector(variantSelectionControllerDidCancelVariantSelection:atOptionIndex:)]) {
[self.delegate variantSelectionControllerDidCancelVariantSelection:self atOptionIndex:self.selectedOptions.count];
}
}
#pragma mark - BUYOptionSelectionDelegate
#pragma mark - OptionSelectionDelegate
- (void)optionSelectionController:(BUYOptionSelectionViewController *)controller didSelectOptionValue:(BUYOptionValue *)optionValue
- (void)optionSelectionController:(OptionSelectionViewController *)controller didSelectOptionValue:(BUYOptionValue *)optionValue
{
self.changedOptionSelection |= ![controller.selectedOptionValue.value isEqualToString:optionValue.value];
self.selectedOptions[optionValue.name] = optionValue;
......@@ -156,13 +147,13 @@
}
}
- (void)optionSelectionControllerDidBackOutOfChoosingOption:(BUYOptionSelectionViewController *)controller
- (void)optionSelectionControllerDidBackOutOfChoosingOption:(OptionSelectionViewController *)controller
{
BUYOption *option = [controller.optionValues firstObject];
[self.selectedOptions removeObjectForKey:option.name];
[self.optionValueNames removeLastObject];
self.filteredProductVariantsForSelectionOption = controller.filteredProductVariantsForSelectionOption;
[[(BUYOptionSelectionNavigationController*)self.navigationController breadsCrumbsView] setSelectedBuyOptionValues:[self.optionValueNames copy]];
[[(OptionSelectionNavigationController*)self.navigationController breadsCrumbsView] setSelectedBuyOptionValues:[self.optionValueNames copy]];
}
- (NSArray*)filteredProductVariantsForSelectionOption
......
//
// BUYCheckoutButton.h
// NavigationController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,18 +25,13 @@
//
@import UIKit;
#import "BUYTheme.h"
/**
* A themed UIButton that includes a UIActivityIndicator
* A custom navigation controller used in the BUYProductViewController, adding a close button and the ability to theme the navigation bar
*/
@interface BUYCheckoutButton : UIButton <BUYThemeable>
@interface NavigationController : UINavigationController
/**
* Show a UIActivityIndicator in place of text while loading
*
* @param show Show or hide the UIActivityIndicator
*/
- (void)showActivityIndicator:(BOOL)show;
@property (nonatomic) BOOL automaticallyMasksSeparator;
@end
//
// NavigationController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "NavigationController.h"
static CGFloat const kSeperatorVisibilityCurve = 0.01f;
static void *kObservationContext = &kObservationContext;
@interface NavigationController() <UINavigationBarDelegate>
@property (strong, nonatomic) UIView *separatorMask;
@property (readonly) UIScrollView *scrollView;
@end
@implementation NavigationController
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithRootViewController:rootViewController];
if (self) {
UINavigationBar *navigationBar = self.navigationBar;
self.separatorMask = [UIView new];
self.separatorMask.backgroundColor = [UIColor whiteColor];
self.separatorMask.hidden = YES;
[navigationBar addSubview:self.separatorMask];
}
return self;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGFloat height = 1.0f / [UIScreen mainScreen].scale;
UINavigationBar *navigationBar = self.navigationBar;
self.separatorMask.frame = CGRectMake(CGRectGetMinX(navigationBar.bounds), CGRectGetMaxY(navigationBar.bounds), CGRectGetWidth(navigationBar.bounds), height);
}
- (void)setAutomaticallyMasksSeparator:(BOOL)automaticallyMasksSeparator
{
self.separatorMask.hidden = !automaticallyMasksSeparator;
}
- (void)dealloc
{
[self.scrollView removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentOffset))];
}
- (UIScrollView *)scrollView
{
UIView *view = self.topViewController.view;
if ([view isKindOfClass:[UIScrollView class]]) {
return (id)view;
} else {
return [view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject isKindOfClass:[UIScrollView class]];
}]].firstObject;
}
}
- (CGFloat)seperatorAlphaWithOffset:(CGFloat)offset
{
CGFloat alpha = offset + CGRectGetMaxY(self.navigationBar.frame);
alpha *= kSeperatorVisibilityCurve;
return 1.0f - alpha;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if (context == kObservationContext) {
UIScrollView *scrollView = object;
if (scrollView != self.scrollView) {
[scrollView removeObserver:self forKeyPath:keyPath];
} else {
CGFloat alpha = [self seperatorAlphaWithOffset:self.scrollView.contentOffset.y];
self.separatorMask.alpha = alpha;
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)updateObservedValues
{
if (!self.scrollView) {
return;
}
NSString *keyPath = NSStringFromSelector(@selector(contentOffset));
[self.scrollView addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:kObservationContext];
}
#pragma mark - UINavigationBarDelegate
- (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item
{
[self updateObservedValues];
}
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item
{
[self updateObservedValues];
}
@end
//
// BUYViewController.h
// PaymentViewController.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -26,69 +26,69 @@
@import UIKit;
@import PassKit;
#import "BUYClient.h"
#import "BUYCart.h"
#import "BUYCheckout.h"
@import Buy;
@class BUYViewController;
@class BUYCheckout;
@class BUYPaymentController;
@class PaymentViewController;
@protocol BUYViewControllerDelegate <NSObject>
@protocol PaymentViewControllerDelegate <NSObject>
@optional
// Look into having this protocol inherit from a generic one
/**
* This is called if there is an error in creating the BUYCheckout. These problems include not being connected to the Internet,
* or if there is a validation error in the checkout.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param error An NSError describing the failure
*/
- (void)controller:(BUYViewController *)controller failedToCreateCheckout:(NSError *)error;
- (void)controller:(PaymentViewController *)controller failedToCreateCheckout:(NSError *)error;
/**
* This failure occurs when either the application is not properly configured to handle Apple Pay,
* or if the user does not have any credit cards configured in PassBook or cannot add any credit cards.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
*/
- (void)controllerFailedToStartApplePayProcess:(BUYViewController *)controller;
- (void)controllerFailedToStartApplePayProcess:(PaymentViewController *)controller;
/**
* This failure occurs whenever an update to BUYCheckout fails (shipping address, billing address, etc.)
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
* @param error An NSError describing the failure
*/
- (void)controller:(BUYViewController *)controller failedToUpdateCheckout:(BUYCheckout *)checkout withError:(NSError *)error;
- (void)controller:(PaymentViewController *)controller failedToUpdateCheckout:(BUYCheckout *)checkout withError:(NSError *)error;
/**
* This failure occurs when shipping rates cannot be retrieved.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
* @param error An NSError describing the failure
*/
- (void)controller:(BUYViewController *)controller failedToGetShippingRates:(BUYCheckout *)checkout withError:(NSError *)error;
- (void)controller:(PaymentViewController *)controller failedToGetShippingRates:(BUYCheckout *)checkout withError:(NSError *)error;
/**
* This failure occurs whenever completing a checkout fails.
* This can occur if there is missing payment information or if the shop is improperly configured.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
* @param error An NSError describing the failure
*/
- (void)controller:(BUYViewController *)controller failedToCompleteCheckout:(BUYCheckout *)checkout withError:(NSError *)error;
- (void)controller:(PaymentViewController *)controller failedToCompleteCheckout:(BUYCheckout *)checkout withError:(NSError *)error;
/**
* This is called whenever the checkout fully completes, success or failure.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
* @param status Checkout status BUYStatus
*/
- (void)controller:(BUYViewController *)controller didCompleteCheckout:(BUYCheckout *)checkout status:(BUYStatus)status;
- (void)controller:(PaymentViewController *)controller didCompleteCheckout:(BUYCheckout *)checkout status:(BUYStatus)status;
/**
* This is called when the Apple Pay Authorization View Controller has been dismissed.
......@@ -98,25 +98,25 @@
* Note: If the PKPaymentAuthorizationStatus is not PKPaymentAuthorizationStatusSuccess we will expire the checkout by
* calling `expireCheckout:completion:` to release the hold on the product inventory.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
*/
- (void)controller:(BUYViewController *)controller didDismissApplePayControllerWithStatus:(PKPaymentAuthorizationStatus)status forCheckout:(BUYCheckout *)checkout;
- (void)controller:(PaymentViewController *)controller didDismissApplePayControllerWithStatus:(PKPaymentAuthorizationStatus)status forCheckout:(BUYCheckout *)checkout;
/**
* This is called when the SFSafariViewController has been dismissed before checkout completion.
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
* @param checkout The BUYCheckout
*/
- (void)controller:(BUYViewController *)controller didDismissWebCheckout:(BUYCheckout *)checkout;
- (void)controller:(PaymentViewController *)controller didDismissWebCheckout:(BUYCheckout *)checkout;
/**
* The view controller has been dismissed
*
* @param controller The BUYViewController
* @param controller The PaymentViewController
*/
- (void)didDismissViewController:(BUYViewController *)controller;
- (void)didDismissViewController:(PaymentViewController *)controller;
@optional
......@@ -125,26 +125,26 @@
*
* @param viewController the view controller
*/
- (void)controllerWillCheckoutViaWeb:(BUYViewController *)viewController;
- (void)controllerWillCheckoutViaWeb:(PaymentViewController *)viewController;
/**
* Called when the user chooses to checkout via Apple Pay
*
* @param viewController the view controller
*/
- (void)controllerWillCheckoutViaApplePay:(BUYViewController *)viewController;
- (void)controllerWillCheckoutViaApplePay:(PaymentViewController *)viewController;
@end
/**
* This base class guides you through the entire Apple Pay process.
*/
@interface BUYViewController : UIViewController <PKPaymentAuthorizationViewControllerDelegate>
@interface PaymentViewController : UIViewController <BUYPaymentProviderDelegate>
/**
* Register yourself as a BUYViewControllerDelegate to handle all errors, and status changes.
* Register yourself as a PaymentViewControllerDelegate to handle all errors, and status changes.
*/
@property (nonatomic, weak) id <BUYViewControllerDelegate> delegate;
@property (nonatomic, weak) id <PaymentViewControllerDelegate> delegate;
/**
* Set the BUYClient using the provided initializer method `initWithClient:` or
......@@ -203,14 +203,15 @@
/**
* The current checkout object
*/
@property (nonatomic, strong, readonly) BUYCheckout *checkout;
@property (nonatomic, strong) BUYCheckout *checkout;
/**
* Loads the shop details
*
* @param block callback block called on completion
*/
- (void)loadShopWithCallback:(void (^)(BOOL, NSError *))block;
- (void)loadShopWithCallback:(void (^)(BOOL, NSError *))block NS_DEPRECATED_IOS(8_0, 9_0);
#pragma mark - Apple Pay Overrides
......@@ -235,11 +236,11 @@
- (instancetype)init NS_UNAVAILABLE;
/**
* Creates a BUYViewController using your
* Creates a PaymentViewController using your
*
* @param client A BUYClient configured to your shop
*
* @return A BUYViewController
* @return A PaymentViewController
*/
- (instancetype)initWithClient:(BUYClient *)client;
......@@ -285,4 +286,6 @@
*/
+ (void)completeCheckoutFromLaunchURL:(NSURL *)url;
@property (nonatomic, strong) BUYPaymentController *paymentController;
@end
//
// PaymentViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import AddressBook;
@import UIKit;
@import Buy;
#import "PaymentViewController.h"
@implementation PaymentViewController
@synthesize client = _client;
- (instancetype)initWithClient:(BUYClient *)client
{
self = [super init];
if (self) {
self.client = client;
}
return self;
}
- (BUYClient*)client
{
if (_client == nil) {
NSLog(@"`BUYClient` has not been initialized. Please initialize PaymentViewController with `initWithClient:` or set a `BUYClient` after Storyboard initialization");
}
return _client;
}
- (void)loadShopWithCallback:(void (^)(BOOL, NSError *))block
{
// Deprecated
}
- (BOOL)canShowApplePaySetup
{
return self.applePayPaymentProvider.canShowApplePaySetup;
}
- (BOOL)isApplePayAvailable
{
return self.applePayPaymentProvider.available;
}
- (BOOL)shouldShowApplePayButton {
return self.applePayPaymentProvider.available || [self canShowApplePaySetup];
}
- (BOOL)shouldShowApplePaySetup
{
return self.applePayPaymentProvider.available == NO && [self canShowApplePaySetup];
}
#pragma mark - Payment
- (void)startApplePayCheckout:(BUYCheckout *)checkout
{
[self.paymentController startCheckout:checkout withProviderType:BUYApplePayPaymentProviderId];
}
- (void)startWebCheckout:(BUYCheckout *)checkout
{
[self.paymentController startCheckout:checkout withProviderType:BUYWebPaymentProviderId];
}
- (BUYPaymentController *)paymentController
{
if (_paymentController == nil) {
_paymentController = [[BUYPaymentController alloc] init];
BUYWebCheckoutPaymentProvider *webPaymentProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client];
webPaymentProvider.delegate = self;
[_paymentController addPaymentProvider:webPaymentProvider];
if (self.merchantId.length) {
BUYApplePayPaymentProvider *applePayPaymentProvider = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:self.merchantId];
applePayPaymentProvider.delegate = self;
[_paymentController addPaymentProvider:applePayPaymentProvider];
}
}
return _paymentController;
}
- (BUYWebCheckoutPaymentProvider *)webPaymentProvider
{
return (BUYWebCheckoutPaymentProvider*)[self.paymentController providerForType:BUYWebPaymentProviderId];
}
- (BUYApplePayPaymentProvider *)applePayPaymentProvider
{
return (BUYApplePayPaymentProvider*)[self.paymentController providerForType:BUYApplePayPaymentProviderId];
}
#pragma mark - Creating a Checkout using a Cart Token
- (void)startCheckoutWithCartToken:(NSString *)token
{
[self.client createCheckoutWithCartToken:token completion:^(BUYCheckout *checkout, NSError *error) {
[self handleCheckoutCompletion:checkout error:error];
}];
}
- (void)handleCheckoutCompletion:(BUYCheckout *)checkout error:(NSError *)error
{
if (checkout && error == nil) {
self.checkout = checkout;
[self.applePayPaymentProvider startCheckout:checkout];
}
else {
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
}
- (void)checkoutCompleted:(BUYCheckout *)checkout status:(BUYStatus)status
{
if ([self.delegate respondsToSelector:@selector(controller:didCompleteCheckout:status:)]) {
[self.delegate controller:self didCompleteCheckout:checkout status:status];
}
}
#pragma mark - Payment delegate methods
+ (void)completeCheckoutFromLaunchURL:(NSURL *)url
{
[[NSNotificationCenter defaultCenter] postNotificationName:BUYSafariCallbackURLNotification object:nil userInfo:@{BUYURLKey: url}];
}
- (void)paymentProviderWillStartCheckout:(id<BUYPaymentProvider>)provider
{
if ([self.delegate respondsToSelector:@selector(controllerWillCheckoutViaWeb:)]) {
[self.delegate controllerWillCheckoutViaWeb:self];
}
}
- (void)paymentProviderDidDismissCheckout:(id<BUYPaymentProvider>)provider
{
if ([self.delegate respondsToSelector:@selector(controller:didDismissWebCheckout:)]) {
[self.delegate controller:self didDismissWebCheckout:self.checkout];
}
}
- (void)paymentProvider:(id<BUYPaymentProvider>)provider didFailCheckoutWithError:(NSError *)error
{
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
- (void)paymentProvider:(id<BUYPaymentProvider>)provider didCompleteCheckout:(BUYCheckout *)checkout withStatus:(BUYStatus)status
{
if ([self.delegate respondsToSelector:@selector(controller:didCompleteCheckout:status:)]) {
[self.delegate controller:self didCompleteCheckout:checkout status:status];
}
}
- (void)paymentProvider:(id<BUYPaymentProvider>)provider wantsControllerPresented:(UIViewController *)controller
{
[self presentViewController:controller animated:YES completion:nil];
}
- (void)paymentProviderWantsControllerDismissed:(id<BUYPaymentProvider>)provider
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(PKPaymentRequest *)paymentRequest
{
return nil;
}
@end
......@@ -27,10 +27,6 @@
@import UIKit;
@import Buy;
#warning - Enter your merchant ID
// Adding a merchant ID will show Apple Pay in the BUYProductViewController (on supported devices)
#define MERCHANT_ID @""
@interface ProductListViewController : UITableViewController
- (instancetype)initWithClient:(BUYClient *)client collection:(BUYCollection*)collection;
......
......@@ -25,11 +25,19 @@
//
#import "ProductListViewController.h"
#import "ProductViewController.h"
#import "Theme.h"
#import "ShippingRatesTableViewController.h"
#import "ProductViewControllerToggleTableViewCell.h"
#import "ProductViewControllerThemeStyleTableViewCell.h"
#import "ProductViewControllerThemeTintColorTableViewCell.h"
#import <Buy/Buy.h>
//#warning - Enter your merchant ID
// Adding a merchant ID will show Apple Pay in the BUYProductViewController (on supported devices)
#define MERCHANT_ID @""
@interface ProductListViewController () <UIViewControllerPreviewingDelegate>
@property (nonatomic, strong) BUYClient *client;
......@@ -39,7 +47,7 @@
@property (nonatomic, strong) NSURLSessionDataTask *checkoutCreationTask;
@property (nonatomic, assign) BOOL demoProductViewController;
@property (nonatomic, assign) BUYThemeStyle themeStyle;
@property (nonatomic, assign) ThemeStyle themeStyle;
@property (nonatomic, strong) NSArray *themeTintColors;
@property (nonatomic, assign) NSInteger themeTintColorSelectedIndex;
@property (nonatomic, assign) BOOL showsProductImageBackground;
......@@ -275,7 +283,7 @@
[self.checkoutCreationTask cancel];
}
BUYCart *cart = [[BUYCart alloc] init];
BUYCart *cart = [self.client.modelManager insertCartWithJSONDictionary:nil];
[cart addVariant:product.variants.firstObject];
BUYCheckout *checkout = [[BUYCheckout alloc] initWithCart:cart];
......@@ -304,7 +312,7 @@
- (void)demoProductViewControllerWithProduct:(BUYProduct*)product
{
BUYProductViewController *productViewController = [self productViewController];
ProductViewController *productViewController = [self productViewController];
[productViewController loadWithProduct:product completion:^(BOOL success, NSError *error) {
if (error == nil) {
if (self.presentViewController) {
......@@ -316,13 +324,13 @@
}];
}
-(BUYProductViewController*)productViewController
-(ProductViewController*)productViewController
{
BUYTheme *theme = [BUYTheme new];
Theme *theme = [Theme new];
theme.style = self.themeStyle;
theme.tintColor = self.themeTintColors[self.themeTintColorSelectedIndex];
theme.showsProductImageBackground = self.showsProductImageBackground;
BUYProductViewController *productViewController = [[BUYProductViewController alloc] initWithClient:self.client theme:theme];
ProductViewController *productViewController = [[ProductViewController alloc] initWithClient:self.client theme:theme];
productViewController.merchantId = MERCHANT_ID;
return productViewController;
}
......@@ -362,7 +370,7 @@
- (BUYAddress *)address
{
BUYAddress *address = [[BUYAddress alloc] init];
BUYAddress *address = [self.client.modelManager insertAddressWithJSONDictionary:nil];
address.address1 = @"150 Elgin Street";
address.address2 = @"8th Floor";
address.city = @"Ottawa";
......@@ -387,7 +395,7 @@
}
BUYProduct *product = self.products[indexPath.row];
BUYProductViewController *productViewController = [self productViewController];
ProductViewController *productViewController = [self productViewController];
[productViewController loadWithProduct:product completion:NULL];
previewingContext.sourceRect = cell.frame;
......
//
// BUYStoreViewController.h
// UIColor+BUYAdditions.h
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -25,60 +25,35 @@
//
@import UIKit;
#import "BUYViewController.h"
#import "BUYError.h"
typedef NS_ENUM(NSUInteger, BUYCheckoutType){
BUYCheckoutTypeNormal,
BUYCheckoutTypeApplePay,
BUYCheckoutTypeCancel
};
#define BUY_RGB(r, g, b) BUY_RGBA(r, g, b, 1)
#define BUY_RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
typedef void (^BUYCheckoutTypeBlock)(BUYCheckoutType type);
@class BUYStoreViewController;
/**
* The BUYStoreViewControllerDelegate protocol implements methods related to the checkout process
*/
@protocol BUYStoreViewControllerDelegate <BUYViewControllerDelegate>
@interface UIColor (BUYAdditions)
/**
* Tells the delegate that the user has proceeded to checkout. Use this opportunity to present an interface to a
* user to choose between checking out with Apple Pay or standard webcheckout.
* Note: Before presenting an option for Apple Pay, check if the device is setup to do so by calling `[PKPaymentAuthorizationViewController canMakePayments]`
* Check if the color is light (brightness of colors combined less than .5)
* Supports RGB and grey space colors
*
* @param controller The controller with an embedded WKWebView displaying the Shopify store
* @param completionHandler (^BUYCheckoutTypeBlock)(BUYCheckoutType type);
* @return Returns true if the color is light
*/
- (void)controller:(BUYStoreViewController *)controller shouldProceedWithCheckoutType:(BUYCheckoutTypeBlock)completionHandler;
@end
- (BOOL)isLightColor;
/**
* This controller shows you how to build a controller that embeds a WKWebView (iOS 8+) with your store in it.
* This means that you can show off your store and its sleek responsive design without having to build a full native app to showcase it.
*/
@interface BUYStoreViewController : BUYViewController
/**
* Creates a view controller with an embedded webview to show the shops storefront
* Creates a UIColor from a hex value
*
* @param client The client configured to your shop
* @param url The address where the shop can be viewed
* @param hex the hex value to convert to a UIColor
*
* @return the BUYStoreViewController instance
*/
- (instancetype)initWithClient:(BUYClient *)client url:(NSURL *)url;
/**
* Jumps back to the shops home page
* @return A UIColor object
*/
- (void)reloadHomePage;
+ (UIColor*)colorWithHex:(NSInteger)hex;
+ (UIColor*)colorWithHexString:(NSString *)hexString;
/**
* The BUYStoreViewControllerDelegate
* Creates a string representing the hex value for the color
*
* @return String representing the hex value
*/
@property (nonatomic, weak) id <BUYStoreViewControllerDelegate> delegate;
- (NSString *)hexString;
@end
//
// UIColor+BUYAdditions.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "UIColor+BUYAdditions.h"
@implementation UIColor (BUYAdditions)
-(BOOL)isLightColor
{
CGFloat colorBrightness = 0;
CGColorSpaceRef colorSpace = CGColorGetColorSpace(self.CGColor);
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
if (colorSpaceModel == kCGColorSpaceModelRGB) {
const CGFloat *componentColors = CGColorGetComponents(self.CGColor);
colorBrightness = ((componentColors[0] * 299) + (componentColors[1] * 587) + (componentColors[2] * 114)) / 1000;
} else {
[self getWhite:&colorBrightness alpha:0];
}
return (colorBrightness >= .5f);
}
+ (UIColor*)colorWithHex:(NSInteger)hex
{
return [UIColor colorWithRed:(((hex & 0xFF0000) >> 16)) / 255.0f
green:(((hex & 0x00FF00) >> 8)) / 255.0f
blue:(((hex & 0x0000FF) >> 0)) / 255.0f
alpha:1.0];
}
+ (UIColor*)colorWithHexString:(NSString *)hexString
{
if ([hexString length] == 0) {
return nil;
}
NSScanner *scanner = [NSScanner scannerWithString:hexString];
unsigned hex;
[scanner scanHexInt:&hex];
return [UIColor colorWithHex:hex];
}
- (NSString *)hexString
{
CGFloat r;
CGFloat g;
CGFloat b;
[self getRed:&r green:&g blue:&b alpha:nil];
return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
lround(r * 255),
lround(g * 255),
lround(b * 255)];
}
@end
//
// BUYFont.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
@interface UIFont (BUYAdditions)
/**
* Class method to allow system fonts to have increased point sizes from the OS default.
*
* @param style The text style for the font.
* @param size A positive value to increase the default font's point size by.
*
* @return A system font with an optionally increased point size.
*/
+ (UIFont *)preferredFontForTextStyle:(NSString *)style increasedPointSize:(CGFloat)size;
@end
//
// BUYFontAdditionsTests.m
// BUYFont.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -24,27 +24,14 @@
// THE SOFTWARE.
//
#import <XCTest/XCTest.h>
#import "UIFont+BUYAdditions.h"
@interface BUYFontAdditionsTests : XCTestCase
@implementation UIFont (BUYAdditions)
@end
@implementation BUYFontAdditionsTests
- (void)testIncreasedFontSize
+ (UIFont *)preferredFontForTextStyle:(NSString *)style increasedPointSize:(CGFloat)size
{
static CGFloat const increase = 2.0;
UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
CGFloat newSize = font.pointSize + increase;
NSMutableDictionary *attributes = [font.fontDescriptor.fontAttributes mutableCopy];
attributes[UIFontDescriptorSizeAttribute] = @(newSize);
UIFont *expected = [UIFont fontWithDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:attributes] size:newSize];
UIFont *actual = [UIFont preferredFontForTextStyle:UIFontTextStyleBody increasedPointSize:increase];
XCTAssertEqualObjects(actual, expected);
UIFontDescriptor *descriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:style];
return [UIFont fontWithDescriptor:descriptor size:descriptor.pointSize + size];
}
@end
//
// UIImage+BUYAdditions.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface UIImage (BUYAdditions)
+ (UIImage *)templateButtonBackgroundImage;
+ (UIImage *)templateImageWithFill:(UIColor *)fill stroke:(UIColor *)stroke edgeInsets:(UIEdgeInsets)edgeInsets;
@end
//
// UIImage+Additions.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "UIImage+BUYAdditions.h"
static const CGFloat kDefaultCornerRadius = 4.0f;
static const CGFloat kDefaultStrokWidth = 1.0f;
@implementation UIImage (BUYAdditions)
+ (UIImage *)templateButtonBackgroundImage
{
UIImage *image = [UIImage templateImageWithFill:[UIColor blackColor] stroke:nil];
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
return image;
}
+ (UIImage *)templateImageWithFill:(UIEdgeInsets)edgeInsets
{
UIImage *image = [UIImage templateImageWithFill:[UIColor blackColor] stroke:nil edgeInsets:edgeInsets];
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
return image;
}
+ (UIImage *)templateImageWithFill:(UIColor *)fill stroke:(UIColor *)stroke
{
CGFloat defaultInsetAmount = kDefaultCornerRadius + 1.0f;
return [UIImage templateImageWithFill:fill stroke:stroke edgeInsets:UIEdgeInsetsMake(defaultInsetAmount, defaultInsetAmount, defaultInsetAmount, defaultInsetAmount)];
}
+ (UIImage *)templateImageWithFill:(UIColor *)fill stroke:(UIColor *)stroke edgeInsets:(UIEdgeInsets)edgeInsets
{
CGFloat defaultStrokeWidth = kDefaultStrokWidth;
return [self templateImageWithFill:fill stroke:stroke edgeInsets:edgeInsets strokeWidth:defaultStrokeWidth];
}
+ (UIImage *)templateImageWithFill:(UIColor *)fill stroke:(UIColor *)stroke edgeInsets:(UIEdgeInsets)edgeInsets strokeWidth:(CGFloat)width
{
CGRect rect = CGRectMake(0.0f, 0.0f,
edgeInsets.left + edgeInsets.right,
edgeInsets.top + edgeInsets.bottom);
CGFloat strokeOffset = stroke ? kDefaultStrokWidth * 0.5f : 0.0f;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, strokeOffset, strokeOffset) cornerRadius:edgeInsets.top];
path.lineWidth = width;
CGRect contextRect = CGRectOffset(rect, kDefaultStrokWidth * 0.5f, kDefaultStrokWidth * 0.5f);
UIGraphicsBeginImageContextWithOptions(contextRect.size, NO, 0);
if (fill) {
[fill setFill];
[path fill];
}
if (stroke) {
[stroke setStroke];
[path stroke];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
image = [image resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];
return image;
}
@end
//
// BUYImageKit.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import Foundation;
@import UIKit;
/**
* Image generator for a variety of images using the BUYProductViewController.
*/
@interface BUYImageKit : NSObject
/**
* Generates a close button image for the variant selection navigation bar.
*
* @param frame The frame size of the image
*
* @return A close button image
*/
+ (UIImage*)imageOfVariantCloseImageWithFrame: (CGRect)frame;
/**
* Generates a checkmark image for use of displaying the previously selected variant
*
* @param frame The frame size of the image
*
* @return A checkmark for the previous variant selection
*/
+ (UIImage*)imageOfPreviousSelectionIndicatorImageWithFrame: (CGRect)frame;
/**
* Generates a custom disclosure indicator image
*
* @param frame The frame size of the image
* @param color The color for the disclosure indicator
*
* @return A disclusore indicator image
*/
+ (UIImage*)imageOfDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)color;
/**
* Generates a close button image for the product view's navigation bar
*
* @param frame The frame size of the image
* @param color The color for the close button image
* @param hasShadow True if the X should have a drop shadow
*
* @return A close button image
*/
+ (UIImage*)imageOfProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor*)color hasShadow:(BOOL)hasShadow;
/**
* Generates a custom back button image for the variant selection navigation bar
*
* @param frame The frame size of the image
*
* @return A custom back button image
*/
+ (UIImage*)imageOfVariantBackImageWithFrame: (CGRect)frame;
@end
//
// BUYImageKit.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYImageKit.h"
@implementation BUYImageKit
#pragma mark Drawing Methods
+ (void)drawVariantCloseImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* closeColor = [UIColor colorWithRed: 0.596f green: 0.596f blue: 0.596f alpha: 1];
//// Variant Close Icon Drawing
UIBezierPath* variantCloseIconPath = UIBezierPath.bezierPath;
[variantCloseIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93886f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.87988f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.95000f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.06114f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.23681f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath closePath];
[variantCloseIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93886f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.23681f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.13971f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.95000f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.06114f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.87988f * CGRectGetHeight(frame))];
[variantCloseIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86029f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.16669f * CGRectGetHeight(frame))];
[variantCloseIconPath closePath];
[closeColor setFill];
[variantCloseIconPath fill];
}
+ (void)drawPreviousSelectionIndicatorImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* indicatorColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
//// Previous Selection Indicator Drawing
UIBezierPath* previousSelectionIndicatorPath = UIBezierPath.bezierPath;
[previousSelectionIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.22386f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.77614f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.22386f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.22386f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.77614f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.00000f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.22386f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 1.00000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.77614f * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.77614f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 1.00000f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath closePath];
[previousSelectionIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.28003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.62929f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25074f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.48003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.18002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.55074f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.39926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76997f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40000f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76924f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.40073f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.76997f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.81997f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.35074f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74926f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.28003f * CGRectGetHeight(frame))];
[previousSelectionIndicatorPath closePath];
[indicatorColor setFill];
[previousSelectionIndicatorPath fill];
}
+ (void)drawDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)arrowColor
{
//// Disclosure Indicator Drawing
UIBezierPath* disclosureIndicatorPath = UIBezierPath.bezierPath;
[disclosureIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06878f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93995f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.49908f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.58746f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11004f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15717f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06878f * CGRectGetHeight(frame))];
[disclosureIndicatorPath closePath];
[disclosureIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.41253f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.93995f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50092f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.25149f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.93121f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11004f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84282f * CGRectGetHeight(frame))];
[disclosureIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79854f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.41253f * CGRectGetHeight(frame))];
[disclosureIndicatorPath closePath];
[arrowColor setFill];
[disclosureIndicatorPath fill];
}
+ (void)drawProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor *)closeColor2 hasShadow:(BOOL)hasShadow
{
//// General Declarations
CGContextRef context = UIGraphicsGetCurrentContext();
//// Color Declarations
UIColor* closeShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
//// Shadow Declarations
NSShadow* closeDropShadow = [[NSShadow alloc] init];
[closeDropShadow setShadowColor: [closeShadowColor colorWithAlphaComponent: 0.15f]];
[closeDropShadow setShadowOffset: CGSizeMake(0.1f, 1.1f)];
[closeDropShadow setShadowBlurRadius: 2];
//// Close Icon Drawing
UIBezierPath* closeIconPath = UIBezierPath.bezierPath;
[closeIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.85907f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84024f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.90452f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.05002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15976f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath closePath];
[closeIconPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.85907f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.15976f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.11431f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.90452f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.05002f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.84024f * CGRectGetHeight(frame))];
[closeIconPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79479f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.09548f * CGRectGetHeight(frame))];
[closeIconPath closePath];
CGContextSaveGState(context);
if (hasShadow) {
CGContextSetShadowWithColor(context, closeDropShadow.shadowOffset, closeDropShadow.shadowBlurRadius, [closeDropShadow.shadowColor CGColor]);
}
[closeColor2 setFill];
[closeIconPath fill];
CGContextRestoreGState(context);
}
+ (void)drawVariantBackImageWithFrame: (CGRect)frame
{
//// Color Declarations
UIColor* indicatorColor3 = [UIColor colorWithRed: 0.596f green: 0.596f blue: 0.596f alpha: 1];
//// Variant Back Indicator Drawing
UIBezierPath* variantBackIndicatorPath = UIBezierPath.bezierPath;
[variantBackIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.42225f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86663f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.86029f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.93886f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.09171f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.50082f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.42225f * CGRectGetHeight(frame))];
[variantBackIndicatorPath closePath];
[variantBackIndicatorPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06114f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.86663f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.13971f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20956f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.57775f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.09171f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.49918f * CGRectGetHeight(frame))];
[variantBackIndicatorPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.74878f * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.06114f * CGRectGetHeight(frame))];
[variantBackIndicatorPath closePath];
[indicatorColor3 setFill];
[variantBackIndicatorPath fill];
}
#pragma mark Generated Images
+ (UIImage*)imageOfVariantCloseImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[BUYImageKit drawVariantCloseImageWithFrame: frame];
UIImage* imageOfVariantCloseImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfVariantCloseImage;
}
+ (UIImage*)imageOfPreviousSelectionIndicatorImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[BUYImageKit drawPreviousSelectionIndicatorImageWithFrame: frame];
UIImage* imageOfPreviousSelectionIndicatorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfPreviousSelectionIndicatorImage;
}
+ (UIImage*)imageOfDisclosureIndicatorImageWithFrame: (CGRect)frame color:(UIColor*)color;
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[BUYImageKit drawDisclosureIndicatorImageWithFrame: frame color:color];
UIImage* imageOfDisclosureIndicatorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfDisclosureIndicatorImage;
}
+ (UIImage*)imageOfProductViewCloseImageWithFrame: (CGRect)frame color:(UIColor*)color hasShadow:(BOOL)hasShadow;
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[BUYImageKit drawProductViewCloseImageWithFrame: frame color:color hasShadow:hasShadow];
UIImage* imageOfProductViewCloseImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfProductViewCloseImage;
}
+ (UIImage*)imageOfVariantBackImageWithFrame: (CGRect)frame
{
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0.0f);
[BUYImageKit drawVariantBackImageWithFrame: frame];
UIImage* imageOfVariantBackImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOfVariantBackImage;
}
@end
//
// BUYFont.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
@interface UIFont (BUYAdditions)
/**
* Class method to allow system fonts to have increased point sizes from the OS default.
*
* @param style The text style for the font.
* @param size A positive value to increase the default font's point size by.
*
* @return A system font with an optionally increased point size.
*/
+ (UIFont *)preferredFontForTextStyle:(NSString *)style increasedPointSize:(CGFloat)size;
@end
//
// BUYFont.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "UIFont+BUYAdditions.h"
@implementation UIFont (BUYAdditions)
+ (UIFont *)preferredFontForTextStyle:(NSString *)style increasedPointSize:(CGFloat)size
{
UIFontDescriptor *descriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:style];
return [UIFont fontWithDescriptor:descriptor size:descriptor.pointSize + size];
}
@end
......@@ -80,7 +80,6 @@
849110351CCE70CE00E53B93 /* BUYDictionaryAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849110341CCE70CE00E53B93 /* BUYDictionaryAdditionsTests.m */; };
8491103A1CCE718100E53B93 /* BUYExceptionAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849110391CCE718100E53B93 /* BUYExceptionAdditionsTests.m */; };
8491103C1CCE731900E53B93 /* BUYURLAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8491103B1CCE731900E53B93 /* BUYURLAdditionsTests.m */; };
8491103E1CCE988600E53B93 /* BUYFontAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8491103D1CCE988600E53B93 /* BUYFontAdditionsTests.m */; };
849110441CCE9F3F00E53B93 /* BUYTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849110431CCE9F3F00E53B93 /* BUYTransformerTests.m */; };
8491104A1CCEA85C00E53B93 /* BUYObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849110461CCEA85C00E53B93 /* BUYObserverTests.m */; };
84980F291CB75AC200CFAB58 /* BUYObjectProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 84980F281CB75AC200CFAB58 /* BUYObjectProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
......@@ -268,118 +267,52 @@
84DD12D01CC6401400A2442D /* BUYCustomer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D915731CC0416800D334FB /* BUYCustomer.m */; };
9003969B1B601DF400226B73 /* BUYCartLineItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396991B601DF400226B73 /* BUYCartLineItem.h */; settings = {ATTRIBUTES = (Public, ); }; };
9003969C1B601DF400226B73 /* BUYCartLineItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 9003969A1B601DF400226B73 /* BUYCartLineItem.m */; };
900396AC1B627CB900226B73 /* BUYProductView.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396AA1B627CB900226B73 /* BUYProductView.h */; };
900396AD1B627CB900226B73 /* BUYProductView.m in Sources */ = {isa = PBXBuildFile; fileRef = 900396AB1B627CB900226B73 /* BUYProductView.m */; };
900396B01B67BD0A00226B73 /* BUYCheckoutButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396AE1B67BD0A00226B73 /* BUYCheckoutButton.h */; };
900396B11B67BD0A00226B73 /* BUYCheckoutButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 900396AF1B67BD0A00226B73 /* BUYCheckoutButton.m */; };
900E7C841B5DA553006F3C81 /* BUYImageKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 900E7C811B5DA32F006F3C81 /* BUYImageKit.h */; };
900E7C851B5DA559006F3C81 /* BUYImageKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 900E7C821B5DA32F006F3C81 /* BUYImageKit.m */; };
901930E31BC5B9BC00D1134E /* BUYApplePayHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */; };
901930E41BC5B9BC00D1134E /* BUYOptionSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9496AF1B4D96D800B38949 /* BUYOptionSelectionViewController.m */; };
901930E51BC5B9BC00D1134E /* BUYVariantOptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CA21B4D771400E35E45 /* BUYVariantOptionView.m */; };
901930E61BC5B9BC00D1134E /* BUYPresentationControllerForVariantSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB74A201B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m */; };
901930E81BC5B9BC00D1134E /* BUYImageLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A7A1A700B0A0087DB2C /* BUYImageLink.m */; };
901930E91BC5B9BC00D1134E /* BUYProductVariant.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A821A700B0A0087DB2C /* BUYProductVariant.m */; };
901930EA1BC5B9BC00D1134E /* BUYProductViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 905ECCC11B4C39710094F336 /* BUYProductViewController.m */; };
901930EC1BC5B9BC00D1134E /* BUYError.m in Sources */ = {isa = PBXBuildFile; fileRef = BE47340E1B66C4EF00AA721A /* BUYError.m */; };
901930ED1BC5B9BC00D1134E /* BUYProductViewHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C861B4C6F7000E35E45 /* BUYProductViewHeader.m */; };
901930EE1BC5B9BC00D1134E /* BUYNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CC21B4F1ED700E35E45 /* BUYNavigationController.m */; };
901930EF1BC5B9BC00D1134E /* BUYVariantSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9496B11B4D96D800B38949 /* BUYVariantSelectionViewController.m */; };
901930F21BC5B9BC00D1134E /* BUYOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E83BC31B9F550E00C95A1B /* BUYOrder.m */; };
901930F41BC5B9BC00D1134E /* BUYProductViewHeaderBackgroundImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90FC31A71B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.m */; };
901930F51BC5B9BC00D1134E /* BUYProductViewHeaderOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 907874981B7276BA0023775B /* BUYProductViewHeaderOverlay.m */; };
901930F61BC5B9BC00D1134E /* BUYProductVariantCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C9A1B4D76D900E35E45 /* BUYProductVariantCell.m */; };
901930F71BC5B9BC00D1134E /* BUYTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CB71B4F0DD500E35E45 /* BUYTheme.m */; };
901930F91BC5B9BC00D1134E /* BUYProductViewErrorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 903BCC7B1B7D1C2D00C21FEB /* BUYProductViewErrorView.m */; };
901930FA1BC5B9BC00D1134E /* BUYLineItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F7FDA16D19C939FF00AF4E93 /* BUYLineItem.m */; };
901930FB1BC5B9BC00D1134E /* BUYCheckoutButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 900396AF1B67BD0A00226B73 /* BUYCheckoutButton.m */; };
901930FC1BC5B9BC00D1134E /* BUYCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 9089CC5D1BB48D06009726D6 /* BUYCollection.m */; };
901930FD1BC5B9BC00D1134E /* BUYTaxLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AFAA5D1B011EA600F21C23 /* BUYTaxLine.m */; };
901930FF1BC5B9BC00D1134E /* BUYVariantOptionBreadCrumbsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90DE926F1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m */; };
901931011BC5B9BC00D1134E /* BUYTheme+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 906EAE421B836DE000976165 /* BUYTheme+Additions.m */; };
901931021BC5B9BC00D1134E /* BUYStoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1C4DF41AE98FBB00E21624 /* BUYStoreViewController.m */; };
901931031BC5B9BC00D1134E /* BUYOptionValue.m in Sources */ = {isa = PBXBuildFile; fileRef = BEEA83E61B0B76C7000C6483 /* BUYOptionValue.m */; };
901931041BC5B9BC00D1134E /* BUYApplePayAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CE40E1A8BF1D90055BEB8 /* BUYApplePayAdditions.m */; };
901931051BC5B9BC00D1134E /* BUYOptionSelectionNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB74A261B554BFB0005A300 /* BUYOptionSelectionNavigationController.m */; };
901931061BC5B9BC00D1134E /* BUYDiscount.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AFAA691B0139DE00F21C23 /* BUYDiscount.m */; };
901931081BC5B9BC00D1134E /* BUYRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A741A700AC80087DB2C /* BUYRuntime.m */; };
901931091BC5B9BC00D1134E /* BUYCart.m in Sources */ = {isa = PBXBuildFile; fileRef = F773744819C77A210039681C /* BUYCart.m */; };
9019310A1BC5B9BC00D1134E /* BUYPaymentButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 905AA9701B3B32A500CAE037 /* BUYPaymentButton.m */; };
9019310C1BC5B9BC00D1134E /* BUYGiftCard.m in Sources */ = {isa = PBXBuildFile; fileRef = 42488B331AB8761A005F21A9 /* BUYGiftCard.m */; };
9019310D1BC5B9BC00D1134E /* BUYOptionValueCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BE10079A1B6165EC0031CEE7 /* BUYOptionValueCell.m */; };
9019310E1BC5B9BC00D1134E /* BUYProduct.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A7D1A700B0A0087DB2C /* BUYProduct.m */; };
9019310F1BC5B9BC00D1134E /* BUYImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CAF1B4EC9FE00E35E45 /* BUYImageView.m */; };
901931101BC5B9BC00D1134E /* BUYProductHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C981B4D76D900E35E45 /* BUYProductHeaderCell.m */; };
901931111BC5B9BC00D1134E /* BUYCartLineItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 9003969A1B601DF400226B73 /* BUYCartLineItem.m */; };
901931121BC5B9BC00D1134E /* BUYMaskedCreditCard.m in Sources */ = {isa = PBXBuildFile; fileRef = BE5DC3621B71022D00B2BC1E /* BUYMaskedCreditCard.m */; };
901931131BC5B9BC00D1134E /* BUYCheckout.m in Sources */ = {isa = PBXBuildFile; fileRef = F773749519C77C260039681C /* BUYCheckout.m */; };
901931141BC5B9BC00D1134E /* BUYProductViewFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C7A1B4C589A00E35E45 /* BUYProductViewFooter.m */; };
901931151BC5B9BC00D1134E /* BUYPresentationControllerWithNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CBE1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.m */; };
901931161BC5B9BC00D1134E /* BUYShippingRate.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AFAA651B01398A00F21C23 /* BUYShippingRate.m */; };
901931181BC5B9BC00D1134E /* BUYGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CB31B4EE5E700E35E45 /* BUYGradientView.m */; };
901931191BC5B9BC00D1134E /* BUYViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1C4DF61AE98FBB00E21624 /* BUYViewController.m */; };
9019311A1BC5B9BC00D1134E /* BUYImageKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 900E7C821B5DA32F006F3C81 /* BUYImageKit.m */; };
9019311C1BC5B9BC00D1134E /* BUYOption.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A801A700B0A0087DB2C /* BUYOption.m */; };
9019311D1BC5B9BC00D1134E /* BUYClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F7FDA17119C93F6F00AF4E93 /* BUYClient.m */; };
9019311E1BC5B9BC00D1134E /* UIFont+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */; };
9019311F1BC5B9BC00D1134E /* BUYProductView.m in Sources */ = {isa = PBXBuildFile; fileRef = 900396AB1B627CB900226B73 /* BUYProductView.m */; };
901931201BC5B9BC00D1134E /* BUYCreditCard.m in Sources */ = {isa = PBXBuildFile; fileRef = F77374AB19C796BD0039681C /* BUYCreditCard.m */; };
901931211BC5B9BC00D1134E /* BUYProductImageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 904606AE1B6BC8D700754173 /* BUYProductImageCollectionViewCell.m */; };
901931221BC5B9BC00D1134E /* BUYShop.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A841A700B0A0087DB2C /* BUYShop.m */; };
901931231BC5B9BC00D1134E /* BUYObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A941A7010B20087DB2C /* BUYObject.m */; };
901931241BC5B9BC00D1134E /* BUYProductDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C961B4D76D900E35E45 /* BUYProductDescriptionCell.m */; };
901931281BC5B9BC00D1134E /* BUYApplePayHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = BE33B4ED1B15FF4D0067982B /* BUYApplePayHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931291BC5B9BC00D1134E /* BUYStoreViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1C4DF31AE98FBB00E21624 /* BUYStoreViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019312A1BC5B9BC00D1134E /* BUYCreditCard.h in Headers */ = {isa = PBXBuildFile; fileRef = F77374AA19C796BD0039681C /* BUYCreditCard.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019312B1BC5B9BC00D1134E /* BUYOption.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A7F1A700B0A0087DB2C /* BUYOption.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019312C1BC5B9BC00D1134E /* BUYProductVariantCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C991B4D76D900E35E45 /* BUYProductVariantCell.h */; };
9019312D1BC5B9BC00D1134E /* BUYTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CB61B4F0DD500E35E45 /* BUYTheme.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019312E1BC5B9BC00D1134E /* BUYProductDescriptionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C951B4D76D900E35E45 /* BUYProductDescriptionCell.h */; };
9019312F1BC5B9BC00D1134E /* BUYLineItem.h in Headers */ = {isa = PBXBuildFile; fileRef = F7FDA16C19C939FF00AF4E93 /* BUYLineItem.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931311BC5B9BC00D1134E /* BUYProductViewHeaderOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 907874971B7276BA0023775B /* BUYProductViewHeaderOverlay.h */; };
901931341BC5B9BC00D1134E /* BUYViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1C4DF51AE98FBB00E21624 /* BUYViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931351BC5B9BC00D1134E /* BUYDiscount.h in Headers */ = {isa = PBXBuildFile; fileRef = 90AFAA681B0139DE00F21C23 /* BUYDiscount.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931361BC5B9BC00D1134E /* BUYProductView.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396AA1B627CB900226B73 /* BUYProductView.h */; };
901931371BC5B9BC00D1134E /* BUYTaxLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 90AFAA5C1B011EA600F21C23 /* BUYTaxLine.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931381BC5B9BC00D1134E /* BUYVariantSelectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE9496B01B4D96D800B38949 /* BUYVariantSelectionViewController.h */; };
901931391BC5B9BC00D1134E /* BUYOptionValueCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */; };
9019313A1BC5B9BC00D1134E /* BUYImageLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A791A700B0A0087DB2C /* BUYImageLink.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019313B1BC5B9BC00D1134E /* BUYOptionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BEEA83E51B0B76C7000C6483 /* BUYOptionValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019313C1BC5B9BC00D1134E /* BUYShop.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A831A700B0A0087DB2C /* BUYShop.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019313D1BC5B9BC00D1134E /* BUYShippingRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 90AFAA641B01398A00F21C23 /* BUYShippingRate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019313E1BC5B9BC00D1134E /* BUYApplePayAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = F70CE40D1A8BF1D90055BEB8 /* BUYApplePayAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931401BC5B9BC00D1134E /* BUYTheme+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 906EAE411B836DE000976165 /* BUYTheme+Additions.h */; };
901931411BC5B9BC00D1134E /* BUYVariantOptionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CA11B4D771400E35E45 /* BUYVariantOptionView.h */; };
901931421BC5B9BC00D1134E /* BUYMaskedCreditCard.h in Headers */ = {isa = PBXBuildFile; fileRef = BE5DC3611B71022D00B2BC1E /* BUYMaskedCreditCard.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931431BC5B9BC00D1134E /* BUYProductViewHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C851B4C6F7000E35E45 /* BUYProductViewHeader.h */; };
901931441BC5B9BC00D1134E /* BUYProductViewHeaderBackgroundImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90FC31A61B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.h */; };
901931451BC5B9BC00D1134E /* UIFont+BUYAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */; };
901931461BC5B9BC00D1134E /* BUYCheckoutButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396AE1B67BD0A00226B73 /* BUYCheckoutButton.h */; };
901931471BC5B9BC00D1134E /* BUYPaymentButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 905AA96F1B3B32A500CAE037 /* BUYPaymentButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931481BC5B9BC00D1134E /* BUYImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CAE1B4EC9FE00E35E45 /* BUYImageView.h */; };
901931491BC5B9BC00D1134E /* BUYGiftCard.h in Headers */ = {isa = PBXBuildFile; fileRef = 42488B321AB8761A005F21A9 /* BUYGiftCard.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019314B1BC5B9BC00D1134E /* BUYNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CC11B4F1ED700E35E45 /* BUYNavigationController.h */; };
9019314D1BC5B9BC00D1134E /* BUYVariantOptionBreadCrumbsView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90DE926E1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h */; };
9019314E1BC5B9BC00D1134E /* BUYProductViewFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C791B4C589A00E35E45 /* BUYProductViewFooter.h */; };
9019314F1BC5B9BC00D1134E /* BUYOptionSelectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE9496AE1B4D96D800B38949 /* BUYOptionSelectionViewController.h */; };
901931501BC5B9BC00D1134E /* BUYOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 90E83BC21B9F550E00C95A1B /* BUYOrder.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931531BC5B9BC00D1134E /* BUYOptionSelectionNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A251B554BFB0005A300 /* BUYOptionSelectionNavigationController.h */; };
901931541BC5B9BC00D1134E /* BUYPresentationControllerWithNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CBD1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.h */; };
901931551BC5B9BC00D1134E /* BUYPresentationControllerForVariantSelection.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A1F1B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h */; };
901931571BC5B9BC00D1134E /* BUYObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A931A7010B20087DB2C /* BUYObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931581BC5B9BC00D1134E /* BUYRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A731A700AC80087DB2C /* BUYRuntime.h */; };
901931591BC5B9BC00D1134E /* BUYCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A8E1B55A3D00005A300 /* BUYCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019315A1BC5B9BC00D1134E /* BUYProductImageCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 904606AD1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h */; };
9019315B1BC5B9BC00D1134E /* BUYImageKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 900E7C811B5DA32F006F3C81 /* BUYImageKit.h */; };
9019315E1BC5B9BC00D1134E /* BUYError.h in Headers */ = {isa = PBXBuildFile; fileRef = BE47340D1B66C4EF00AA721A /* BUYError.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019315F1BC5B9BC00D1134E /* BUYProductHeaderCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C971B4D76D900E35E45 /* BUYProductHeaderCell.h */; };
901931601BC5B9BC00D1134E /* BUYProductViewErrorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 903BCC7A1B7D1C2D00C21FEB /* BUYProductViewErrorView.h */; };
901931611BC5B9BC00D1134E /* BUYClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F7FDA17019C93F6F00AF4E93 /* BUYClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931631BC5B9BC00D1134E /* BUYGradientView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CB21B4EE5E700E35E45 /* BUYGradientView.h */; };
901931641BC5B9BC00D1134E /* BUYCartLineItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 900396991B601DF400226B73 /* BUYCartLineItem.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931661BC5B9BC00D1134E /* BUYCheckout.h in Headers */ = {isa = PBXBuildFile; fileRef = F773749419C77C260039681C /* BUYCheckout.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931671BC5B9BC00D1134E /* BUYCart.h in Headers */ = {isa = PBXBuildFile; fileRef = F773744719C77A210039681C /* BUYCart.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931681BC5B9BC00D1134E /* BUYProductViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 905ECCC01B4C39710094F336 /* BUYProductViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
901931691BC5B9BC00D1134E /* BUYProduct.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A7C1A700B0A0087DB2C /* BUYProduct.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019316A1BC5B9BC00D1134E /* BUYSerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = F76CFF1E19CB7C500079C703 /* BUYSerializable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9019316B1BC5B9BC00D1134E /* BUYProductVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF52A811A700B0A0087DB2C /* BUYProductVariant.h */; settings = {ATTRIBUTES = (Public, ); }; };
......@@ -387,27 +320,15 @@
9032F2DB1BE9457A00BB9EEF /* BUYCheckoutAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 9032F2D81BE9457A00BB9EEF /* BUYCheckoutAttribute.h */; settings = {ATTRIBUTES = (Public, ); }; };
9032F2DC1BE9457A00BB9EEF /* BUYCheckoutAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 9032F2D91BE9457A00BB9EEF /* BUYCheckoutAttribute.m */; };
9032F2DD1BE9457A00BB9EEF /* BUYCheckoutAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 9032F2D91BE9457A00BB9EEF /* BUYCheckoutAttribute.m */; };
903BCC7C1B7D1C2D00C21FEB /* BUYProductViewErrorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 903BCC7A1B7D1C2D00C21FEB /* BUYProductViewErrorView.h */; };
903BCC7D1B7D1C2D00C21FEB /* BUYProductViewErrorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 903BCC7B1B7D1C2D00C21FEB /* BUYProductViewErrorView.m */; };
904606AF1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 904606AD1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h */; };
904606B01B6BC8D700754173 /* BUYProductImageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 904606AE1B6BC8D700754173 /* BUYProductImageCollectionViewCell.m */; };
906CF1AD1B8B5F7D001F7D5B /* BUYNSPersonNameComponents.m in Sources */ = {isa = PBXBuildFile; fileRef = 906CF1AC1B8B5F7D001F7D5B /* BUYNSPersonNameComponents.m */; };
906CF1B11B8B66AE001F7D5B /* BUYCNPostalAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 906CF1B01B8B66AE001F7D5B /* BUYCNPostalAddress.m */; };
906EAE431B836DE000976165 /* BUYTheme+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 906EAE411B836DE000976165 /* BUYTheme+Additions.h */; };
906EAE441B836DE000976165 /* BUYTheme+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 906EAE421B836DE000976165 /* BUYTheme+Additions.m */; };
907874991B7276BA0023775B /* BUYProductViewHeaderOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 907874971B7276BA0023775B /* BUYProductViewHeaderOverlay.h */; };
9078749A1B7276BA0023775B /* BUYProductViewHeaderOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 907874981B7276BA0023775B /* BUYProductViewHeaderOverlay.m */; };
9089CC5E1BB48D06009726D6 /* BUYCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = 9089CC5D1BB48D06009726D6 /* BUYCollection.m */; };
909944491B71B76800C40A33 /* UIFont+BUYAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */; };
9099444A1B71B76800C40A33 /* UIFont+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */; };
90BBCD731B87B6BA00FCCE51 /* BUYPKContact.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BBCD701B87B6AB00FCCE51 /* BUYPKContact.m */; };
90C27AAF1BB2E8F3008AF7A4 /* libOHHTTPStubs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE98DB501BB1ED5500C29564 /* libOHHTTPStubs.a */; };
90C856B51BD6B0F300936926 /* Buy.h in Headers */ = {isa = PBXBuildFile; fileRef = 90DA8DF11BC6A82D0027BCB7 /* Buy.h */; settings = {ATTRIBUTES = (Public, ); }; };
90C856B61BD6B0F400936926 /* Buy.h in Headers */ = {isa = PBXBuildFile; fileRef = 90DA8DF11BC6A82D0027BCB7 /* Buy.h */; settings = {ATTRIBUTES = (Public, ); }; };
90DAEC361BC6E511007555A5 /* Buy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE9A64281B503C2F0033E558 /* Buy.framework */; };
90DAEC381BC6E736007555A5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 901931761BC5BC9100D1134E /* libc++.tbd */; };
90DE92701B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90DE926E1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h */; };
90DE92711B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90DE926F1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m */; };
90E83BC41B9F550E00C95A1B /* BUYOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 90E83BC21B9F550E00C95A1B /* BUYOrder.h */; settings = {ATTRIBUTES = (Public, ); }; };
90E83BC51B9F550E00C95A1B /* BUYOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E83BC31B9F550E00C95A1B /* BUYOrder.m */; };
90F593041B0D5F4C0026B382 /* BUYIntegrationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 90F592F81B0D5F4C0026B382 /* BUYIntegrationTest.m */; };
......@@ -436,8 +357,6 @@
9A47CF221CE5112A00A6D5BA /* BUYAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A47CF211CE5112A00A6D5BA /* BUYAssert.h */; };
9A47CF231CE5112A00A6D5BA /* BUYAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A47CF211CE5112A00A6D5BA /* BUYAssert.h */; };
9A6B03791CDA5D4F0054C26E /* BUYAccountCredentialsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A6B03781CDA5D4F0054C26E /* BUYAccountCredentialsTests.m */; };
BE10079B1B6165EC0031CEE7 /* BUYOptionValueCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */; };
BE10079C1B6165EC0031CEE7 /* BUYOptionValueCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BE10079A1B6165EC0031CEE7 /* BUYOptionValueCell.m */; };
BE47340F1B66C4EF00AA721A /* BUYError.h in Headers */ = {isa = PBXBuildFile; fileRef = BE47340D1B66C4EF00AA721A /* BUYError.h */; settings = {ATTRIBUTES = (Public, ); }; };
BE4734101B66C4EF00AA721A /* BUYError.m in Sources */ = {isa = PBXBuildFile; fileRef = BE47340E1B66C4EF00AA721A /* BUYError.m */; };
BE5DC3631B71022D00B2BC1E /* BUYMaskedCreditCard.h in Headers */ = {isa = PBXBuildFile; fileRef = BE5DC3611B71022D00B2BC1E /* BUYMaskedCreditCard.h */; settings = {ATTRIBUTES = (Public, ); }; };
......@@ -484,46 +403,6 @@
BE9A646F1B503D210033E558 /* BUYRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF52A741A700AC80087DB2C /* BUYRuntime.m */; };
BE9A64741B503D2E0033E558 /* BUYApplePayHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = BE33B4ED1B15FF4D0067982B /* BUYApplePayHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
BE9A64751B503D370033E558 /* BUYApplePayHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */; };
BE9A647E1B503D930033E558 /* BUYStoreViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1C4DF31AE98FBB00E21624 /* BUYStoreViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
BE9A647F1B503D960033E558 /* BUYStoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1C4DF41AE98FBB00E21624 /* BUYStoreViewController.m */; };
BE9A64801B503D990033E558 /* BUYViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE1C4DF51AE98FBB00E21624 /* BUYViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
BE9A64811B503D9E0033E558 /* BUYViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1C4DF61AE98FBB00E21624 /* BUYViewController.m */; };
BE9A64821B503DAD0033E558 /* BUYPaymentButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 905AA96F1B3B32A500CAE037 /* BUYPaymentButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
BE9A64831B503DB10033E558 /* BUYPaymentButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 905AA9701B3B32A500CAE037 /* BUYPaymentButton.m */; };
BEB74A221B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A1F1B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h */; };
BEB74A241B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB74A201B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m */; };
BEB74A281B554BFB0005A300 /* BUYOptionSelectionNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A251B554BFB0005A300 /* BUYOptionSelectionNavigationController.h */; };
BEB74A2A1B554BFB0005A300 /* BUYOptionSelectionNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB74A261B554BFB0005A300 /* BUYOptionSelectionNavigationController.m */; };
BEB74A2B1B554C150005A300 /* BUYTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CB61B4F0DD500E35E45 /* BUYTheme.h */; settings = {ATTRIBUTES = (Public, ); }; };
BEB74A2C1B554C370005A300 /* BUYTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CB71B4F0DD500E35E45 /* BUYTheme.m */; };
BEB74A2D1B554E870005A300 /* BUYProductViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 905ECCC01B4C39710094F336 /* BUYProductViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
BEB74A2E1B554E8B0005A300 /* BUYProductViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 905ECCC11B4C39710094F336 /* BUYProductViewController.m */; };
BEB74A651B5563FF0005A300 /* BUYGradientView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CB21B4EE5E700E35E45 /* BUYGradientView.h */; };
BEB74A661B5564030005A300 /* BUYGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CB31B4EE5E700E35E45 /* BUYGradientView.m */; };
BEB74A671B55640C0005A300 /* BUYNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CC11B4F1ED700E35E45 /* BUYNavigationController.h */; };
BEB74A681B55640F0005A300 /* BUYNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CC21B4F1ED700E35E45 /* BUYNavigationController.m */; };
BEB74A691B5564160005A300 /* BUYPresentationControllerWithNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CBD1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.h */; };
BEB74A6A1B5564190005A300 /* BUYPresentationControllerWithNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CBE1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.m */; };
BEB74A6B1B55641B0005A300 /* BUYProductDescriptionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C951B4D76D900E35E45 /* BUYProductDescriptionCell.h */; };
BEB74A6C1B55641D0005A300 /* BUYProductDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C961B4D76D900E35E45 /* BUYProductDescriptionCell.m */; };
BEB74A6D1B5564200005A300 /* BUYProductHeaderCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C971B4D76D900E35E45 /* BUYProductHeaderCell.h */; };
BEB74A6E1B5564230005A300 /* BUYProductHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C981B4D76D900E35E45 /* BUYProductHeaderCell.m */; };
BEB74A6F1B5564260005A300 /* BUYProductVariantCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C991B4D76D900E35E45 /* BUYProductVariantCell.h */; };
BEB74A701B5564290005A300 /* BUYProductVariantCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C9A1B4D76D900E35E45 /* BUYProductVariantCell.m */; };
BEB74A711B5564300005A300 /* BUYProductViewFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C791B4C589A00E35E45 /* BUYProductViewFooter.h */; };
BEB74A721B5564320005A300 /* BUYProductViewFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C7A1B4C589A00E35E45 /* BUYProductViewFooter.m */; };
BEB74A731B5564350005A300 /* BUYProductViewHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516C851B4C6F7000E35E45 /* BUYProductViewHeader.h */; };
BEB74A741B5564380005A300 /* BUYProductViewHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516C861B4C6F7000E35E45 /* BUYProductViewHeader.m */; };
BEB74A751B55643B0005A300 /* BUYProductViewHeaderBackgroundImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90FC31A61B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.h */; };
BEB74A761B55643E0005A300 /* BUYProductViewHeaderBackgroundImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90FC31A71B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.m */; };
BEB74A771B55646D0005A300 /* BUYImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CAE1B4EC9FE00E35E45 /* BUYImageView.h */; };
BEB74A781B55646F0005A300 /* BUYImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CAF1B4EC9FE00E35E45 /* BUYImageView.m */; };
BEB74A791B5564790005A300 /* BUYOptionSelectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE9496AE1B4D96D800B38949 /* BUYOptionSelectionViewController.h */; };
BEB74A7A1B55647C0005A300 /* BUYOptionSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9496AF1B4D96D800B38949 /* BUYOptionSelectionViewController.m */; };
BEB74A7B1B5564810005A300 /* BUYVariantOptionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 90516CA11B4D771400E35E45 /* BUYVariantOptionView.h */; };
BEB74A7C1B5564840005A300 /* BUYVariantOptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CA21B4D771400E35E45 /* BUYVariantOptionView.m */; };
BEB74A7D1B5564870005A300 /* BUYVariantSelectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BE9496B01B4D96D800B38949 /* BUYVariantSelectionViewController.h */; };
BEB74A7E1B5564890005A300 /* BUYVariantSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9496B11B4D96D800B38949 /* BUYVariantSelectionViewController.m */; };
BEB74A901B55A3D00005A300 /* BUYCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB74A8E1B55A3D00005A300 /* BUYCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
BEB9AE781BA8627B00575F8A /* test_shop_data.json in Resources */ = {isa = PBXBuildFile; fileRef = BEB9AE721BA73E6C00575F8A /* test_shop_data.json */; };
BEB9AE7D1BA885E300575F8A /* BUYClientTestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB9AE7C1BA8685600575F8A /* BUYClientTestBase.m */; };
......@@ -592,7 +471,6 @@
849110341CCE70CE00E53B93 /* BUYDictionaryAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYDictionaryAdditionsTests.m; sourceTree = "<group>"; };
849110391CCE718100E53B93 /* BUYExceptionAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYExceptionAdditionsTests.m; sourceTree = "<group>"; };
8491103B1CCE731900E53B93 /* BUYURLAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYURLAdditionsTests.m; sourceTree = "<group>"; };
8491103D1CCE988600E53B93 /* BUYFontAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYFontAdditionsTests.m; sourceTree = "<group>"; };
849110431CCE9F3F00E53B93 /* BUYTransformerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYTransformerTests.m; sourceTree = "<group>"; };
849110461CCEA85C00E53B93 /* BUYObserverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYObserverTests.m; sourceTree = "<group>"; };
84980F281CB75AC200CFAB58 /* BUYObjectProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYObjectProtocol.h; sourceTree = "<group>"; };
......@@ -695,58 +573,16 @@
84D915B51CC0417700D334FB /* _BUYTaxLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _BUYTaxLine.m; sourceTree = "<group>"; };
900396991B601DF400226B73 /* BUYCartLineItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYCartLineItem.h; sourceTree = "<group>"; };
9003969A1B601DF400226B73 /* BUYCartLineItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYCartLineItem.m; sourceTree = "<group>"; };
900396AA1B627CB900226B73 /* BUYProductView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductView.h; path = "Product View/BUYProductView.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
900396AB1B627CB900226B73 /* BUYProductView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductView.m; path = "Product View/BUYProductView.m"; sourceTree = "<group>"; };
900396AE1B67BD0A00226B73 /* BUYCheckoutButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYCheckoutButton.h; path = "Product View/BUYCheckoutButton.h"; sourceTree = "<group>"; };
900396AF1B67BD0A00226B73 /* BUYCheckoutButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYCheckoutButton.m; path = "Product View/BUYCheckoutButton.m"; sourceTree = "<group>"; };
900E7C811B5DA32F006F3C81 /* BUYImageKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYImageKit.h; sourceTree = "<group>"; };
900E7C821B5DA32F006F3C81 /* BUYImageKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYImageKit.m; sourceTree = "<group>"; };
901931701BC5B9BC00D1134E /* Buy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Buy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
901931761BC5BC9100D1134E /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
9032F2D81BE9457A00BB9EEF /* BUYCheckoutAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYCheckoutAttribute.h; sourceTree = "<group>"; };
9032F2D91BE9457A00BB9EEF /* BUYCheckoutAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYCheckoutAttribute.m; sourceTree = "<group>"; };
903BCC7A1B7D1C2D00C21FEB /* BUYProductViewErrorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewErrorView.h; path = "Product View/BUYProductViewErrorView.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
903BCC7B1B7D1C2D00C21FEB /* BUYProductViewErrorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewErrorView.m; path = "Product View/BUYProductViewErrorView.m"; sourceTree = "<group>"; };
904606AD1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductImageCollectionViewCell.h; path = "Product View/BUYProductImageCollectionViewCell.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
904606AE1B6BC8D700754173 /* BUYProductImageCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductImageCollectionViewCell.m; path = "Product View/BUYProductImageCollectionViewCell.m"; sourceTree = "<group>"; };
904FB6001AE03D4500EA1758 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = "Mobile Buy SDK/Info.plist"; sourceTree = "<group>"; };
90516C791B4C589A00E35E45 /* BUYProductViewFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewFooter.h; path = "Product View/BUYProductViewFooter.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90516C7A1B4C589A00E35E45 /* BUYProductViewFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewFooter.m; path = "Product View/BUYProductViewFooter.m"; sourceTree = "<group>"; };
90516C851B4C6F7000E35E45 /* BUYProductViewHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewHeader.h; path = "Product View/BUYProductViewHeader.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90516C861B4C6F7000E35E45 /* BUYProductViewHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewHeader.m; path = "Product View/BUYProductViewHeader.m"; sourceTree = "<group>"; };
90516C951B4D76D900E35E45 /* BUYProductDescriptionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYProductDescriptionCell.h; path = "Product View/BUYProductDescriptionCell.h"; sourceTree = "<group>"; };
90516C961B4D76D900E35E45 /* BUYProductDescriptionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductDescriptionCell.m; path = "Product View/BUYProductDescriptionCell.m"; sourceTree = "<group>"; };
90516C971B4D76D900E35E45 /* BUYProductHeaderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductHeaderCell.h; path = "Product View/BUYProductHeaderCell.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90516C981B4D76D900E35E45 /* BUYProductHeaderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductHeaderCell.m; path = "Product View/BUYProductHeaderCell.m"; sourceTree = "<group>"; };
90516C991B4D76D900E35E45 /* BUYProductVariantCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYProductVariantCell.h; path = "Product View/BUYProductVariantCell.h"; sourceTree = "<group>"; };
90516C9A1B4D76D900E35E45 /* BUYProductVariantCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductVariantCell.m; path = "Product View/BUYProductVariantCell.m"; sourceTree = "<group>"; };
90516CA11B4D771400E35E45 /* BUYVariantOptionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYVariantOptionView.h; sourceTree = "<group>"; };
90516CA21B4D771400E35E45 /* BUYVariantOptionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYVariantOptionView.m; sourceTree = "<group>"; };
90516CAE1B4EC9FE00E35E45 /* BUYImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYImageView.h; path = "Product View/BUYImageView.h"; sourceTree = "<group>"; };
90516CAF1B4EC9FE00E35E45 /* BUYImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYImageView.m; path = "Product View/BUYImageView.m"; sourceTree = "<group>"; };
90516CB21B4EE5E700E35E45 /* BUYGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYGradientView.h; path = "Product View/BUYGradientView.h"; sourceTree = "<group>"; };
90516CB31B4EE5E700E35E45 /* BUYGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYGradientView.m; path = "Product View/BUYGradientView.m"; sourceTree = "<group>"; };
90516CB61B4F0DD500E35E45 /* BUYTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYTheme.h; path = "Product View/BUYTheme.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90516CB71B4F0DD500E35E45 /* BUYTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYTheme.m; path = "Product View/BUYTheme.m"; sourceTree = "<group>"; };
90516CBD1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYPresentationControllerWithNavigationController.h; path = "Product View/BUYPresentationControllerWithNavigationController.h"; sourceTree = "<group>"; };
90516CBE1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYPresentationControllerWithNavigationController.m; path = "Product View/BUYPresentationControllerWithNavigationController.m"; sourceTree = "<group>"; };
90516CC11B4F1ED700E35E45 /* BUYNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYNavigationController.h; path = "Product View/BUYNavigationController.h"; sourceTree = "<group>"; };
90516CC21B4F1ED700E35E45 /* BUYNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYNavigationController.m; path = "Product View/BUYNavigationController.m"; sourceTree = "<group>"; };
905AA96F1B3B32A500CAE037 /* BUYPaymentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYPaymentButton.h; path = BUYPaymentButton/BUYPaymentButton.h; sourceTree = "<group>"; };
905AA9701B3B32A500CAE037 /* BUYPaymentButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYPaymentButton.m; path = BUYPaymentButton/BUYPaymentButton.m; sourceTree = "<group>"; };
905ECCC01B4C39710094F336 /* BUYProductViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewController.h; path = "Product View/BUYProductViewController.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
905ECCC11B4C39710094F336 /* BUYProductViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewController.m; path = "Product View/BUYProductViewController.m"; sourceTree = "<group>"; };
906CF1AB1B8B5F7D001F7D5B /* BUYNSPersonNameComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYNSPersonNameComponents.h; sourceTree = "<group>"; };
906CF1AC1B8B5F7D001F7D5B /* BUYNSPersonNameComponents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYNSPersonNameComponents.m; sourceTree = "<group>"; };
906CF1AF1B8B66AE001F7D5B /* BUYCNPostalAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYCNPostalAddress.h; sourceTree = "<group>"; };
906CF1B01B8B66AE001F7D5B /* BUYCNPostalAddress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYCNPostalAddress.m; sourceTree = "<group>"; };
906EAE411B836DE000976165 /* BUYTheme+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "BUYTheme+Additions.h"; path = "Utils/BUYTheme+Additions.h"; sourceTree = "<group>"; };
906EAE421B836DE000976165 /* BUYTheme+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "BUYTheme+Additions.m"; path = "Utils/BUYTheme+Additions.m"; sourceTree = "<group>"; };
907874971B7276BA0023775B /* BUYProductViewHeaderOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYProductViewHeaderOverlay.h; path = "Product View/BUYProductViewHeaderOverlay.h"; sourceTree = "<group>"; };
907874981B7276BA0023775B /* BUYProductViewHeaderOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewHeaderOverlay.m; path = "Product View/BUYProductViewHeaderOverlay.m"; sourceTree = "<group>"; };
9089CC5D1BB48D06009726D6 /* BUYCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYCollection.m; sourceTree = "<group>"; };
909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+BUYAdditions.h"; sourceTree = "<group>"; };
909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+BUYAdditions.m"; sourceTree = "<group>"; };
90AFAA5C1B011EA600F21C23 /* BUYTaxLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYTaxLine.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90AFAA5D1B011EA600F21C23 /* BUYTaxLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = BUYTaxLine.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
90AFAA641B01398A00F21C23 /* BUYShippingRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYShippingRate.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
......@@ -761,8 +597,6 @@
90C856B71BD6B19D00936926 /* Buy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Buy.h; path = "Mobile Buy SDK/Static Framework/Buy.h"; sourceTree = "<group>"; };
90C856B81BD6B19D00936926 /* Buy.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = Buy.modulemap; path = "Mobile Buy SDK/Static Framework/Buy.modulemap"; sourceTree = "<group>"; };
90DA8DF11BC6A82D0027BCB7 /* Buy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Buy.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90DE926E1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYVariantOptionBreadCrumbsView.h; sourceTree = "<group>"; };
90DE926F1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYVariantOptionBreadCrumbsView.m; sourceTree = "<group>"; };
90E80E461AFBBB68003A9909 /* AppledocSettings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppledocSettings.plist; path = docs/AppledocSettings.plist; sourceTree = "<group>"; };
90E83BC21B9F550E00C95A1B /* BUYOrder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYOrder.h; sourceTree = "<group>"; };
90E83BC31B9F550E00C95A1B /* BUYOrder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYOrder.m; sourceTree = "<group>"; };
......@@ -777,8 +611,6 @@
90F592FE1B0D5F4C0026B382 /* BUYLineItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYLineItemTest.m; sourceTree = "<group>"; };
90F592FF1B0D5F4C0026B382 /* BUYObjectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYObjectTests.m; sourceTree = "<group>"; };
90F593001B0D5F4C0026B382 /* BUYTestConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYTestConstants.h; sourceTree = "<group>"; };
90FC31A61B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewHeaderBackgroundImageView.h; path = "Product View/BUYProductViewHeaderBackgroundImageView.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
90FC31A71B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYProductViewHeaderBackgroundImageView.m; path = "Product View/BUYProductViewHeaderBackgroundImageView.m"; sourceTree = "<group>"; };
9A102D1A1CDD1F960026CC43 /* BUYErrorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYErrorTests.m; sourceTree = "<group>"; };
9A102D1D1CDD25980026CC43 /* BUYOptionValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYOptionValueTests.m; sourceTree = "<group>"; };
9A47CEF81CE39EC200A6D5BA /* BUYPaymentToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BUYPaymentToken.h; sourceTree = "<group>"; };
......@@ -792,12 +624,6 @@
9A47CF1F1CE50EBB00A6D5BA /* BUYApplePayTestToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYApplePayTestToken.m; sourceTree = "<group>"; };
9A47CF211CE5112A00A6D5BA /* BUYAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYAssert.h; path = ../Additions/BUYAssert.h; sourceTree = "<group>"; };
9A6B03781CDA5D4F0054C26E /* BUYAccountCredentialsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYAccountCredentialsTests.m; sourceTree = "<group>"; };
BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYOptionValueCell.h; sourceTree = "<group>"; };
BE10079A1B6165EC0031CEE7 /* BUYOptionValueCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYOptionValueCell.m; sourceTree = "<group>"; };
BE1C4DF31AE98FBB00E21624 /* BUYStoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYStoreViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
BE1C4DF41AE98FBB00E21624 /* BUYStoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = BUYStoreViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
BE1C4DF51AE98FBB00E21624 /* BUYViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
BE1C4DF61AE98FBB00E21624 /* BUYViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = BUYViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
BE33B4ED1B15FF4D0067982B /* BUYApplePayHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYApplePayHelpers.h; sourceTree = "<group>"; };
BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYApplePayHelpers.m; sourceTree = "<group>"; };
BE47340D1B66C4EF00AA721A /* BUYError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYError.h; sourceTree = "<group>"; };
......@@ -807,19 +633,11 @@
BE6C07031BB1DE1D00BD9F7B /* OHHTTPStubs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OHHTTPStubs.framework; path = "Mobile Buy SDK Tests/OHHTTPStubs.framework"; sourceTree = "<group>"; };
BE6C07051BB1E46900BD9F7B /* mocked_responses.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = mocked_responses.json; sourceTree = "<group>"; };
BE9496681B45CCF400B38949 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; };
BE9496AE1B4D96D800B38949 /* BUYOptionSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYOptionSelectionViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
BE9496AF1B4D96D800B38949 /* BUYOptionSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYOptionSelectionViewController.m; sourceTree = "<group>"; };
BE9496B01B4D96D800B38949 /* BUYVariantSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BUYVariantSelectionViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
BE9496B11B4D96D800B38949 /* BUYVariantSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYVariantSelectionViewController.m; sourceTree = "<group>"; };
BE98DB4E1BB1ED3E00C29564 /* OHHTTPStubs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = OHHTTPStubs; path = "Mobile Buy SDK Tests/OHHTTPStubs"; sourceTree = "<group>"; };
BE98DB501BB1ED5500C29564 /* libOHHTTPStubs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libOHHTTPStubs.a; path = "Mobile Buy SDK Tests/OHHTTPStubs/libOHHTTPStubs.a"; sourceTree = "<group>"; };
BE98DB5A1BB1F4D000C29564 /* OHHTTPStubsResponse+Helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OHHTTPStubsResponse+Helpers.h"; sourceTree = "<group>"; };
BE98DB5B1BB1F4D000C29564 /* OHHTTPStubsResponse+Helpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OHHTTPStubsResponse+Helpers.m"; sourceTree = "<group>"; };
BE9A64281B503C2F0033E558 /* Buy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Buy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BEB74A1F1B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYPresentationControllerForVariantSelection.h; path = "Mobile Buy SDK/Product View/Variant Selection/BUYPresentationControllerForVariantSelection.h"; sourceTree = SOURCE_ROOT; };
BEB74A201B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYPresentationControllerForVariantSelection.m; path = "Mobile Buy SDK/Product View/Variant Selection/BUYPresentationControllerForVariantSelection.m"; sourceTree = SOURCE_ROOT; };
BEB74A251B554BFB0005A300 /* BUYOptionSelectionNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BUYOptionSelectionNavigationController.h; path = "Mobile Buy SDK/Product View/Variant Selection/BUYOptionSelectionNavigationController.h"; sourceTree = SOURCE_ROOT; };
BEB74A261B554BFB0005A300 /* BUYOptionSelectionNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BUYOptionSelectionNavigationController.m; path = "Mobile Buy SDK/Product View/Variant Selection/BUYOptionSelectionNavigationController.m"; sourceTree = SOURCE_ROOT; };
BEB74A8E1B55A3D00005A300 /* BUYCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYCollection.h; sourceTree = "<group>"; };
BEB9AE721BA73E6C00575F8A /* test_shop_data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = test_shop_data.json; sourceTree = "<group>"; };
BEB9AE7A1BA866D000575F8A /* BUYClientTestBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYClientTestBase.h; sourceTree = "<group>"; };
......@@ -1099,7 +917,6 @@
8498DCC21CDD208200BD12A8 /* BUYCustomerTests.m */,
849110341CCE70CE00E53B93 /* BUYDictionaryAdditionsTests.m */,
849110391CCE718100E53B93 /* BUYExceptionAdditionsTests.m */,
8491103D1CCE988600E53B93 /* BUYFontAdditionsTests.m */,
90F592F81B0D5F4C0026B382 /* BUYIntegrationTest.m */,
90F592FE1B0D5F4C0026B382 /* BUYLineItemTest.m */,
8498DCC31CDD208200BD12A8 /* BUYModelManagerTests.m */,
......@@ -1134,68 +951,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
90FC31AA1B50576400AFAB51 /* Variant Selection */ = {
isa = PBXGroup;
children = (
BEB74A251B554BFB0005A300 /* BUYOptionSelectionNavigationController.h */,
BEB74A261B554BFB0005A300 /* BUYOptionSelectionNavigationController.m */,
BE9496AE1B4D96D800B38949 /* BUYOptionSelectionViewController.h */,
BE9496AF1B4D96D800B38949 /* BUYOptionSelectionViewController.m */,
BEB74A1F1B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h */,
BEB74A201B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m */,
90DE926E1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h */,
90DE926F1B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m */,
90516CA11B4D771400E35E45 /* BUYVariantOptionView.h */,
90516CA21B4D771400E35E45 /* BUYVariantOptionView.m */,
BE9496B01B4D96D800B38949 /* BUYVariantSelectionViewController.h */,
BE9496B11B4D96D800B38949 /* BUYVariantSelectionViewController.m */,
BE1007981B6165CD0031CEE7 /* Cells */,
);
name = "Variant Selection";
path = "Product View/Variant Selection";
sourceTree = "<group>";
};
90FC31AB1B50589800AFAB51 /* Product View */ = {
isa = PBXGroup;
children = (
900396AE1B67BD0A00226B73 /* BUYCheckoutButton.h */,
900396AF1B67BD0A00226B73 /* BUYCheckoutButton.m */,
90516CB21B4EE5E700E35E45 /* BUYGradientView.h */,
90516CB31B4EE5E700E35E45 /* BUYGradientView.m */,
90516CAE1B4EC9FE00E35E45 /* BUYImageView.h */,
90516CAF1B4EC9FE00E35E45 /* BUYImageView.m */,
90516CC11B4F1ED700E35E45 /* BUYNavigationController.h */,
90516CC21B4F1ED700E35E45 /* BUYNavigationController.m */,
905AA96F1B3B32A500CAE037 /* BUYPaymentButton.h */,
905AA9701B3B32A500CAE037 /* BUYPaymentButton.m */,
90516CBD1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.h */,
90516CBE1B4F110A00E35E45 /* BUYPresentationControllerWithNavigationController.m */,
904606AD1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h */,
904606AE1B6BC8D700754173 /* BUYProductImageCollectionViewCell.m */,
900396AA1B627CB900226B73 /* BUYProductView.h */,
900396AB1B627CB900226B73 /* BUYProductView.m */,
905ECCC01B4C39710094F336 /* BUYProductViewController.h */,
905ECCC11B4C39710094F336 /* BUYProductViewController.m */,
903BCC7A1B7D1C2D00C21FEB /* BUYProductViewErrorView.h */,
903BCC7B1B7D1C2D00C21FEB /* BUYProductViewErrorView.m */,
90516C791B4C589A00E35E45 /* BUYProductViewFooter.h */,
90516C7A1B4C589A00E35E45 /* BUYProductViewFooter.m */,
90516C851B4C6F7000E35E45 /* BUYProductViewHeader.h */,
90516C861B4C6F7000E35E45 /* BUYProductViewHeader.m */,
90FC31A61B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.h */,
90FC31A71B50371600AFAB51 /* BUYProductViewHeaderBackgroundImageView.m */,
907874971B7276BA0023775B /* BUYProductViewHeaderOverlay.h */,
907874981B7276BA0023775B /* BUYProductViewHeaderOverlay.m */,
90516CB61B4F0DD500E35E45 /* BUYTheme.h */,
90516CB71B4F0DD500E35E45 /* BUYTheme.m */,
906EAE411B836DE000976165 /* BUYTheme+Additions.h */,
906EAE421B836DE000976165 /* BUYTheme+Additions.m */,
BE2E1D371B599039009610DA /* Cells */,
90FC31AA1B50576400AFAB51 /* Variant Selection */,
);
name = "Product View";
sourceTree = "<group>";
};
9A102D1C1CDD257D0026CC43 /* Models Tests */ = {
isa = PBXGroup;
children = (
......@@ -1234,39 +989,6 @@
name = "Test Objects";
sourceTree = "<group>";
};
BE1007981B6165CD0031CEE7 /* Cells */ = {
isa = PBXGroup;
children = (
BE1007991B6165EC0031CEE7 /* BUYOptionValueCell.h */,
BE10079A1B6165EC0031CEE7 /* BUYOptionValueCell.m */,
);
name = Cells;
sourceTree = "<group>";
};
BE1C4DF21AE98F8E00E21624 /* View Controllers */ = {
isa = PBXGroup;
children = (
BE1C4DF31AE98FBB00E21624 /* BUYStoreViewController.h */,
BE1C4DF41AE98FBB00E21624 /* BUYStoreViewController.m */,
BE1C4DF51AE98FBB00E21624 /* BUYViewController.h */,
BE1C4DF61AE98FBB00E21624 /* BUYViewController.m */,
);
path = "View Controllers";
sourceTree = "<group>";
};
BE2E1D371B599039009610DA /* Cells */ = {
isa = PBXGroup;
children = (
90516C951B4D76D900E35E45 /* BUYProductDescriptionCell.h */,
90516C961B4D76D900E35E45 /* BUYProductDescriptionCell.m */,
90516C971B4D76D900E35E45 /* BUYProductHeaderCell.h */,
90516C981B4D76D900E35E45 /* BUYProductHeaderCell.m */,
90516C991B4D76D900E35E45 /* BUYProductVariantCell.h */,
90516C9A1B4D76D900E35E45 /* BUYProductVariantCell.m */,
);
name = Cells;
sourceTree = "<group>";
};
F773741419C770CB0039681C = {
isa = PBXGroup;
children = (
......@@ -1338,13 +1060,9 @@
BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */,
8498DCA71CDD1B1C00BD12A8 /* BUYError+BUYAdditions.h */,
8498DCA81CDD1B1C00BD12A8 /* BUYError+BUYAdditions.m */,
900E7C811B5DA32F006F3C81 /* BUYImageKit.h */,
900E7C821B5DA32F006F3C81 /* BUYImageKit.m */,
2AF52A731A700AC80087DB2C /* BUYRuntime.h */,
2AF52A741A700AC80087DB2C /* BUYRuntime.m */,
8498DCA91CDD1B1C00BD12A8 /* BUYShopifyErrorCodes.h */,
909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */,
909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */,
);
path = Utils;
sourceTree = "<group>";
......@@ -1369,11 +1087,9 @@
841ADDEA1CB6C942000004B0 /* Additions */,
F7FDA16F19C93F6100AF4E93 /* Data */,
F773744419C779C20039681C /* Models */,
90FC31AB1B50589800AFAB51 /* Product View */,
84B0A7281CE10ED900253EB0 /* Payment Providers */,
F773744519C779C20039681C /* Utils */,
84980F491CB760FA00CFAB58 /* Value Transformers */,
BE1C4DF21AE98F8E00E21624 /* View Controllers */,
);
name = Classes;
sourceTree = "<group>";
......@@ -1421,26 +1137,17 @@
84980F2A1CB75AC200CFAB58 /* BUYObjectProtocol.h in Headers */,
901931281BC5B9BC00D1134E /* BUYApplePayHelpers.h in Headers */,
9A47CF231CE5112A00A6D5BA /* BUYAssert.h in Headers */,
901931291BC5B9BC00D1134E /* BUYStoreViewController.h in Headers */,
9019312A1BC5B9BC00D1134E /* BUYCreditCard.h in Headers */,
9019312B1BC5B9BC00D1134E /* BUYOption.h in Headers */,
84980F4D1CB7613700CFAB58 /* BUYIdentityTransformer.h in Headers */,
9019312C1BC5B9BC00D1134E /* BUYProductVariantCell.h in Headers */,
9019312D1BC5B9BC00D1134E /* BUYTheme.h in Headers */,
9019312E1BC5B9BC00D1134E /* BUYProductDescriptionCell.h in Headers */,
9019312F1BC5B9BC00D1134E /* BUYLineItem.h in Headers */,
90C856B51BD6B0F300936926 /* Buy.h in Headers */,
8498DCAB1CDD1B2600BD12A8 /* BUYShopifyErrorCodes.h in Headers */,
9A47CF071CE3ACE000A6D5BA /* BUYPaymentToken.h in Headers */,
901931311BC5B9BC00D1134E /* BUYProductViewHeaderOverlay.h in Headers */,
901931341BC5B9BC00D1134E /* BUYViewController.h in Headers */,
901931351BC5B9BC00D1134E /* BUYDiscount.h in Headers */,
8498DCB71CDD1B5400BD12A8 /* BUYClient+Customers.h in Headers */,
901931361BC5B9BC00D1134E /* BUYProductView.h in Headers */,
849810931CB7E07900CFAB58 /* BUYDeliveryRangeTransformer.h in Headers */,
901931371BC5B9BC00D1134E /* BUYTaxLine.h in Headers */,
901931381BC5B9BC00D1134E /* BUYVariantSelectionViewController.h in Headers */,
901931391BC5B9BC00D1134E /* BUYOptionValueCell.h in Headers */,
84B0A7351CE10ED900253EB0 /* BUYPaymentController.h in Headers */,
9019313A1BC5B9BC00D1134E /* BUYImageLink.h in Headers */,
9019313B1BC5B9BC00D1134E /* BUYOptionValue.h in Headers */,
......@@ -1448,23 +1155,15 @@
9019313C1BC5B9BC00D1134E /* BUYShop.h in Headers */,
9019313D1BC5B9BC00D1134E /* BUYShippingRate.h in Headers */,
9019313E1BC5B9BC00D1134E /* BUYApplePayAdditions.h in Headers */,
901931401BC5B9BC00D1134E /* BUYTheme+Additions.h in Headers */,
84980F531CB7616900CFAB58 /* BUYDecimalNumberTransformer.h in Headers */,
901931411BC5B9BC00D1134E /* BUYVariantOptionView.h in Headers */,
901931421BC5B9BC00D1134E /* BUYMaskedCreditCard.h in Headers */,
901931431BC5B9BC00D1134E /* BUYProductViewHeader.h in Headers */,
901931441BC5B9BC00D1134E /* BUYProductViewHeaderBackgroundImageView.h in Headers */,
8498DCB61CDD1B5400BD12A8 /* BUYClient_Internal.h in Headers */,
901931461BC5B9BC00D1134E /* BUYCheckoutButton.h in Headers */,
901931471BC5B9BC00D1134E /* BUYPaymentButton.h in Headers */,
901931481BC5B9BC00D1134E /* BUYImageView.h in Headers */,
841ADE201CB6C942000004B0 /* NSURL+BUYAdditions.h in Headers */,
841ADE241CB6C942000004B0 /* NSURLComponents+BUYAdditions.h in Headers */,
841ADE141CB6C942000004B0 /* NSException+BUYAdditions.h in Headers */,
841ADE041CB6C942000004B0 /* NSDate+BUYAdditions.h in Headers */,
84980F2D1CB75B5E00CFAB58 /* BUYModelManagerProtocol.h in Headers */,
84D73C051CDD1945000F978A /* BUYAddress.h in Headers */,
901931451BC5B9BC00D1134E /* UIFont+BUYAdditions.h in Headers */,
84B0A73B1CE10ED900253EB0 /* BUYWebCheckoutPaymentProvider.h in Headers */,
841ADE081CB6C942000004B0 /* NSDateFormatter+BUYAdditions.h in Headers */,
841ADE001CB6C942000004B0 /* NSArray+BUYAdditions.h in Headers */,
......@@ -1475,39 +1174,26 @@
841ADE0C1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.h in Headers */,
84980F331CB75C2900CFAB58 /* NSEntityDescription+BUYAdditions.h in Headers */,
901931491BC5B9BC00D1134E /* BUYGiftCard.h in Headers */,
9019314B1BC5B9BC00D1134E /* BUYNavigationController.h in Headers */,
9019314D1BC5B9BC00D1134E /* BUYVariantOptionBreadCrumbsView.h in Headers */,
9019314E1BC5B9BC00D1134E /* BUYProductViewFooter.h in Headers */,
9019314F1BC5B9BC00D1134E /* BUYOptionSelectionViewController.h in Headers */,
84CD7C2E1CC65D5A00B6EE61 /* _BUYCheckoutAttribute.h in Headers */,
901931501BC5B9BC00D1134E /* BUYOrder.h in Headers */,
901931531BC5B9BC00D1134E /* BUYOptionSelectionNavigationController.h in Headers */,
901931541BC5B9BC00D1134E /* BUYPresentationControllerWithNavigationController.h in Headers */,
84D9154C1CC03F1600D334FB /* BUYManagedObject.h in Headers */,
901931551BC5B9BC00D1134E /* BUYPresentationControllerForVariantSelection.h in Headers */,
84DD12CF1CC6401400A2442D /* BUYCustomer.h in Headers */,
901931571BC5B9BC00D1134E /* BUYObject.h in Headers */,
901931581BC5B9BC00D1134E /* BUYRuntime.h in Headers */,
901931591BC5B9BC00D1134E /* BUYCollection.h in Headers */,
84D915441CC0359700D334FB /* BUYObserver.h in Headers */,
9019315A1BC5B9BC00D1134E /* BUYProductImageCollectionViewCell.h in Headers */,
84980F5F1CB7617E00CFAB58 /* BUYDateTransformer.h in Headers */,
84980F591CB7617500CFAB58 /* BUYURLTransformer.h in Headers */,
9019315B1BC5B9BC00D1134E /* BUYImageKit.h in Headers */,
84D915501CC03F1600D334FB /* BUYModelManager.h in Headers */,
9032F2DB1BE9457A00BB9EEF /* BUYCheckoutAttribute.h in Headers */,
9019315E1BC5B9BC00D1134E /* BUYError.h in Headers */,
84980F371CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.h in Headers */,
9019315F1BC5B9BC00D1134E /* BUYProductHeaderCell.h in Headers */,
901931601BC5B9BC00D1134E /* BUYProductViewErrorView.h in Headers */,
901931611BC5B9BC00D1134E /* BUYClient.h in Headers */,
901931631BC5B9BC00D1134E /* BUYGradientView.h in Headers */,
849810971CB7E07900CFAB58 /* BUYFlatCollectionTransformer.h in Headers */,
901931641BC5B9BC00D1134E /* BUYCartLineItem.h in Headers */,
8498DCAE1CDD1B2F00BD12A8 /* BUYError+BUYAdditions.h in Headers */,
901931661BC5B9BC00D1134E /* BUYCheckout.h in Headers */,
901931671BC5B9BC00D1134E /* BUYCart.h in Headers */,
901931681BC5B9BC00D1134E /* BUYProductViewController.h in Headers */,
901931691BC5B9BC00D1134E /* BUYProduct.h in Headers */,
9019316A1BC5B9BC00D1134E /* BUYSerializable.h in Headers */,
9A47CF041CE3A24600A6D5BA /* BUYApplePayToken.h in Headers */,
......@@ -1544,25 +1230,16 @@
84980F291CB75AC200CFAB58 /* BUYObjectProtocol.h in Headers */,
BE9A64741B503D2E0033E558 /* BUYApplePayHelpers.h in Headers */,
9A47CF221CE5112A00A6D5BA /* BUYAssert.h in Headers */,
BE9A647E1B503D930033E558 /* BUYStoreViewController.h in Headers */,
BE9A64551B503CC50033E558 /* BUYCreditCard.h in Headers */,
BE9A645F1B503CE90033E558 /* BUYOption.h in Headers */,
84980F4C1CB7613700CFAB58 /* BUYIdentityTransformer.h in Headers */,
BEB74A6F1B5564260005A300 /* BUYProductVariantCell.h in Headers */,
BEB74A2B1B554C150005A300 /* BUYTheme.h in Headers */,
BEB74A6B1B55641B0005A300 /* BUYProductDescriptionCell.h in Headers */,
BE9A645B1B503CDC0033E558 /* BUYLineItem.h in Headers */,
907874991B7276BA0023775B /* BUYProductViewHeaderOverlay.h in Headers */,
8498DCAA1CDD1B2500BD12A8 /* BUYShopifyErrorCodes.h in Headers */,
9A47CF081CE3ACE100A6D5BA /* BUYPaymentToken.h in Headers */,
BE9A64801B503D990033E558 /* BUYViewController.h in Headers */,
BE9A644F1B503CA90033E558 /* BUYDiscount.h in Headers */,
900396AC1B627CB900226B73 /* BUYProductView.h in Headers */,
8498DCB41CDD1B5400BD12A8 /* BUYClient+Customers.h in Headers */,
BE9A64511B503CB00033E558 /* BUYTaxLine.h in Headers */,
849810921CB7E07900CFAB58 /* BUYDeliveryRangeTransformer.h in Headers */,
BEB74A7D1B5564870005A300 /* BUYVariantSelectionViewController.h in Headers */,
BE10079B1B6165EC0031CEE7 /* BUYOptionValueCell.h in Headers */,
BE9A64591B503CD40033E558 /* BUYImageLink.h in Headers */,
84B0A7341CE10ED900253EB0 /* BUYPaymentController.h in Headers */,
BE9A64681B503D080033E558 /* BUYOptionValue.h in Headers */,
......@@ -1570,18 +1247,10 @@
84B0A7301CE10ED900253EB0 /* BUYApplePayPaymentProvider.h in Headers */,
BE9A644D1B503CA20033E558 /* BUYShippingRate.h in Headers */,
BE9A646C1B503D180033E558 /* BUYApplePayAdditions.h in Headers */,
906EAE431B836DE000976165 /* BUYTheme+Additions.h in Headers */,
BEB74A7B1B5564810005A300 /* BUYVariantOptionView.h in Headers */,
84980F521CB7616900CFAB58 /* BUYDecimalNumberTransformer.h in Headers */,
BE5DC3631B71022D00B2BC1E /* BUYMaskedCreditCard.h in Headers */,
BEB74A731B5564350005A300 /* BUYProductViewHeader.h in Headers */,
BEB74A751B55643B0005A300 /* BUYProductViewHeaderBackgroundImageView.h in Headers */,
90C856B61BD6B0F400936926 /* Buy.h in Headers */,
8498DCB31CDD1B5400BD12A8 /* BUYClient_Internal.h in Headers */,
900396B01B67BD0A00226B73 /* BUYCheckoutButton.h in Headers */,
BE9A64821B503DAD0033E558 /* BUYPaymentButton.h in Headers */,
BEB74A771B55646D0005A300 /* BUYImageView.h in Headers */,
909944491B71B76800C40A33 /* UIFont+BUYAdditions.h in Headers */,
841ADE0F1CB6C942000004B0 /* NSDictionary+BUYAdditions.h in Headers */,
841ADE1F1CB6C942000004B0 /* NSURL+BUYAdditions.h in Headers */,
841ADE231CB6C942000004B0 /* NSURLComponents+BUYAdditions.h in Headers */,
......@@ -1598,39 +1267,26 @@
841ADE0B1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.h in Headers */,
84980F321CB75C2900CFAB58 /* NSEntityDescription+BUYAdditions.h in Headers */,
BE9A64571B503CCC0033E558 /* BUYGiftCard.h in Headers */,
BEB74A671B55640C0005A300 /* BUYNavigationController.h in Headers */,
90DE92701B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.h in Headers */,
BEB74A711B5564300005A300 /* BUYProductViewFooter.h in Headers */,
BEB74A791B5564790005A300 /* BUYOptionSelectionViewController.h in Headers */,
84CD7C2D1CC65D5A00B6EE61 /* _BUYCheckoutAttribute.h in Headers */,
90E83BC41B9F550E00C95A1B /* BUYOrder.h in Headers */,
BEB74A281B554BFB0005A300 /* BUYOptionSelectionNavigationController.h in Headers */,
BEB74A691B5564160005A300 /* BUYPresentationControllerWithNavigationController.h in Headers */,
84D9154B1CC03F1600D334FB /* BUYManagedObject.h in Headers */,
BEB74A221B554BF20005A300 /* BUYPresentationControllerForVariantSelection.h in Headers */,
84DD12CD1CC6401400A2442D /* BUYCustomer.h in Headers */,
BE9A645D1B503CE30033E558 /* BUYObject.h in Headers */,
BE9A646E1B503D1E0033E558 /* BUYRuntime.h in Headers */,
BEB74A901B55A3D00005A300 /* BUYCollection.h in Headers */,
84D915431CC0359700D334FB /* BUYObserver.h in Headers */,
904606AF1B6BC8D700754173 /* BUYProductImageCollectionViewCell.h in Headers */,
84980F5E1CB7617E00CFAB58 /* BUYDateTransformer.h in Headers */,
84980F581CB7617500CFAB58 /* BUYURLTransformer.h in Headers */,
900E7C841B5DA553006F3C81 /* BUYImageKit.h in Headers */,
84D9154F1CC03F1600D334FB /* BUYModelManager.h in Headers */,
9032F2DA1BE9457A00BB9EEF /* BUYCheckoutAttribute.h in Headers */,
BE47340F1B66C4EF00AA721A /* BUYError.h in Headers */,
84980F361CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.h in Headers */,
BEB74A6D1B5564200005A300 /* BUYProductHeaderCell.h in Headers */,
903BCC7C1B7D1C2D00C21FEB /* BUYProductViewErrorView.h in Headers */,
BE9A64471B503C8B0033E558 /* BUYClient.h in Headers */,
BEB74A651B5563FF0005A300 /* BUYGradientView.h in Headers */,
849810961CB7E07900CFAB58 /* BUYFlatCollectionTransformer.h in Headers */,
9003969B1B601DF400226B73 /* BUYCartLineItem.h in Headers */,
8498DCAC1CDD1B2F00BD12A8 /* BUYError+BUYAdditions.h in Headers */,
BE9A644B1B503C9B0033E558 /* BUYCheckout.h in Headers */,
BE9A64491B503C940033E558 /* BUYCart.h in Headers */,
BEB74A2D1B554E870005A300 /* BUYProductViewController.h in Headers */,
BE9A64611B503CEF0033E558 /* BUYProduct.h in Headers */,
BE9A64651B503CFE0033E558 /* BUYSerializable.h in Headers */,
9A47CF031CE3A24600A6D5BA /* BUYApplePayToken.h in Headers */,
......@@ -1836,53 +1492,36 @@
files = (
901930E31BC5B9BC00D1134E /* BUYApplePayHelpers.m in Sources */,
84DD12AA1CC63FE600A2442D /* _BUYOrder.m in Sources */,
901930E41BC5B9BC00D1134E /* BUYOptionSelectionViewController.m in Sources */,
901930E51BC5B9BC00D1134E /* BUYVariantOptionView.m in Sources */,
841ADE1E1CB6C942000004B0 /* NSString+BUYAdditions.m in Sources */,
84980F5B1CB7617500CFAB58 /* BUYURLTransformer.m in Sources */,
901930E61BC5B9BC00D1134E /* BUYPresentationControllerForVariantSelection.m in Sources */,
84980F611CB7617E00CFAB58 /* BUYDateTransformer.m in Sources */,
901930E81BC5B9BC00D1134E /* BUYImageLink.m in Sources */,
84DD129E1CC63FE600A2442D /* _BUYCollection.m in Sources */,
901930E91BC5B9BC00D1134E /* BUYProductVariant.m in Sources */,
84D9154E1CC03F1600D334FB /* BUYManagedObject.m in Sources */,
901930EA1BC5B9BC00D1134E /* BUYProductViewController.m in Sources */,
84B0A7331CE10ED900253EB0 /* BUYApplePayPaymentProvider.m in Sources */,
841ADE021CB6C942000004B0 /* NSArray+BUYAdditions.m in Sources */,
901930EC1BC5B9BC00D1134E /* BUYError.m in Sources */,
841ADE0E1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.m in Sources */,
84DD12AE1CC63FE600A2442D /* _BUYProductVariant.m in Sources */,
84B0A7211CDD261100253EB0 /* BUYSerializable.m in Sources */,
901930ED1BC5B9BC00D1134E /* BUYProductViewHeader.m in Sources */,
901930EE1BC5B9BC00D1134E /* BUYNavigationController.m in Sources */,
901930EF1BC5B9BC00D1134E /* BUYVariantSelectionViewController.m in Sources */,
9A47CEFE1CE39F6100A6D5BA /* BUYCreditCardToken.m in Sources */,
901930F21BC5B9BC00D1134E /* BUYOrder.m in Sources */,
901930F41BC5B9BC00D1134E /* BUYProductViewHeaderBackgroundImageView.m in Sources */,
901930F51BC5B9BC00D1134E /* BUYProductViewHeaderOverlay.m in Sources */,
901930F61BC5B9BC00D1134E /* BUYProductVariantCell.m in Sources */,
849810991CB7E07900CFAB58 /* BUYFlatCollectionTransformer.m in Sources */,
84DD12A41CC63FE600A2442D /* _BUYLineItem.m in Sources */,
901930F71BC5B9BC00D1134E /* BUYTheme.m in Sources */,
84DD12CC1CC63FEE00A2442D /* _BUYTaxLine.m in Sources */,
84DD12CA1CC63FEE00A2442D /* _BUYShippingRate.m in Sources */,
901930F91BC5B9BC00D1134E /* BUYProductViewErrorView.m in Sources */,
901930FA1BC5B9BC00D1134E /* BUYLineItem.m in Sources */,
901930FB1BC5B9BC00D1134E /* BUYCheckoutButton.m in Sources */,
849810951CB7E07900CFAB58 /* BUYDeliveryRangeTransformer.m in Sources */,
84DD12B01CC63FE600A2442D /* _BUYShop.m in Sources */,
901930FC1BC5B9BC00D1134E /* BUYCollection.m in Sources */,
901930FD1BC5B9BC00D1134E /* BUYTaxLine.m in Sources */,
84980F351CB75C2900CFAB58 /* NSEntityDescription+BUYAdditions.m in Sources */,
84D915461CC0359700D334FB /* BUYObserver.m in Sources */,
901930FF1BC5B9BC00D1134E /* BUYVariantOptionBreadCrumbsView.m in Sources */,
901931011BC5B9BC00D1134E /* BUYTheme+Additions.m in Sources */,
901931021BC5B9BC00D1134E /* BUYStoreViewController.m in Sources */,
84D73C091CDD194D000F978A /* BUYAddress.m in Sources */,
901931031BC5B9BC00D1134E /* BUYOptionValue.m in Sources */,
84980F551CB7616900CFAB58 /* BUYDecimalNumberTransformer.m in Sources */,
901931041BC5B9BC00D1134E /* BUYApplePayAdditions.m in Sources */,
901931051BC5B9BC00D1134E /* BUYOptionSelectionNavigationController.m in Sources */,
901931061BC5B9BC00D1134E /* BUYDiscount.m in Sources */,
84DD129A1CC63FE600A2442D /* _BUYCart.m in Sources */,
841ADE0A1CB6C942000004B0 /* NSDateFormatter+BUYAdditions.m in Sources */,
......@@ -1890,7 +1529,6 @@
84DD12C21CC63FEE00A2442D /* _BUYCheckout.m in Sources */,
901931091BC5B9BC00D1134E /* BUYCart.m in Sources */,
84B0A73D1CE10ED900253EB0 /* BUYWebCheckoutPaymentProvider.m in Sources */,
9019310A1BC5B9BC00D1134E /* BUYPaymentButton.m in Sources */,
9A47CF061CE3A24600A6D5BA /* BUYApplePayToken.m in Sources */,
84D915521CC03F1600D334FB /* BUYModelManager.m in Sources */,
84DD129C1CC63FE600A2442D /* _BUYCartLineItem.m in Sources */,
......@@ -1898,42 +1536,31 @@
9019310C1BC5B9BC00D1134E /* BUYGiftCard.m in Sources */,
841ADE161CB6C942000004B0 /* NSException+BUYModelAdditions.m in Sources */,
84DD12A01CC63FE600A2442D /* _BUYCustomer.m in Sources */,
9019310D1BC5B9BC00D1134E /* BUYOptionValueCell.m in Sources */,
9019310E1BC5B9BC00D1134E /* BUYProduct.m in Sources */,
84DD12C81CC63FEE00A2442D /* _BUYMaskedCreditCard.m in Sources */,
84DD12AC1CC63FE600A2442D /* _BUYProduct.m in Sources */,
9019310F1BC5B9BC00D1134E /* BUYImageView.m in Sources */,
84DD12A21CC63FE600A2442D /* _BUYImageLink.m in Sources */,
901931101BC5B9BC00D1134E /* BUYProductHeaderCell.m in Sources */,
841ADE1A1CB6C942000004B0 /* NSRegularExpression+BUYAdditions.m in Sources */,
8498DCBE1CDD1FA400BD12A8 /* BUYAccountCredentials.m in Sources */,
9032F2DD1BE9457A00BB9EEF /* BUYCheckoutAttribute.m in Sources */,
901931111BC5B9BC00D1134E /* BUYCartLineItem.m in Sources */,
901931121BC5B9BC00D1134E /* BUYMaskedCreditCard.m in Sources */,
901931131BC5B9BC00D1134E /* BUYCheckout.m in Sources */,
901931141BC5B9BC00D1134E /* BUYProductViewFooter.m in Sources */,
84DD12A61CC63FE600A2442D /* _BUYOption.m in Sources */,
841ADE261CB6C942000004B0 /* NSURLComponents+BUYAdditions.m in Sources */,
8498DCAF1CDD1B2F00BD12A8 /* BUYError+BUYAdditions.m in Sources */,
901931151BC5B9BC00D1134E /* BUYPresentationControllerWithNavigationController.m in Sources */,
84DD12D01CC6401400A2442D /* BUYCustomer.m in Sources */,
84980F391CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.m in Sources */,
841ADE221CB6C942000004B0 /* NSURL+BUYAdditions.m in Sources */,
901931161BC5B9BC00D1134E /* BUYShippingRate.m in Sources */,
841ADE061CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
901931181BC5B9BC00D1134E /* BUYGradientView.m in Sources */,
901931191BC5B9BC00D1134E /* BUYViewController.m in Sources */,
84B0A7431CE10F8100253EB0 /* BUYClient+Checkout.m in Sources */,
9019311A1BC5B9BC00D1134E /* BUYImageKit.m in Sources */,
84B0A7371CE10ED900253EB0 /* BUYPaymentController.m in Sources */,
9019311C1BC5B9BC00D1134E /* BUYOption.m in Sources */,
84D73C081CDD194D000F978A /* _BUYAddress.m in Sources */,
9019311D1BC5B9BC00D1134E /* BUYClient.m in Sources */,
9019311E1BC5B9BC00D1134E /* UIFont+BUYAdditions.m in Sources */,
8498DCB81CDD1B5400BD12A8 /* BUYClient+Customers.m in Sources */,
9019311F1BC5B9BC00D1134E /* BUYProductView.m in Sources */,
901931201BC5B9BC00D1134E /* BUYCreditCard.m in Sources */,
901931211BC5B9BC00D1134E /* BUYProductImageCollectionViewCell.m in Sources */,
84980F4F1CB7613700CFAB58 /* BUYIdentityTransformer.m in Sources */,
84CD7C301CC65D7C00B6EE61 /* _BUYCheckoutAttribute.m in Sources */,
84DD12A81CC63FE600A2442D /* _BUYOptionValue.m in Sources */,
......@@ -1942,7 +1569,6 @@
84DD12C61CC63FEE00A2442D /* _BUYGiftCard.m in Sources */,
84DD12C41CC63FEE00A2442D /* _BUYDiscount.m in Sources */,
84D915591CC040C300D334FB /* Mobile Buy SDK.xcdatamodeld in Sources */,
901931241BC5B9BC00D1134E /* BUYProductDescriptionCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1951,7 +1577,6 @@
buildActionMask = 2147483647;
files = (
BEB9AE7D1BA885E300575F8A /* BUYClientTestBase.m in Sources */,
8491103E1CCE988600E53B93 /* BUYFontAdditionsTests.m in Sources */,
8491103A1CCE718100E53B93 /* BUYExceptionAdditionsTests.m in Sources */,
849110441CCE9F3F00E53B93 /* BUYTransformerTests.m in Sources */,
8498DCCC1CDD208200BD12A8 /* BUYCustomerTests.m in Sources */,
......@@ -1996,53 +1621,36 @@
files = (
BE9A64751B503D370033E558 /* BUYApplePayHelpers.m in Sources */,
84DD12921CC63FE600A2442D /* _BUYOrder.m in Sources */,
BEB74A7A1B55647C0005A300 /* BUYOptionSelectionViewController.m in Sources */,
BEB74A7C1B5564840005A300 /* BUYVariantOptionView.m in Sources */,
841ADE1D1CB6C942000004B0 /* NSString+BUYAdditions.m in Sources */,
84980F5A1CB7617500CFAB58 /* BUYURLTransformer.m in Sources */,
BEB74A241B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m in Sources */,
84980F601CB7617E00CFAB58 /* BUYDateTransformer.m in Sources */,
BE9A645A1B503CD90033E558 /* BUYImageLink.m in Sources */,
84DD12861CC63FE600A2442D /* _BUYCollection.m in Sources */,
BE9A64641B503CFB0033E558 /* BUYProductVariant.m in Sources */,
84D9154D1CC03F1600D334FB /* BUYManagedObject.m in Sources */,
BEB74A2E1B554E8B0005A300 /* BUYProductViewController.m in Sources */,
84B0A7321CE10ED900253EB0 /* BUYApplePayPaymentProvider.m in Sources */,
841ADE011CB6C942000004B0 /* NSArray+BUYAdditions.m in Sources */,
BE4734101B66C4EF00AA721A /* BUYError.m in Sources */,
841ADE0D1CB6C942000004B0 /* NSDecimalNumber+BUYAdditions.m in Sources */,
84DD12961CC63FE600A2442D /* _BUYProductVariant.m in Sources */,
84B0A7201CDD261100253EB0 /* BUYSerializable.m in Sources */,
BEB74A741B5564380005A300 /* BUYProductViewHeader.m in Sources */,
BEB74A681B55640F0005A300 /* BUYNavigationController.m in Sources */,
BEB74A7E1B5564890005A300 /* BUYVariantSelectionViewController.m in Sources */,
9A47CEFD1CE39F6000A6D5BA /* BUYCreditCardToken.m in Sources */,
90E83BC51B9F550E00C95A1B /* BUYOrder.m in Sources */,
BEB74A761B55643E0005A300 /* BUYProductViewHeaderBackgroundImageView.m in Sources */,
9078749A1B7276BA0023775B /* BUYProductViewHeaderOverlay.m in Sources */,
BEB74A701B5564290005A300 /* BUYProductVariantCell.m in Sources */,
849810981CB7E07900CFAB58 /* BUYFlatCollectionTransformer.m in Sources */,
84DD128C1CC63FE600A2442D /* _BUYLineItem.m in Sources */,
BEB74A2C1B554C370005A300 /* BUYTheme.m in Sources */,
84DD12BE1CC63FEE00A2442D /* _BUYTaxLine.m in Sources */,
84DD12BC1CC63FEE00A2442D /* _BUYShippingRate.m in Sources */,
903BCC7D1B7D1C2D00C21FEB /* BUYProductViewErrorView.m in Sources */,
BE9A645C1B503CE00033E558 /* BUYLineItem.m in Sources */,
900396B11B67BD0A00226B73 /* BUYCheckoutButton.m in Sources */,
849810941CB7E07900CFAB58 /* BUYDeliveryRangeTransformer.m in Sources */,
84DD12981CC63FE600A2442D /* _BUYShop.m in Sources */,
9089CC5E1BB48D06009726D6 /* BUYCollection.m in Sources */,
BE9A64521B503CB80033E558 /* BUYTaxLine.m in Sources */,
84980F341CB75C2900CFAB58 /* NSEntityDescription+BUYAdditions.m in Sources */,
84D915451CC0359700D334FB /* BUYObserver.m in Sources */,
90DE92711B9897B6002EF4DA /* BUYVariantOptionBreadCrumbsView.m in Sources */,
906EAE441B836DE000976165 /* BUYTheme+Additions.m in Sources */,
BE9A647F1B503D960033E558 /* BUYStoreViewController.m in Sources */,
84D73C071CDD194D000F978A /* BUYAddress.m in Sources */,
BE9A64691B503D0C0033E558 /* BUYOptionValue.m in Sources */,
84980F541CB7616900CFAB58 /* BUYDecimalNumberTransformer.m in Sources */,
BE9A646D1B503D1C0033E558 /* BUYApplePayAdditions.m in Sources */,
BEB74A2A1B554BFB0005A300 /* BUYOptionSelectionNavigationController.m in Sources */,
BE9A64501B503CAD0033E558 /* BUYDiscount.m in Sources */,
84DD12821CC63FE600A2442D /* _BUYCart.m in Sources */,
841ADE091CB6C942000004B0 /* NSDateFormatter+BUYAdditions.m in Sources */,
......@@ -2050,7 +1658,6 @@
84DD12B41CC63FEE00A2442D /* _BUYCheckout.m in Sources */,
BE9A644A1B503C980033E558 /* BUYCart.m in Sources */,
84B0A73C1CE10ED900253EB0 /* BUYWebCheckoutPaymentProvider.m in Sources */,
BE9A64831B503DB10033E558 /* BUYPaymentButton.m in Sources */,
9A47CF051CE3A24600A6D5BA /* BUYApplePayToken.m in Sources */,
84D915511CC03F1600D334FB /* BUYModelManager.m in Sources */,
84DD12841CC63FE600A2442D /* _BUYCartLineItem.m in Sources */,
......@@ -2058,42 +1665,31 @@
BE9A64581B503CD10033E558 /* BUYGiftCard.m in Sources */,
841ADE151CB6C942000004B0 /* NSException+BUYModelAdditions.m in Sources */,
84DD12881CC63FE600A2442D /* _BUYCustomer.m in Sources */,
BE10079C1B6165EC0031CEE7 /* BUYOptionValueCell.m in Sources */,
BE9A64621B503CF40033E558 /* BUYProduct.m in Sources */,
84DD12BA1CC63FEE00A2442D /* _BUYMaskedCreditCard.m in Sources */,
84DD12941CC63FE600A2442D /* _BUYProduct.m in Sources */,
BEB74A781B55646F0005A300 /* BUYImageView.m in Sources */,
84DD128A1CC63FE600A2442D /* _BUYImageLink.m in Sources */,
BEB74A6E1B5564230005A300 /* BUYProductHeaderCell.m in Sources */,
841ADE191CB6C942000004B0 /* NSRegularExpression+BUYAdditions.m in Sources */,
8498DCBD1CDD1FA400BD12A8 /* BUYAccountCredentials.m in Sources */,
9032F2DC1BE9457A00BB9EEF /* BUYCheckoutAttribute.m in Sources */,
9003969C1B601DF400226B73 /* BUYCartLineItem.m in Sources */,
BE5DC3641B71022D00B2BC1E /* BUYMaskedCreditCard.m in Sources */,
BE9A644C1B503C9F0033E558 /* BUYCheckout.m in Sources */,
BEB74A721B5564320005A300 /* BUYProductViewFooter.m in Sources */,
84DD128E1CC63FE600A2442D /* _BUYOption.m in Sources */,
841ADE251CB6C942000004B0 /* NSURLComponents+BUYAdditions.m in Sources */,
8498DCAD1CDD1B2F00BD12A8 /* BUYError+BUYAdditions.m in Sources */,
BEB74A6A1B5564190005A300 /* BUYPresentationControllerWithNavigationController.m in Sources */,
84DD12CE1CC6401400A2442D /* BUYCustomer.m in Sources */,
84980F381CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.m in Sources */,
841ADE211CB6C942000004B0 /* NSURL+BUYAdditions.m in Sources */,
BE9A644E1B503CA60033E558 /* BUYShippingRate.m in Sources */,
841ADE051CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
BEB74A661B5564030005A300 /* BUYGradientView.m in Sources */,
BE9A64811B503D9E0033E558 /* BUYViewController.m in Sources */,
84B0A7421CE10F8100253EB0 /* BUYClient+Checkout.m in Sources */,
900E7C851B5DA559006F3C81 /* BUYImageKit.m in Sources */,
84B0A7361CE10ED900253EB0 /* BUYPaymentController.m in Sources */,
BE9A64601B503CEC0033E558 /* BUYOption.m in Sources */,
84D73C061CDD194D000F978A /* _BUYAddress.m in Sources */,
BE9A64481B503C900033E558 /* BUYClient.m in Sources */,
9099444A1B71B76800C40A33 /* UIFont+BUYAdditions.m in Sources */,
8498DCB51CDD1B5400BD12A8 /* BUYClient+Customers.m in Sources */,
900396AD1B627CB900226B73 /* BUYProductView.m in Sources */,
BE9A64561B503CC90033E558 /* BUYCreditCard.m in Sources */,
904606B01B6BC8D700754173 /* BUYProductImageCollectionViewCell.m in Sources */,
84980F4E1CB7613700CFAB58 /* BUYIdentityTransformer.m in Sources */,
84CD7C2F1CC65D7B00B6EE61 /* _BUYCheckoutAttribute.m in Sources */,
84DD12901CC63FE600A2442D /* _BUYOptionValue.m in Sources */,
......@@ -2102,7 +1698,6 @@
84DD12B81CC63FEE00A2442D /* _BUYGiftCard.m in Sources */,
84DD12B61CC63FEE00A2442D /* _BUYDiscount.m in Sources */,
84D915581CC040C300D334FB /* Mobile Buy SDK.xcdatamodeld in Sources */,
BEB74A6C1B55641D0005A300 /* BUYProductDescriptionCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -2,8 +2,26 @@
// BUYAssert.h
// Mobile Buy SDK
//
// Created by Dima Bart on 2016-05-12.
// Copyright © 2016 Shopify Inc. All rights reserved.
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#define BUYAssert(exp, ...) \
......
......@@ -75,11 +75,6 @@ FOUNDATION_EXPORT const unsigned char BuyVersionString[];
#import <Buy/BUYShopifyErrorCodes.h>
#import <Buy/BUYPaymentToken.h>
#import <Buy/BUYPaymentButton.h>
#import <Buy/BUYProductViewController.h>
#import <Buy/BUYStoreViewController.h>
#import <Buy/BUYTheme.h>
#import <Buy/BUYViewController.h>
#import <Buy/NSArray+BUYAdditions.h>
#import <Buy/NSDate+BUYAdditions.h>
......
//
// BUYProductViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYGradientView.h"
#import "BUYImageView.h"
#import "BUYOptionSelectionNavigationController.h"
#import "BUYPresentationControllerWithNavigationController.h"
#import "BUYProduct.h"
#import "BUYProductViewController.h"
#import "BUYImageKit.h"
#import "BUYImageLink.h"
#import "BUYProductView.h"
#import "BUYProductViewFooter.h"
#import "BUYProductHeaderCell.h"
#import "BUYProductVariantCell.h"
#import "BUYProductDescriptionCell.h"
#import "BUYProductViewHeader.h"
#import "BUYProductImageCollectionViewCell.h"
#import "BUYProductViewHeaderBackgroundImageView.h"
#import "BUYProductViewHeaderOverlay.h"
#import "BUYTheme+Additions.h"
#import "BUYVariantSelectionViewController.h"
#import "BUYError.h"
#import "BUYShop.h"
#import "BUYShopifyErrorCodes.h"
CGFloat const BUYMaxProductViewWidth = 414.0; // We max out to the width of the iPhone 6+
CGFloat const BUYMaxProductViewHeight = 640.0;
@interface BUYProductViewController (Private)
@property (nonatomic, strong) BUYCheckout *checkout;
- (void)handleCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)completion;
- (void)postCheckoutCompletion:(BUYCheckout *)checkout error:(NSError *)error;
@end
@interface BUYProductViewController () <BUYThemeable, UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate, BUYVariantSelectionDelegate, BUYNavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) NSString *productId;
@property (nonatomic, strong) BUYProductVariant *selectedProductVariant;
@property (nonatomic, strong) BUYTheme *theme;
@property (nonatomic, assign) BOOL shouldShowVariantSelector;
@property (nonatomic, assign) BOOL shouldEnableVariantSelection;
@property (nonatomic, assign) BOOL shouldShowDescription;
@property (nonatomic, strong) BUYProduct *product;
@property (nonatomic, assign) BOOL isLoading;
@property (nonatomic, strong) NSNumberFormatter *currencyFormatter;
// views
@property (nonatomic, strong) BUYProductView *productView;
@property (nonatomic, weak) UIView *navigationBar;
@property (nonatomic, weak) UILabel *navigationBarTitle;
@property (nonatomic, strong) BUYProductHeaderCell *headerCell;
@property (nonatomic, strong) BUYProductVariantCell *variantCell;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
@end
@implementation BUYProductViewController
@synthesize theme = _theme;
- (instancetype)initWithClient:(BUYClient *)client
{
return [self initWithClient:client theme:nil];
}
- (instancetype)initWithClient:(BUYClient *)client theme:(BUYTheme *)theme
{
self = [super initWithClient:client];
if (self) {
self.theme = theme? : [[BUYTheme alloc] init];
self.modalPresentationStyle = UIModalPresentationCustom;
self.transitioningDelegate = self;
self.allowApplePaySetup = YES;
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
_activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO;
_activityIndicatorView.hidesWhenStopped = YES;
[_activityIndicatorView startAnimating];
[self.view addSubview:_activityIndicatorView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicatorView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicatorView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
}
return self;
}
- (BUYProductView *)productView
{
if (_productView == nil && self.product != nil && self.shop != nil) {
_productView = [[BUYProductView alloc] initWithFrame:CGRectMake(0, 0, self.preferredContentSize.width, self.preferredContentSize.height) product:self.product theme:self.theme shouldShowApplePaySetup:self.shouldShowApplePaySetup];
_productView.translatesAutoresizingMaskIntoConstraints = NO;
_productView.hidden = YES;
[self.view addSubview:_productView];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_productView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_productView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_productView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_productView)]];
_productView.tableView.delegate = self;
_productView.tableView.dataSource = self;
[_productView.productViewFooter setApplePayButtonVisible:self.shouldShowApplePayButton];
[_productView.productViewFooter.buyPaymentButton addTarget:self action:@selector(checkoutWithApplePay) forControlEvents:UIControlEventTouchUpInside];
[_productView.productViewFooter.checkoutButton addTarget:self action:@selector(checkoutWithShopify) forControlEvents:UIControlEventTouchUpInside];
_productView.productViewHeader.collectionView.delegate = self;
_productView.productViewHeader.collectionView.dataSource = self;
_productView.layoutMargins = UIEdgeInsetsMake(self.productView.layoutMargins.top, self.productView.layoutMargins.left, self.bottomLayoutGuide.length, self.productView.layoutMargins.right);
}
return _productView;
}
- (CGSize)preferredContentSize
{
return CGSizeMake(MIN(BUYMaxProductViewWidth, self.view.bounds.size.width),
MIN(BUYMaxProductViewHeight, self.view.bounds.size.height));
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupNavigationBarAppearance];
[self.navigationController setNavigationBarHidden:self.isLoading];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (self.productView.hasSetVariantOnCollectionView == NO) {
if ([self canCollectionViewDrawProductImages] || [self.product.images count] == 0) {
[self setSelectedProductVariant:self.selectedProductVariant];
self.productView.hasSetVariantOnCollectionView = YES;
}
}
}
- (BOOL)canCollectionViewDrawProductImages
{
return [self.product.images count] > 0 && CGSizeEqualToSize(self.productView.productViewHeader.collectionView.bounds.size, CGSizeZero) == NO;
}
- (void)setupNavigationBarAppearance
{
if (self.navigationBar == nil && _productView && self.presentingViewController != nil) {
for (UIView *view in [self.navigationController.navigationBar subviews]) {
if (CGRectGetHeight(view.bounds) >= 44) {
// Get a reference to the UINavigationBar
self.navigationBar = view;
self.navigationBar.alpha = 0;
continue;
} else if ([view.subviews count] == 1 && [view.subviews[0] isKindOfClass:[UILabel class]]) {
// Get a reference to the UINavigationBar's title
self.navigationBarTitle = view.subviews[0];
self.navigationBarTitle.alpha = 0;
continue;
}
}
// Hide the navigation bar
[self scrollViewDidScroll:self.productView.tableView];
} else if (self.navigationController && _productView && self.presentingViewController == nil) {
[self.productView setTopInset:CGRectGetHeight(self.navigationController.navigationBar.bounds) + self.navigationController.topLayoutGuide.length];
}
}
- (void)setTheme:(BUYTheme *)theme
{
_theme = theme;
self.view.tintColor = theme.tintColor;
self.view.backgroundColor = [theme backgroundColor];
self.productView.theme = theme;
self.activityIndicatorView.activityIndicatorViewStyle = [theme activityIndicatorViewStyle];
[self setNeedsStatusBarAppearanceUpdate];
}
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
{
BUYPresentationControllerWithNavigationController *presentationController = [[BUYPresentationControllerWithNavigationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
presentationController.delegate = presentationController;
presentationController.navigationDelegate = self;
[presentationController setTheme:self.theme];
return presentationController;
}
- (void)loadProduct:(NSString *)productId completion:(void (^)(BOOL success, NSError *error))completion
{
if (productId == nil) {
if (completion) {
completion(NO, [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoProductSpecified userInfo:nil]);
}
}
else {
self.isLoading = YES;
[self loadShopWithCallback:^(BOOL success, NSError *error) {
if (success) {
self.productId = productId;
[self.client getProductById:productId completion:^(BUYProduct *product, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
self.isLoading = NO;
if (error) {
if (completion) {
completion(NO, error);
}
}
else {
self.product = product;
if (completion) {
completion(YES, nil);
}
}
});
}];
}
else {
self.isLoading = NO;
if (completion) {
completion(success, error);
}
}
}];
}
}
- (void)loadWithProduct:(BUYProduct *)product completion:(void (^)(BOOL success, NSError *error))completion;
{
if (product == nil) {
completion(NO, [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoProductSpecified userInfo:nil]);
}
else {
if (self.shop == nil) {
self.isLoading = YES;
[self loadShopWithCallback:^(BOOL success, NSError *error) {
self.product = product;
self.isLoading = NO;
if (completion) {
completion(success, error);
}
}];
}
else {
self.product = product;
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion(YES, nil);
}
});
}
}
}
- (void)setProduct:(BUYProduct *)product
{
_product = product;
self.navigationItem.title = _product.title;
self.selectedProductVariant = [_product.variants firstObject];
self.shouldShowVariantSelector = [_product isDefaultVariant] == NO;
self.shouldEnableVariantSelection = self.shouldShowVariantSelector && [_product.variants count] > 1;
self.shouldShowDescription = ([_product.htmlDescription length] == 0) == NO;
self.productView.hidden = NO;
[self setupNavigationBarAppearance];
[self.activityIndicatorView stopAnimating];
[self setNeedsStatusBarAppearanceUpdate];
[self.navigationController setNavigationBarHidden:NO];
}
- (void)setShop:(BUYShop *)shop
{
[super setShop:shop];
self.currencyFormatter = [[NSNumberFormatter alloc] init];
self.currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
self.currencyFormatter.currencyCode = shop.currency;
[self.productView.productViewFooter setApplePayButtonVisible:self.shouldShowApplePayButton];
[self.productView.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
if (self.product) {
rows += 1; // product title and price
rows += self.shouldShowVariantSelector;
rows += self.shouldShowDescription;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell <BUYThemeable> *theCell = nil;
if (indexPath.row == 0) {
BUYProductHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"headerCell"];
[cell setProductVariant:self.selectedProductVariant withCurrencyFormatter:self.currencyFormatter];
self.headerCell = cell;
theCell = cell;
} else if (indexPath.row == 1 && self.shouldShowVariantSelector) {
BUYProductVariantCell *cell = [tableView dequeueReusableCellWithIdentifier:@"variantCell"];
[cell setOptionsForProductVariant:self.selectedProductVariant];
cell.accessoryType = self.shouldEnableVariantSelection ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
self.variantCell = cell;
theCell = cell;
} else if ((indexPath.row == 2 && self.shouldShowDescription) || (indexPath.row == 1 && self.shouldShowVariantSelector == NO && self.shouldShowDescription)) {
BUYProductDescriptionCell *cell = [tableView dequeueReusableCellWithIdentifier:@"descriptionCell"];
cell.descriptionHTML = self.product.htmlDescription;
cell.separatorInset = UIEdgeInsetsMake(0, CGRectGetWidth(self.productView.tableView.bounds), 0, 0);
theCell = cell;
}
[theCell setTheme:self.theme];
return theCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1 && self.shouldEnableVariantSelection) {
[self.productView.tableView deselectRowAtIndexPath:indexPath animated:YES];
BUYVariantSelectionViewController *optionSelectionViewController = [[BUYVariantSelectionViewController alloc] initWithProduct:self.product theme:self.theme];
optionSelectionViewController.selectedProductVariant = self.selectedProductVariant;
optionSelectionViewController.delegate = self;
optionSelectionViewController.currencyFormatter = self.currencyFormatter;
BUYOptionSelectionNavigationController *optionSelectionNavigationController = [[BUYOptionSelectionNavigationController alloc] initWithRootViewController:optionSelectionViewController];
[optionSelectionNavigationController setTheme:self.theme];
[self presentViewController:optionSelectionNavigationController animated:YES completion:nil];
}
}
#pragma mark - BUYVariantSelectionViewControllerDelegate
- (void)variantSelectionController:(BUYVariantSelectionViewController *)controller didSelectVariant:(BUYProductVariant *)variant
{
if (self.selectedProductVariant != variant) {
self.selectedProductVariant = variant;
[self.productView.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[self dismissViewControllerAnimated:YES completion:^{
[self setNeedsStatusBarAppearanceUpdate];
[self scrollViewDidScroll:self.productView.tableView];
}];
}
- (void)variantSelectionControllerDidCancelVariantSelection:(BUYVariantSelectionViewController *)controller atOptionIndex:(NSUInteger)optionIndex
{
[self dismissViewControllerAnimated:YES completion:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (void)setSelectedProductVariant:(BUYProductVariant *)selectedProductVariant {
_selectedProductVariant = selectedProductVariant;
if (self.headerCell) {
[self.headerCell setProductVariant:selectedProductVariant withCurrencyFormatter:self.currencyFormatter];
[self.variantCell setOptionsForProductVariant:self.selectedProductVariant];
}
if (self.productView.productViewHeader.collectionView) {
NSArray *images = self.product.images.array;
[self.productView.productViewHeader setImageForSelectedVariant:_selectedProductVariant withImages:images];
[self.productView updateBackgroundImage:images];
}
if (self.productView.productViewFooter) {
[self.productView.productViewFooter updateButtonsForProductVariant:selectedProductVariant];
}
if (self.productView.tableView) {
[self scrollViewDidScroll:self.productView.tableView];
}
}
#pragma mark Scroll view delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ([scrollView isKindOfClass:[UITableView class]]) {
if (self.productView.productViewHeader) {
[self.productView scrollViewDidScroll:scrollView];
if (self.navigationBar) {
CGFloat duration = 0.3f;
if (self.navigationBar.alpha != 1 && [self navigationBarThresholdReached] == YES) {
[(BUYNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:YES duration:duration];
[UIView animateWithDuration:duration
delay:0
options:(UIViewAnimationOptionCurveLinear | UIViewKeyframeAnimationOptionBeginFromCurrentState)
animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationBar.alpha = 1;
self.navigationBarTitle.alpha = 1;
}
completion:NULL];
} else if (self.navigationBar.alpha != 0 && [self navigationBarThresholdReached] == NO) {
duration = 0.2f;
[(BUYNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:NO duration:duration];
[UIView animateWithDuration:duration
delay:0
options:(UIViewAnimationOptionCurveLinear | UIViewKeyframeAnimationOptionBeginFromCurrentState)
animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationBar.alpha = 0;
self.navigationBarTitle.alpha = 0;
}
completion:NULL];
}
[self.productView.productViewHeader.productViewHeaderOverlay scrollViewDidScroll:scrollView withNavigationBarHeight:CGRectGetHeight(self.navigationBar.bounds)];
}
} else if (self.productView.productViewHeader == nil && self.navigationBar && self.navigationBar.alpha == 0) {
// If the product view does not contain an image, inset the productView so its not obstructed with the navigation bar
[(BUYNavigationController*)self.navigationController updateCloseButtonImageWithTintColor:YES duration:0];
self.navigationBar.alpha = 1;
self.navigationBarTitle.alpha = 1;
CGFloat topInset = 0;
if (self.presentingViewController) {
topInset = CGRectGetHeight(self.navigationController.navigationBar.bounds) + self.presentingViewController.topLayoutGuide.length;
}
[self.productView setInsets:UIEdgeInsetsMake(topInset, 0, 0, 0) appendToCurrentInset:YES];
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if ([scrollView isKindOfClass:[UICollectionView class]]) {
[self.productView updateBackgroundImage:self.product.images.array];
}
}
#pragma mark Checkout
- (BUYCart *)cart
{
BUYCart *cart = [self.client.modelManager insertCartWithJSONDictionary:nil];
[cart addVariant:self.selectedProductVariant];
return cart;
}
- (void)checkoutWithApplePay
{
if (self.isApplePayAvailable) {
self.checkout = [[BUYCheckout alloc] initWithCart:[self cart]];
[self startApplePayCheckout:self.checkout];
} else {
[[[PKPassLibrary alloc] init] openPaymentSetup];
}
}
- (void)checkoutWithShopify
{
self.checkout = [[BUYCheckout alloc] initWithCart:[self cart]];
[self startWebCheckout:self.checkout];
}
- (void)startWebCheckout:(BUYCheckout *)checkout
{
[_productView.productViewFooter.checkoutButton showActivityIndicator:YES];
[self handleCheckout:checkout completion:^(BUYCheckout *checkout, NSError *error) {
[_productView.productViewFooter.checkoutButton showActivityIndicator:NO];
[self postCheckoutCompletion:checkout error:error];
if (error) {
[self.productView showErrorWithMessage:@"Could not checkout at this time"];
}
}];
}
#pragma mark UIStatusBar appearance
- (UIStatusBarStyle)preferredStatusBarStyle
{
if (self.theme.style == BUYThemeStyleDark || ([self navigationBarThresholdReached] == NO && self.isLoading == NO && self.productView.productViewHeader)) {
return UIStatusBarStyleLightContent;
} else if (self.isLoading == YES && self.theme.style == BUYThemeStyleDark && self.productView.productViewHeader) {
return UIStatusBarStyleLightContent;
} else {
return UIStatusBarStyleDefault;
}
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationFade;
}
- (BOOL)navigationBarThresholdReached
{
return self.productView.tableView.contentOffset.y > CGRectGetHeight(self.productView.productViewHeader.bounds) - CGRectGetHeight(self.navigationBar.bounds);
}
#pragma mark BUYPresentationControllerWithNavigationControllerDelegate
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate {
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
}
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
{
}
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
{
if ([self.delegate respondsToSelector:@selector(didDismissViewController:)]) {
[self.delegate didDismissViewController:self];
}
_product = nil;
_productId = nil;
[_productView removeFromSuperview];
_productView = nil;
}
#pragma mark - Collection View Delegate and Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.product.images count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
BUYProductImageCollectionViewCell *cell = (BUYProductImageCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
BUYImageLink *image = self.product.images[indexPath.row];
NSURL *url = [NSURL URLWithString:image.src];
[cell.productImageView loadImageWithURL:url completion:NULL];
[cell setContentOffset:self.productView.tableView.contentOffset];
return cell;
}
- (void)presentPortraitInViewController:(UIViewController *)controller
{
BUYNavigationController *navController = [[BUYNavigationController alloc] initWithRootViewController:self];
navController.modalPresentationStyle = [BUYPresentationControllerWithNavigationController adaptivePresentationStyle];
navController.navigationDelegate = self;
[navController setTheme:self.theme];
[controller presentViewController:navController animated:YES completion:nil];
}
@end
//
// BUYProductViewFooter.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import PassKit;
#import "BUYProductViewFooter.h"
#import "BUYTheme.h"
#import "BUYProductVariant.h"
#import "BUYTheme+Additions.h"
@interface BUYProductViewFooter ()
@property (nonatomic, strong) UIVisualEffectView *visualEffectView;
@property (nonatomic, strong) NSArray *checkoutLayoutConstraints;
@property (nonatomic, strong) NSArray *applePayLayoutConstraints;
@property (nonatomic, strong) BUYTheme *theme;
@end
@implementation BUYProductViewFooter
- (instancetype)initWithTheme:(BUYTheme *)theme showApplePaySetup:(BOOL)showApplePaySetup
{
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.theme = theme;
self.visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[theme blurEffect]];
self.visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.visualEffectView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_visualEffectView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_visualEffectView)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_visualEffectView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_visualEffectView)]];
UIView *separatorLineView = [[UIView alloc] init];
separatorLineView.translatesAutoresizingMaskIntoConstraints = NO;
separatorLineView.backgroundColor = [theme separatorColor];
[self.visualEffectView.contentView addSubview:separatorLineView];
[self.visualEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[separatorLineView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(separatorLineView)]];
[self.visualEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[separatorLineView(lineHeight)]"
options:0
metrics:@{ @"lineHeight" : @([[UIScreen mainScreen] scale] / 4) }
views:NSDictionaryOfVariableBindings(separatorLineView)]];
self.checkoutButton = [BUYCheckoutButton buttonWithType:UIButtonTypeCustom];
self.checkoutButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.checkoutButton setTheme:self.theme];
[self.checkoutButton setTitle:@"Checkout" forState:UIControlStateNormal];
self.checkoutButton.layer.cornerRadius = 5;
[self.visualEffectView.contentView addSubview:self.checkoutButton];
BUYPaymentButtonType buttonType = showApplePaySetup ? BUYPaymentButtonTypeSetup : BUYPaymentButtonTypeBuy;
self.buyPaymentButton = [BUYPaymentButton buttonWithType:buttonType style:[self.theme paymentButtonStyle]];
self.buyPaymentButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.visualEffectView.contentView addSubview:self.buyPaymentButton];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_checkoutButton, _buyPaymentButton);
self.applePayLayoutConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_checkoutButton]-[_buyPaymentButton(==_checkoutButton)]-|"
options:0
metrics:nil
views:viewsDictionary];
[self addConstraints:self.applePayLayoutConstraints];
[NSLayoutConstraint deactivateConstraints:self.applePayLayoutConstraints];
self.checkoutLayoutConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_checkoutButton]-|"
options:0
metrics:nil
views:viewsDictionary];
[self addConstraints:self.checkoutLayoutConstraints];
[NSLayoutConstraint deactivateConstraints:self.checkoutLayoutConstraints];
NSDictionary *metricsDictionary = @{ @"buttonHeight" : @(kBuyCheckoutButtonHeight) };
[self.visualEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_checkoutButton(buttonHeight)]-|"
options:0
metrics:metricsDictionary
views:viewsDictionary]];
[self.visualEffectView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_buyPaymentButton(==_checkoutButton)]-|"
options:0
metrics:nil
views:viewsDictionary]];
}
return self;
}
- (void)setApplePayButtonVisible:(BOOL)isApplePayAvailable
{
self.buyPaymentButton.hidden = !isApplePayAvailable;
if (isApplePayAvailable) {
[NSLayoutConstraint deactivateConstraints:self.checkoutLayoutConstraints];
[NSLayoutConstraint activateConstraints:self.applePayLayoutConstraints];
} else {
[NSLayoutConstraint deactivateConstraints:self.applePayLayoutConstraints];
[NSLayoutConstraint activateConstraints:self.checkoutLayoutConstraints];
}
}
- (void)tintColorDidChange
{
[super tintColorDidChange];
self.checkoutButton.backgroundColor = self.tintColor;
}
- (void)updateButtonsForProductVariant:(BUYProductVariant *)productVariant {
self.checkoutButton.enabled = productVariant.available;
self.checkoutButton.alpha = productVariant.available ? 1.0f : 0.5f;
self.buyPaymentButton.enabled = productVariant.available;
self.buyPaymentButton.alpha = productVariant.available ? 1.0f : 0.5f;
}
@end
......@@ -72,11 +72,6 @@
#import "BUYShopifyErrorCodes.h"
#import "BUYPaymentToken.h"
#import "BUYPaymentButton.h"
#import "BUYProductViewController.h"
#import "BUYStoreViewController.h"
#import "BUYTheme.h"
#import "BUYViewController.h"
#import "NSArray+BUYAdditions.h"
#import "NSDateFormatter+BUYAdditions.h"
......
//
// BUYStoreController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import WebKit;
#import "BUYLineItem.h"
#import "BUYProduct.h"
#import "BUYProductVariant.h"
#import "BUYStoreViewController.h"
#import "BUYError.h"
#import "BUYOrder.h"
#import "BUYShopifyErrorCodes.h"
@interface BUYStoreViewController () <WKNavigationDelegate, WKScriptMessageHandler>
@end
@implementation BUYStoreViewController {
NSURL *_url;
WKWebView *_webView;
UIBarButtonItem *_backButton;
UIBarButtonItem *_forwardButton;
BOOL _skippingAppCheckout;
NSURLRequest *_checkoutRequest;
}
@dynamic delegate;
- (instancetype)initWithClient:(BUYClient *)client url:(NSURL *)url
{
self = [super initWithClient:client];
if (self) {
_url = url;
}
return self;
}
- (instancetype)initWithClient:(BUYClient *)client
{
self = [super initWithClient:client];
if (self) {
_url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", client.shopDomain]];
}
return self;
}
- (void)loadView
{
WKWebViewConfiguration *configuration = [self webViewConfiguration];
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
_webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
_webView.navigationDelegate = self;
self.view = _webView;
_backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:_webView action:@selector(goBack)];
_forwardButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"forward"] style:UIBarButtonItemStylePlain target:_webView action:@selector(goForward)];
UIBarButtonItem *shareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(shareTapped)];
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
self.toolbarItems = @[_backButton, flexible, _forwardButton, flexible, shareButton, flexible, flexible, flexible];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[_webView loadRequest:[NSURLRequest requestWithURL:_url]];
[self updateButtons];
}
#pragma mark - Button Presses
- (void)updateButtons
{
_backButton.enabled = [_webView canGoBack];
_forwardButton.enabled = [_webView canGoForward];
}
- (void)shareTapped
{
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[_webView.URL] applicationActivities:nil];
activityViewController.excludedActivityTypes = @[UIActivityTypeAddToReadingList, UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeSaveToCameraRoll];
[self presentViewController:activityViewController animated:YES completion:nil];
}
#pragma mark - Web View Navigation Delegate Methods
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString *currentUrlString = [[[navigationAction request] URL] absoluteString];
BOOL checkoutLink = [currentUrlString containsString:@"/checkout"] || [currentUrlString containsString:@"/sessions"];
BOOL thankYouPage = [currentUrlString containsString:@"thank_you"];
if (checkoutLink && thankYouPage == NO) {
if (_skippingAppCheckout) {
decisionHandler(WKNavigationActionPolicyAllow);
}
else {
decisionHandler(WKNavigationActionPolicyCancel);
[self presentCheckoutMethodSelectionMenuWithCheckoutRequest:[navigationAction request]];
}
}
else {
_skippingAppCheckout = NO;
decisionHandler(WKNavigationActionPolicyAllow);
}
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
[self updateButtons];
}
- (void)reloadHomePage
{
[_webView loadRequest:[NSURLRequest requestWithURL:_url]];
}
#pragma mark - Checkout Methods
- (void)presentCheckoutMethodSelectionMenuWithCheckoutRequest:(NSURLRequest *)request
{
_checkoutRequest = request;
if ([self.delegate respondsToSelector:@selector(controller:shouldProceedWithCheckoutType:)]) {
[self.delegate controller:self shouldProceedWithCheckoutType:^(BUYCheckoutType type) {
switch (type) {
case BUYCheckoutTypeNormal:
[self checkoutWithNormalCheckout];
break;
case BUYCheckoutTypeApplePay:
[self checkoutWithApplePay];
break;
default:
break;
}
}];
}
else {
[self checkoutWithNormalCheckout];
}
}
- (void)getProduct:(NSString *)productId withVariantId:(NSString *)variantId completion:(void (^)(BUYProductVariant *variant, NSError *error))completion;
{
[self.client getProductById:productId completion:^(BUYProduct *product, NSError *error) {
BUYProductVariant *selectedVariant = nil;
if (error == nil) {
for (BUYProductVariant *variant in product.variants) {
if ([variant.identifier isEqual:@([variantId longLongValue])]) {
selectedVariant = variant;
break;
}
}
}
else {
NSLog(@"Failed to fetch variant: %@", error);
}
completion(selectedVariant, error);
}];
}
#pragma mark - Checkout Selection Delegate Methods
- (void)checkoutWithApplePay
{
[_webView evaluateJavaScript:@"\
var cartRequest = new XMLHttpRequest();\
cartRequest.open(\"GET\", \"/cart.json\", false);\
cartRequest.onreadystatechange = function() {\
if (cartRequest.readyState == 4 && cartRequest.status == 200) {\
window.webkit.messageHandlers.nativeApp.postMessage(JSON.parse(cartRequest.responseText));\
}\
};\
cartRequest.send(null);"
completionHandler:^(id response, NSError *error) {
}];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
NSDictionary *json = message.body;
NSString *cartToken = json[@"token"];
if (cartToken) {
[self startCheckoutWithCartToken:cartToken];
}
else {
NSError *error = [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_CartFetchError userInfo:nil];
[self.delegate controller:self failedToCreateCheckout:error];
}
}
- (void)checkoutWithNormalCheckout
{
_skippingAppCheckout = YES;
[_webView loadRequest:_checkoutRequest];
}
#pragma mark - Checkout Completion Handling
- (void)checkoutCompleted:(BUYCheckout *)checkout status:(BUYStatus)status
{
if (status == BUYStatusComplete) {
[self.client getCheckout:checkout completion:^(BUYCheckout *updatedCheckout, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (updatedCheckout.order.statusURL) {
[_webView loadRequest:[NSURLRequest requestWithURL:updatedCheckout.order.statusURL]];
}
else {
NSLog(@"Couldn't redirect to thank you page: %@ (url: %@)", updatedCheckout, updatedCheckout.order.statusURL);
}
});
}];
}
else {
NSError *error = [NSError errorWithDomain:BUYShopifyError code:status userInfo:@{@"checkout": checkout}];
[self.delegate controller:self failedToCompleteCheckout:checkout withError:error];
}
}
#pragma mark - Web View Configuration
- (WKWebViewConfiguration *)webViewConfiguration
{
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = [self userContentConfiguration];
configuration.processPool = [self processPool];
return configuration;
}
- (WKProcessPool *)processPool
{
static WKProcessPool *pool = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
pool = [[WKProcessPool alloc] init];
});
return pool;
}
- (WKUserContentController *)userContentConfiguration
{
//Register our native bridge
WKUserContentController *contentController = [WKUserContentController new];
[contentController addScriptMessageHandler:self name:@"nativeApp"];
return contentController;
}
@end
//
// BUYViewController.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import AddressBook;
@import PassKit;
@import SafariServices;
#import "BUYApplePayAdditions.h"
#import "BUYCart.h"
#import "BUYClient.h"
#import "BUYViewController.h"
#import "BUYApplePayHelpers.h"
#import "BUYDiscount.h"
#import "BUYShop.h"
#import "BUYWebCheckoutPaymentProvider.h"
@interface BUYViewController () <SFSafariViewControllerDelegate>
@property (nonatomic, strong) BUYCheckout *checkout;
@property (nonatomic, strong) BUYApplePayHelpers *applePayHelper;
@property (nonatomic, assign) BOOL isLoadingShop;
@property (nonatomic, assign) PKPaymentAuthorizationStatus paymentAuthorizationStatus;
@end
@implementation BUYViewController
@synthesize client = _client;
- (instancetype)initWithClient:(BUYClient *)client
{
self = [super init];
if (self) {
self.client = client;
}
return self;
}
- (void)setClient:(BUYClient *)client
{
_client = client;
if (&PKPaymentNetworkDiscover != NULL) {
self.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkDiscover];
} else {
self.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa];
}
}
- (BUYClient*)client
{
if (_client == nil) {
NSLog(@"`BUYClient` has not been initialized. Please initialize BUYViewController with `initWithClient:` or set a `BUYClient` after Storyboard initialization");
}
return _client;
}
- (void)loadShopWithCallback:(void (^)(BOOL, NSError *))block
{
// fetch shop details for the currency and country codes
self.isLoadingShop = YES;
[self.client getShop:^(BUYShop *shop, NSError *error) {
if (error == nil) {
self.shop = shop;
}
self.isLoadingShop = NO;
if (block) block((error == nil), error);
}];
}
- (BOOL)canShowApplePaySetup
{
PKPassLibrary *passLibrary = [[PKPassLibrary alloc] init];
if (self.allowApplePaySetup == YES &&
// Check that it's running iOS 9.0 or above
[passLibrary respondsToSelector:@selector(canAddPaymentPassWithPrimaryAccountIdentifier:)] &&
// Check if the device can add a payment pass
[PKPaymentAuthorizationViewController canMakePayments] &&
// Check that Apple Pay is enabled for the merchant
[self.merchantId length]) {
return YES;
} else {
return NO;
}
}
- (BOOL)isApplePayAvailable
{
// checks if the client is setup to use Apple Pay
// checks if device hardware is capable of using Apple Pay
// checks if the device has a payment card setup
return (self.merchantId.length &&
[PKPaymentAuthorizationViewController canMakePayments] &&
[PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:self.supportedNetworks]);
}
- (BOOL)shouldShowApplePayButton {
return self.isApplePayAvailable || [self canShowApplePaySetup];
}
- (BOOL)shouldShowApplePaySetup
{
return self.isApplePayAvailable == NO && [self canShowApplePaySetup];
}
#pragma mark - Checkout Flow Methods
#pragma mark - Step 1 - Creating or updating a Checkout
- (void)startApplePayCheckout:(BUYCheckout *)checkout
{
// Default to the failure state, since cancelling a payment would not update the state and thus appear as a success
self.paymentAuthorizationStatus = PKPaymentAuthorizationStatusFailure;
/**
* To perform an Apple Pay checkout, we need both the BUYShop object, and a BUYCheckout
* We will download both in parallel, and continue with the checkout when they both succeed
*/
dispatch_group_t group = dispatch_group_create();
__block NSError *checkoutError = nil;
// download the shop
if (self.shop == nil) {
dispatch_group_enter(group);
[self loadShopWithCallback:^(BOOL success, NSError *error) {
if (error) {
checkoutError = error;
if ([self.delegate respondsToSelector:@selector(controllerFailedToStartApplePayProcess:)]) {
[self.delegate controllerFailedToStartApplePayProcess:self];
}
}
dispatch_group_leave(group);
}];
}
// create the checkout on Shopify
dispatch_group_enter(group);
[self handleCheckout:checkout completion:^(BUYCheckout *checkout, NSError *error) {
if (error) {
checkoutError = error;
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
else {
self.checkout = checkout;
}
dispatch_group_leave(group);
}];
// When we have both the shop and checkout, we can request the payment with Apple Pay
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (self.checkout && self.shop) {
if ([self.delegate respondsToSelector:@selector(controllerWillCheckoutViaApplePay:)]) {
[self.delegate controllerWillCheckoutViaApplePay:self];
}
self.applePayHelper = [[BUYApplePayHelpers alloc] initWithClient:self.client checkout:self.checkout shop:self.shop];
[self requestPayment];
}
else {
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:checkoutError];
}
}
});
}
- (void)startWebCheckout:(BUYCheckout *)checkout
{
[self handleCheckout:checkout completion:^(BUYCheckout *checkout, NSError *error) {
[self postCheckoutCompletion:checkout error:error];
}];
}
- (void)postCheckoutCompletion:(BUYCheckout *)checkout error:(NSError *)error
{
if (error == nil) {
self.checkout = checkout;
if ([self.delegate respondsToSelector:@selector(controllerWillCheckoutViaWeb:)]) {
[self.delegate controllerWillCheckoutViaWeb:self];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveCallbackURLNotification:) name:BUYSafariCallbackURLNotification object:nil];
[self openWebCheckout:checkout];
}
else {
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
}
- (void)handleCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)completion
{
if ([checkout.token length] > 0) {
[self.client updateCheckout:checkout completion:completion];
} else {
[self.client createCheckout:checkout completion:completion];
}
}
#pragma mark - Alternative Step 1 - Creating a Checkout using a Cart Token
- (void)startCheckoutWithCartToken:(NSString *)token
{
[self.client createCheckoutWithCartToken:token completion:^(BUYCheckout *checkout, NSError *error) {
self.applePayHelper = [[BUYApplePayHelpers alloc] initWithClient:self.client checkout:checkout];
[self handleCheckoutCompletion:checkout error:error];
}];
}
- (void)handleCheckoutCompletion:(BUYCheckout *)checkout error:(NSError *)error
{
if (checkout && error == nil) {
self.checkout = checkout;
[self requestPayment];
}
else {
if ([self.delegate respondsToSelector:@selector(controller:failedToCreateCheckout:)]) {
[self.delegate controller:self failedToCreateCheckout:error];
}
}
}
#pragma mark - Web Checkout
- (void)openWebCheckout:(BUYCheckout *)checkout
{
if ([SFSafariViewController class]) {
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:checkout.webCheckoutURL];
safariViewController.delegate = self;
[self presentViewController:safariViewController animated:YES completion:nil];
}
else {
[[UIApplication sharedApplication] openURL:checkout.webCheckoutURL];
}
}
#pragma mark - Step 2 - Requesting Payment using Apple Pay
- (void)requestPayment
{
//Step 2 - Request payment from the user by presenting an Apple Pay sheet
if (self.merchantId.length == 0) {
NSLog(@"Merchant ID must be configured to use Apple Pay");
if ([self.delegate respondsToSelector:@selector(controllerFailedToStartApplePayProcess:)]) {
[self.delegate controllerFailedToStartApplePayProcess:self];
}
return;
}
if (self.shop == nil) {
NSLog(@"loadShopWithCallback: must be called before starting an Apple Pay checkout");
if ([self.delegate respondsToSelector:@selector(controllerFailedToStartApplePayProcess:)]) {
[self.delegate controllerFailedToStartApplePayProcess:self];
}
return;
}
PKPaymentRequest *request = [self paymentRequest];
request.paymentSummaryItems = [self.checkout buy_summaryItemsWithShopName:self.shop.name];
PKPaymentAuthorizationViewController *controller = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
if (controller) {
controller.delegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
else {
if ([self.delegate respondsToSelector:@selector(controllerFailedToStartApplePayProcess:)]) {
[self.delegate controllerFailedToStartApplePayProcess:self];
}
}
}
- (void)checkoutCompleted:(BUYCheckout *)checkout status:(BUYStatus)status
{
if ([self.delegate respondsToSelector:@selector(controller:didCompleteCheckout:status:)]) {
[self.delegate controller:self didCompleteCheckout:checkout status:status];
}
}
#pragma mark - PKPaymentAuthorizationViewControllerDelegate Methods
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment completion:(void (^)(PKPaymentAuthorizationStatus status))completion
{
[self.applePayHelper paymentAuthorizationViewController:controller didAuthorizePayment:payment completion:^(PKPaymentAuthorizationStatus status) {
self.paymentAuthorizationStatus = status;
switch (status) {
case PKPaymentAuthorizationStatusFailure:
if ([self.delegate respondsToSelector:@selector(controller:failedToCompleteCheckout:withError:)]) {
[self.delegate controller:self failedToCompleteCheckout:self.checkout withError:self.applePayHelper.lastError];
}
break;
case PKPaymentAuthorizationStatusInvalidShippingPostalAddress:
if ([self.delegate respondsToSelector:@selector(controller:failedToUpdateCheckout:withError:)]) {
[self.delegate controller:self failedToUpdateCheckout:self.checkout withError:self.applePayHelper.lastError];
}
break;
default: {
if ([self.delegate respondsToSelector:@selector(controller:didCompleteCheckout:status:)]) {
BUYStatus buyStatus = (status == PKPaymentAuthorizationStatusSuccess) ? BUYStatusComplete : BUYStatusFailed;
[self.delegate controller:self didCompleteCheckout:self.checkout status:buyStatus];
}
}
break;
}
completion(status);
}];
}
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller
{
// The checkout is done at this point, it may have succeeded or failed. You are responsible for dealing with failure/success earlier in the steps.
[self dismissViewControllerAnimated:YES completion:^{
// If Apple Pay is dismissed with Cancel we need to clear the reservation time on the products in the checkout
if (self.paymentAuthorizationStatus != PKPaymentAuthorizationStatusSuccess) {
[self.client removeProductReservationsFromCheckout:self.checkout completion:^(BUYCheckout *checkout, NSError *error) {
self.checkout = checkout;
if ([self.delegate respondsToSelector:@selector(controller:didDismissApplePayControllerWithStatus:forCheckout:)]) {
[self.delegate controller:self didDismissApplePayControllerWithStatus:self.paymentAuthorizationStatus forCheckout:self.checkout];
}
}];
} else {
if ([self.delegate respondsToSelector:@selector(controller:didDismissApplePayControllerWithStatus:forCheckout:)]) {
[self.delegate controller:self didDismissApplePayControllerWithStatus:self.paymentAuthorizationStatus forCheckout:self.checkout];
}
}
}];
}
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingMethod:(nonnull PKShippingMethod *)shippingMethod completion:(nonnull void (^)(PKPaymentAuthorizationStatus, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
{
[self.applePayHelper paymentAuthorizationViewController:controller didSelectShippingMethod:shippingMethod completion:^(PKPaymentAuthorizationStatus status, NSArray<PKPaymentSummaryItem *> * _Nonnull summaryItems) {
if (status == PKPaymentAuthorizationStatusInvalidShippingPostalAddress) {
if ([self.delegate respondsToSelector:@selector(controller:failedToGetShippingRates:withError:)]) {
[self.delegate controller:self failedToGetShippingRates:self.checkout withError:self.applePayHelper.lastError];
}
}
completion(status, summaryItems);
}];
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingAddress:(ABRecordRef)address completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
{
[self.applePayHelper paymentAuthorizationViewController:controller didSelectShippingAddress:address completion:^(PKPaymentAuthorizationStatus status, NSArray<PKShippingMethod *> * _Nonnull shippingMethods, NSArray<PKPaymentSummaryItem *> * _Nonnull summaryItems) {
if (status == PKPaymentAuthorizationStatusInvalidShippingPostalAddress) {
if ([self.delegate respondsToSelector:@selector(controller:failedToUpdateCheckout:withError:)]) {
[self.delegate controller:self failedToUpdateCheckout:self.checkout withError:self.applePayHelper.lastError];
}
}
completion(status, shippingMethods, summaryItems);
}];
}
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingContact:(PKContact *)contact completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
{
[self.applePayHelper paymentAuthorizationViewController:controller didSelectShippingContact:contact completion:^(PKPaymentAuthorizationStatus status, NSArray<PKShippingMethod *> * _Nonnull shippingMethods, NSArray<PKPaymentSummaryItem *> * _Nonnull summaryItems) {
if (status == PKPaymentAuthorizationStatusInvalidShippingPostalAddress) {
if ([self.delegate respondsToSelector:@selector(controller:failedToUpdateCheckout:withError:)]) {
[self.delegate controller:self failedToUpdateCheckout:self.checkout withError:self.applePayHelper.lastError];
}
}
completion(status, shippingMethods, summaryItems);
}];
}
#pragma mark - Helpers
- (PKPaymentRequest *)paymentRequest
{
PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
NSString *merchantId = self.client.merchantId ? : self.merchantId;
#pragma GCC diagnostic pop
[paymentRequest setMerchantIdentifier:merchantId];
[paymentRequest setRequiredBillingAddressFields:PKAddressFieldAll];
[paymentRequest setRequiredShippingAddressFields:self.checkout.requiresShipping ? PKAddressFieldAll : PKAddressFieldEmail|PKAddressFieldPhone];
[paymentRequest setSupportedNetworks:self.supportedNetworks];
[paymentRequest setMerchantCapabilities:PKMerchantCapability3DS];
[paymentRequest setCountryCode:self.shop.country];
[paymentRequest setCurrencyCode:self.shop.currency];
return paymentRequest;
}
#pragma mark - Web Checkout delegate methods
- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller;
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:BUYSafariCallbackURLNotification object:nil];
if ([self.delegate respondsToSelector:@selector(controller:didDismissWebCheckout:)]) {
[self.delegate controller:self didDismissWebCheckout:self.checkout];
}
}
- (void)didReceiveCallbackURLNotification:(NSNotification *)notification
{
NSURL *url = notification.userInfo[BUYURLKey];
[self.client getCompletionStatusOfCheckoutURL:url completion:^(BUYStatus status, NSError *error) {
[self checkoutCompleted:_checkout status:status];
[[NSNotificationCenter defaultCenter] removeObserver:self name:BUYSafariCallbackURLNotification object:nil];
}];
if (self.presentedViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
+ (void)completeCheckoutFromLaunchURL:(NSURL *)url
{
[[NSNotificationCenter defaultCenter] postNotificationName:BUYSafariCallbackURLNotification object:nil userInfo:@{BUYURLKey: url}];
}
@end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment