diff --git a/.jazzy.yaml b/.jazzy.yaml index fc6e1630a0..d087c50219 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -1,7 +1,41 @@ -clean: true +module: Adyen author: Adyen author_url: https://adyen.com -github_url: https://github.com/Adyen +github_url: https://github.com/Adyen/adyen-ios + +output: Docs + +theme: fullwidth skip_undocumented: false hide_documentation_coverage: true -theme: fullwidth + +custom_categories: + - name: UI + children: + - CheckoutViewController + - CheckoutViewControllerDelegate + - AppearanceConfiguration + - name: Payment + children: + - Payment + - PaymentStatus + - name: Payment Request + children: + - PaymentRequest + - PaymentRequestDelegate + - PaymentRequestResult + - Error + - name: Payment Method + children: + - PaymentMethod + - PaymentDetails + - InputDetail + - InputType + - InputSelectItem + - name: Utilities + children: + - CardType + - CardValidator + - IBANSpecification + - IBANValidator + - IBANTextField diff --git a/Example/1-quick-integration-example/.swiftlint.yml b/.swiftlint.yml similarity index 73% rename from Example/1-quick-integration-example/.swiftlint.yml rename to .swiftlint.yml index cbcd8b8256..988103840a 100644 --- a/Example/1-quick-integration-example/.swiftlint.yml +++ b/.swiftlint.yml @@ -11,9 +11,8 @@ disabled_rules: - function_body_length - file_length included: - - ../../Adyen - - ../../Example - - ../../UnitTests + - Adyen + - Examples + - AdyenTests excluded: - Pods - - ../../Adyen/Core/Config.swift diff --git a/.travis.yml b/.travis.yml index 0fea8e5018..9208ad8a28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,16 @@ osx_image: xcode8.3 env: global: - - WORKSPACE="Example/1-quick-integration-example/ShoppingApp.xcworkspace" - - SCHEME="ShoppingApp" + - WORKSPACE="Adyen.xcworkspace" + - SCHEME="Adyen" - DESTINATION="platform=iOS Simulator,name=iPhone 7,OS=10.3" before_install: - gem install cocoapods - pod repo update - - (cd Example/1-quick-integration-example && pod install) + - pod install script: - - (cd Example/1-quick-integration-example && ./Pods/SwiftLint/swiftlint) + - ./Pods/SwiftLint/swiftlint - pod lib lint - xcodebuild test -workspace "${WORKSPACE}" -scheme "${SCHEME}" -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -destination "${DESTINATION}" | xcpretty -s && exit ${PIPESTATUS[0]} diff --git a/Adyen.podspec b/Adyen.podspec index e21ea48277..bd097fe516 100644 --- a/Adyen.podspec +++ b/Adyen.podspec @@ -1,6 +1,8 @@ +version = `agvtool vers -terse` + Pod::Spec.new do |s| s.name = 'Adyen' - s.version = File.read('VERSION') + s.version = version s.summary = "Adyen SDK for iOS" s.description = <<-DESC With Adyen SDK you can dynamically list all relevant payment methods for a specific transaction, so your shoppers can always pay with the method of their choice. The methods are listed based on the shopper's country, the transaction currency and amount. @@ -14,11 +16,10 @@ Pod::Spec.new do |s| s.ios.deployment_target = '9.0' s.frameworks = 'Foundation' - s.default_subspecs = 'Core', 'Cards', 'Ideal', 'UI' + s.default_subspecs = 'Core', 'Cards', 'Ideal', 'SEPADirectDebit', 'UI' s.subspec 'Core' do |plugin| plugin.source_files = 'Adyen/Core/**/*' - plugin.resources = ['VERSION'] end # Payment Methods @@ -46,6 +47,17 @@ Pod::Spec.new do |s| plugin.dependency 'Adyen/Core' end + s.subspec 'SEPADirectDebit' do |plugin| + plugin.source_files = 'Adyen/Plugins/SEPADirectDebit/**/*' + plugin.dependency 'Adyen/Core' + plugin.dependency 'Adyen/CoreUI' + plugin.resource_bundles = { + 'SEPADirectDebit' => [ + 'Adyen/Plugins/SEPADirectDebit/**/*.xib' + ] + } + end + # Internals s.subspec 'UI' do |plugin| plugin.source_files = 'Adyen/UI/**/*' @@ -55,7 +67,12 @@ Pod::Spec.new do |s| s.subspec 'CoreUI' do |plugin| plugin.source_files = 'Adyen/CoreUI/**/*.swift' - plugin.resources = ['Adyen/CoreUI/Assets/Media.xcassets'] + plugin.resource_bundles = { + 'CoreUI' => [ + 'Adyen/CoreUI/Assets/Media.xcassets', + 'Adyen/CoreUI/Assets/*.lproj/*.strings' + ] + } plugin.dependency 'Adyen/Core' end end diff --git a/Adyen.xcodeproj/project.pbxproj b/Adyen.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..fb9686f285 --- /dev/null +++ b/Adyen.xcodeproj/project.pbxproj @@ -0,0 +1,1463 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 53C0FEFC4B5CD9400E89E4CA /* Pods_AdyenTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */; }; + 7D7AD12FB4E950056731EEB6 /* Pods_Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */; }; + C3A02E02B25D9A9E913FA639 /* Pods_AdyenUIHost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */; }; + E20AD01A1EFAB0310065B70E /* Adyen.h in Headers */ = {isa = PBXBuildFile; fileRef = E20AD00C1EFAB0310065B70E /* Adyen.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E20AD0691EFAB0E00065B70E /* BasePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0241EFAB0E00065B70E /* BasePlugin.swift */; }; + E20AD06A1EFAB0E00065B70E /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0251EFAB0E00065B70E /* Currency.swift */; }; + E20AD06B1EFAB0E00065B70E /* CardBrandCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */; }; + E20AD06C1EFAB0E00065B70E /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0281EFAB0E00065B70E /* Error.swift */; }; + E20AD06D1EFAB0E00065B70E /* InputType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0291EFAB0E00065B70E /* InputType.swift */; }; + E20AD06E1EFAB0E00065B70E /* MethodRequiresPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */; }; + E20AD06F1EFAB0E00065B70E /* PaymentMethodType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */; }; + E20AD0701EFAB0E00065B70E /* PaymentRequestResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */; }; + E20AD0711EFAB0E00065B70E /* PaymentStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */; }; + E20AD0721EFAB0E00065B70E /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */; }; + E20AD0731EFAB0E00065B70E /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */; }; + E20AD0741EFAB0E00065B70E /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */; }; + E20AD0751EFAB0E00065B70E /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0321EFAB0E00065B70E /* StringExtensions.swift */; }; + E20AD0761EFAB0E00065B70E /* UIScreenExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */; }; + E20AD0771EFAB0E00065B70E /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0341EFAB0E00065B70E /* URLExtensions.swift */; }; + E20AD0781EFAB0E00065B70E /* InputDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0351EFAB0E00065B70E /* InputDetail.swift */; }; + E20AD0791EFAB0E00065B70E /* InputSelectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */; }; + E20AD07A1EFAB0E00065B70E /* InternalPaymentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */; }; + E20AD07B1EFAB0E00065B70E /* Payment.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0381EFAB0E00065B70E /* Payment.swift */; }; + E20AD07C1EFAB0E00065B70E /* PaymentDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */; }; + E20AD07D1EFAB0E00065B70E /* PaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */; }; + E20AD07F1EFAB0E00065B70E /* PaymentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */; }; + E20AD0801EFAB0E00065B70E /* PaymentServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */; }; + E20AD0811EFAB0E00065B70E /* PluginLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */; }; + E20AD0821EFAB0E00065B70E /* DeviceDependable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */; }; + E20AD0841EFAB0E00065B70E /* PaymentRequestDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */; }; + E20AD0851EFAB0E00065B70E /* RequiresFinalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */; }; + E20AD0871EFAB0E00065B70E /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0451EFAB0E00065B70E /* Version.swift */; }; + E20AD0891EFAB0E00065B70E /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0491EFAB0E00065B70E /* Media.xcassets */; }; + E20AD08A1EFAB0E00065B70E /* CheckoutButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */; }; + E20AD08B1EFAB0E00065B70E /* LoadingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */; }; + E20AD08C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */; }; + E20AD08D1EFAB0E00065B70E /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */; }; + E20AD08E1EFAB0E00065B70E /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */; }; + E20AD08F1EFAB0E00065B70E /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */; }; + E20AD0901EFAB0E00065B70E /* ApplePayDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */; }; + E20AD0911EFAB0E00065B70E /* ApplePayPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */; }; + E20AD0921EFAB0E00065B70E /* CardFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */; }; + E20AD0931EFAB0E00065B70E /* CardFormViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */; }; + E20AD0941EFAB0E00065B70E /* CardPaymentFieldManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */; }; + E20AD0951EFAB0E00065B70E /* CardType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0581EFAB0E00065B70E /* CardType.swift */; }; + E20AD0961EFAB0E00065B70E /* CardValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0591EFAB0E00065B70E /* CardValidator.swift */; }; + E20AD0971EFAB0E00065B70E /* CardsAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */; }; + E20AD0981EFAB0E00065B70E /* CardsDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */; }; + E20AD0991EFAB0E00065B70E /* CardsPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */; }; + E20AD09A1EFAB0E00065B70E /* CheckoutTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */; }; + E20AD09B1EFAB0E00065B70E /* IdealDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */; }; + E20AD09C1EFAB0E00065B70E /* IdealIssuerPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */; }; + E20AD09D1EFAB0E00065B70E /* IdealPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */; }; + E20AD09E1EFAB0E00065B70E /* CheckoutHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */; }; + E20AD09F1EFAB0E00065B70E /* CheckoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */; }; + E20AD0A01EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */; }; + E20AD0BD1EFAB1950065B70E /* CardValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */; }; + E20AD0BE1EFAB1950065B70E /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */; }; + E20AD0BF1EFAB1950065B70E /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */; }; + E20AD0C01EFAB1950065B70E /* CurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */; }; + E20AD0C11EFAB1950065B70E /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */; }; + E20AD0C21EFAB1950065B70E /* InputDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */; }; + E20AD0C31EFAB1950065B70E /* InputSelectItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */; }; + E20AD0C41EFAB1950065B70E /* PaymentDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */; }; + E20AD0C51EFAB1950065B70E /* PaymentMethodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */; }; + E20AD0C61EFAB1950065B70E /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */; }; + E20AD0C71EFAB1950065B70E /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */; }; + E20AD0C91EFAB1950065B70E /* PaymentMethodApplePay.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */; }; + E20AD0CA1EFAB1950065B70E /* PaymentMethodCard.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */; }; + E20AD0CB1EFAB1950065B70E /* PaymentMethodCardCvc.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */; }; + E20AD0CC1EFAB1950065B70E /* PaymentMethodIdeal.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */; }; + E20AD0CD1EFAB1950065B70E /* PaymentMethodKlarna.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */; }; + E20AD0CE1EFAB1950065B70E /* PaymentMethodPaypal.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */; }; + E20AD0CF1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */; }; + E20AD0D01EFAB1950065B70E /* PaymentMethodSepa.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */; }; + E20AD0D31EFAB1BF0065B70E /* JsonReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */; }; + E226F1491EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */; }; + E240E7531F0BC5600059FA0E /* UITableViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */; }; + E250E13F1F0E606000BFFF2F /* Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; }; + E250E1401F0E606000BFFF2F /* Adyen.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E255C4021F0103DF0075254F /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E255C4011F0103DF0075254F /* NavigationController.swift */; }; + E25A3FC11F0686F800679DCD /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F627661F063849005D8026 /* Localization.swift */; }; + E25C87A61F0B81FC00FF3EA0 /* PaymentMethodPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */; }; + E25C87A71F0B81FF00FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */; }; + E28562591F0FC06F0049E442 /* BundleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28562581F0FC06F0049E442 /* BundleExtensions.swift */; }; + E28562641F13BA5D0049E442 /* PaymentStatusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */; }; + E28A79991EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */; }; + E28A799C1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */; }; + E28A799D1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */; }; + E28A799F1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */; }; + E2A167C31F0E643A00A27E4A /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A167C21F0E643A00A27E4A /* Configuration.swift */; }; + E2A167C61F0E704100A27E4A /* Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; }; + E2B6207D1F0E5EA5001D4C27 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */; }; + E2B6207F1F0E5F0F001D4C27 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */; }; + E2BF6CCD1F0395670065E574 /* TestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CCC1F0395670065E574 /* TestCase.swift */; }; + E2BF6CCF1F0397060065E574 /* SEPADirectDebitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */; }; + E2BF6CD11F0397AC0065E574 /* XCUIElementQueryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */; }; + E2BF6CD31F03A8240065E574 /* CardsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD21F03A8240065E574 /* CardsTests.swift */; }; + E2BF6CD71F03CEF60065E574 /* IdealTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD61F03CEF60065E574 /* IdealTests.swift */; }; + E2E9D01E1F0389C80056E0AC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */; }; + E2E9D0201F0389C80056E0AC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2E9D01F1F0389C80056E0AC /* ViewController.swift */; }; + E2E9D0251F0389C80056E0AC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E2E9D0241F0389C80056E0AC /* Assets.xcassets */; }; + E2EE2E4B1F0141CD008DC96D /* IBANValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */; }; + E2EE2E541F026746008DC96D /* IBANSpecification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E511F026746008DC96D /* IBANSpecification.swift */; }; + E2EE2E551F026746008DC96D /* IBANTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E521F026746008DC96D /* IBANTextField.swift */; }; + E2EE2E561F026746008DC96D /* IBANValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E531F026746008DC96D /* IBANValidator.swift */; }; + E2F627681F06386C005D8026 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E2F627651F063842005D8026 /* Localizable.strings */; }; + E2F6276E1F06413B005D8026 /* UIPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6276D1F064127005D8026 /* UIPresentable.swift */; }; + E2F6276F1F06413D005D8026 /* PaymentMethodDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */; }; + E2F627701F064270005D8026 /* AppearanceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + E20AD0141EFAB0310065B70E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E20AD0001EFAB0310065B70E /* Project object */; + proxyType = 1; + remoteGlobalIDString = E20AD0081EFAB0310065B70E; + remoteInfo = Adyen; + }; + E250E1411F0E606000BFFF2F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E20AD0001EFAB0310065B70E /* Project object */; + proxyType = 1; + remoteGlobalIDString = E20AD0081EFAB0310065B70E; + remoteInfo = Adyen; + }; + E2BF6CC61F03952D0065E574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E20AD0001EFAB0310065B70E /* Project object */; + proxyType = 1; + remoteGlobalIDString = E2E9D01A1F0389C80056E0AC; + remoteInfo = AdyenUIHost; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + E250E1431F0E606000BFFF2F /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + E250E1401F0E606000BFFF2F /* Adyen.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adyen.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Adyen/Pods-Adyen.debug.xcconfig"; sourceTree = ""; }; + 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AdyenUIHost.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adyen.release.xcconfig"; path = "Pods/Target Support Files/Pods-Adyen/Pods-Adyen.release.xcconfig"; sourceTree = ""; }; + 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenUIHost.release.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost.release.xcconfig"; sourceTree = ""; }; + 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests.debug.xcconfig"; sourceTree = ""; }; + 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenUIHost.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost.debug.xcconfig"; sourceTree = ""; }; + B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AdyenTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E20AD0091EFAB0310065B70E /* Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E20AD00C1EFAB0310065B70E /* Adyen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Adyen.h; sourceTree = ""; }; + E20AD00D1EFAB0310065B70E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E20AD0121EFAB0310065B70E /* AdyenTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdyenTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E20AD0191EFAB0310065B70E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E20AD0241EFAB0E00065B70E /* BasePlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePlugin.swift; sourceTree = ""; }; + E20AD0251EFAB0E00065B70E /* Currency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Currency.swift; sourceTree = ""; }; + E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardBrandCode.swift; sourceTree = ""; }; + E20AD0281EFAB0E00065B70E /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; + E20AD0291EFAB0E00065B70E /* InputType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputType.swift; sourceTree = ""; }; + E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodRequiresPlugin.swift; sourceTree = ""; }; + E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodType.swift; sourceTree = ""; }; + E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequestResult.swift; sourceTree = ""; }; + E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentStatus.swift; sourceTree = ""; }; + E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; + E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; + E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; + E20AD0321EFAB0E00065B70E /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; + E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIScreenExtensions.swift; sourceTree = ""; }; + E20AD0341EFAB0E00065B70E /* URLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; }; + E20AD0351EFAB0E00065B70E /* InputDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputDetail.swift; sourceTree = ""; }; + E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputSelectItem.swift; sourceTree = ""; }; + E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InternalPaymentRequest.swift; sourceTree = ""; }; + E20AD0381EFAB0E00065B70E /* Payment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Payment.swift; sourceTree = ""; }; + E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentDetails.swift; sourceTree = ""; }; + E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethod.swift; sourceTree = ""; }; + E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequest.swift; sourceTree = ""; }; + E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentServer.swift; sourceTree = ""; }; + E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginLoader.swift; sourceTree = ""; }; + E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceDependable.swift; sourceTree = ""; }; + E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequestDelegate.swift; sourceTree = ""; }; + E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequiresFinalState.swift; sourceTree = ""; }; + E20AD0451EFAB0E00065B70E /* Version.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = ""; }; + E20AD0491EFAB0E00065B70E /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; + E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutButton.swift; sourceTree = ""; }; + E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingTableViewCell.swift; sourceTree = ""; }; + E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodTableViewCell.swift; sourceTree = ""; }; + E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; + E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; + E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; + E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplePayDetailsPresenter.swift; sourceTree = ""; }; + E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplePayPlugin.swift; sourceTree = ""; }; + E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardFormViewController.swift; sourceTree = ""; }; + E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CardFormViewController.xib; sourceTree = ""; }; + E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardPaymentFieldManager.swift; sourceTree = ""; }; + E20AD0581EFAB0E00065B70E /* CardType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardType.swift; sourceTree = ""; }; + E20AD0591EFAB0E00065B70E /* CardValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardValidator.swift; sourceTree = ""; }; + E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsAlertController.swift; sourceTree = ""; }; + E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsDetailsPresenter.swift; sourceTree = ""; }; + E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsPlugin.swift; sourceTree = ""; }; + E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutTextField.swift; sourceTree = ""; }; + E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealDetailsPresenter.swift; sourceTree = ""; }; + E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealIssuerPickerViewController.swift; sourceTree = ""; }; + E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealPlugin.swift; sourceTree = ""; }; + E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutHeaderView.swift; sourceTree = ""; }; + E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewController.swift; sourceTree = ""; }; + E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewControllerDelegate.swift; sourceTree = ""; }; + E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardValidatorTests.swift; sourceTree = ""; }; + E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionTests.swift; sourceTree = ""; }; + E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; }; + E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyTests.swift; sourceTree = ""; }; + E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionTests.swift; sourceTree = ""; }; + E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputDetailsTests.swift; sourceTree = ""; }; + E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputSelectItemTests.swift; sourceTree = ""; }; + E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentDetailsTests.swift; sourceTree = ""; }; + E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodTests.swift; sourceTree = ""; }; + E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; }; + E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; }; + E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodApplePay.json; sourceTree = ""; }; + E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCard.json; sourceTree = ""; }; + E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCardCvc.json; sourceTree = ""; }; + E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodIdeal.json; sourceTree = ""; }; + E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodKlarna.json; sourceTree = ""; }; + E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypal.json; sourceTree = ""; }; + E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypalRecurring.json; sourceTree = ""; }; + E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodSepa.json; sourceTree = ""; }; + E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JsonReader.swift; sourceTree = ""; }; + E20AD1E81EFBE7630065B70E /* AdyenCSE.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdyenCSE.framework; path = Carthage/Build/iOS/AdyenCSE.framework; sourceTree = ""; }; + E214EF681F0A2C41009A7E3A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + E214EF691F0A2C49009A7E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + E214EF6A1F0A2C51009A7E3A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitPlugin.swift; sourceTree = ""; }; + E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewControllerExtensions.swift; sourceTree = ""; }; + E255C4011F0103DF0075254F /* NavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; }; + E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodPickerViewControllerDelegate.swift; sourceTree = ""; }; + E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodPickerViewController.swift; sourceTree = ""; }; + E28562581F0FC06F0049E442 /* BundleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BundleExtensions.swift; sourceTree = ""; }; + E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentStatusTests.swift; sourceTree = ""; }; + E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitDetailsPresenter.swift; sourceTree = ""; }; + E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitFormViewController.swift; sourceTree = ""; }; + E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SEPADirectDebitFormViewController.xib; sourceTree = ""; }; + E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitFormViewControllerDelegate.swift; sourceTree = ""; }; + E28ECE001F065383004FCEA6 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + E2A167C21F0E643A00A27E4A /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; + E2AB20EE1F0A31400006FF2A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + E2AB20F01F0A65000006FF2A /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = ""; }; + E2AB20F11F0A650D0006FF2A /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; + E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdyenUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E2BF6CC51F03952D0065E574 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E2BF6CCC1F0395670065E574 /* TestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCase.swift; sourceTree = ""; }; + E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitTests.swift; sourceTree = ""; }; + E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCUIElementQueryExtensions.swift; sourceTree = ""; }; + E2BF6CD21F03A8240065E574 /* CardsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsTests.swift; sourceTree = ""; }; + E2BF6CD61F03CEF60065E574 /* IdealTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealTests.swift; sourceTree = ""; }; + E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdyenUIHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E2E9D01F1F0389C80056E0AC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + E2E9D0241F0389C80056E0AC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E2E9D0291F0389C80056E0AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANValidatorTests.swift; sourceTree = ""; }; + E2EE2E511F026746008DC96D /* IBANSpecification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANSpecification.swift; sourceTree = ""; }; + E2EE2E521F026746008DC96D /* IBANTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANTextField.swift; sourceTree = ""; }; + E2EE2E531F026746008DC96D /* IBANValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANValidator.swift; sourceTree = ""; }; + E2F627641F063842005D8026 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + E2F627661F063849005D8026 /* Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = ""; }; + E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfiguration.swift; sourceTree = ""; }; + E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodDetailsPresenter.swift; sourceTree = ""; }; + E2F6276D1F064127005D8026 /* UIPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIPresentable.swift; sourceTree = ""; }; + EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E20AD0051EFAB0310065B70E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7D7AD12FB4E950056731EEB6 /* Pods_Adyen.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E20AD00F1EFAB0310065B70E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E2A167C61F0E704100A27E4A /* Adyen.framework in Frameworks */, + 53C0FEFC4B5CD9400E89E4CA /* Pods_AdyenTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2BF6CBE1F03952C0065E574 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2E9D0181F0389C80056E0AC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E250E13F1F0E606000BFFF2F /* Adyen.framework in Frameworks */, + C3A02E02B25D9A9E913FA639 /* Pods_AdyenUIHost.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2C63A3DBF353ABFDA95AC068 /* Pods */ = { + isa = PBXGroup; + children = ( + 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */, + 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */, + 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */, + EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */, + 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */, + 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + E20ACFFF1EFAB0310065B70E = { + isa = PBXGroup; + children = ( + E20AD00B1EFAB0310065B70E /* Adyen */, + E20AD0161EFAB0310065B70E /* AdyenTests */, + E2BF6CC21F03952C0065E574 /* AdyenUITests */, + E2E9D01C1F0389C80056E0AC /* AdyenUIHost */, + E20AD00A1EFAB0310065B70E /* Products */, + E20AD1E71EFBE7630065B70E /* Frameworks */, + 2C63A3DBF353ABFDA95AC068 /* Pods */, + ); + sourceTree = ""; + }; + E20AD00A1EFAB0310065B70E /* Products */ = { + isa = PBXGroup; + children = ( + E20AD0091EFAB0310065B70E /* Adyen.framework */, + E20AD0121EFAB0310065B70E /* AdyenTests.xctest */, + E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */, + E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + E20AD00B1EFAB0310065B70E /* Adyen */ = { + isa = PBXGroup; + children = ( + E20AD0231EFAB0E00065B70E /* Core */, + E20AD0461EFAB0E00065B70E /* CoreUI */, + E20AD0621EFAB0E00065B70E /* UI */, + E20AD0501EFAB0E00065B70E /* Plugins */, + E20AD00C1EFAB0310065B70E /* Adyen.h */, + E20AD00D1EFAB0310065B70E /* Info.plist */, + ); + path = Adyen; + sourceTree = ""; + }; + E20AD0161EFAB0310065B70E /* AdyenTests */ = { + isa = PBXGroup; + children = ( + E20AD0A41EFAB1950065B70E /* Cards */, + E20AD0A61EFAB1950065B70E /* Core */, + E20AD0B11EFAB1950065B70E /* CoreUI */, + E2EE2E481F0141C3008DC96D /* Plugins */, + E20AD0B31EFAB1950065B70E /* Resources */, + E20AD0D11EFAB1BF0065B70E /* Helpers */, + E20AD0191EFAB0310065B70E /* Info.plist */, + ); + path = AdyenTests; + sourceTree = ""; + }; + E20AD0231EFAB0E00065B70E /* Core */ = { + isa = PBXGroup; + children = ( + E20AD0261EFAB0E00065B70E /* Enum */, + E20AD02E1EFAB0E00065B70E /* Extensions */, + E20AD03F1EFAB0E00065B70E /* Protocols */, + E20AD0241EFAB0E00065B70E /* BasePlugin.swift */, + E20AD0251EFAB0E00065B70E /* Currency.swift */, + E20AD0351EFAB0E00065B70E /* InputDetail.swift */, + E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */, + E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */, + E20AD0381EFAB0E00065B70E /* Payment.swift */, + E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */, + E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */, + E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */, + E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */, + E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */, + E20AD0451EFAB0E00065B70E /* Version.swift */, + ); + path = Core; + sourceTree = ""; + }; + E20AD0261EFAB0E00065B70E /* Enum */ = { + isa = PBXGroup; + children = ( + E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */, + E20AD0281EFAB0E00065B70E /* Error.swift */, + E20AD0291EFAB0E00065B70E /* InputType.swift */, + E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */, + E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */, + E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */, + E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */, + ); + path = Enum; + sourceTree = ""; + }; + E20AD02E1EFAB0E00065B70E /* Extensions */ = { + isa = PBXGroup; + children = ( + E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */, + E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */, + E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */, + E20AD0321EFAB0E00065B70E /* StringExtensions.swift */, + E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */, + E20AD0341EFAB0E00065B70E /* URLExtensions.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + E20AD03F1EFAB0E00065B70E /* Protocols */ = { + isa = PBXGroup; + children = ( + E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */, + E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */, + E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */, + ); + path = Protocols; + sourceTree = ""; + }; + E20AD0461EFAB0E00065B70E /* CoreUI */ = { + isa = PBXGroup; + children = ( + E20AD0471EFAB0E00065B70E /* Assets */, + E2F6276B1F064127005D8026 /* Plugins */, + E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */, + E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */, + E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */, + E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */, + E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */, + E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */, + E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */, + E28562581F0FC06F0049E442 /* BundleExtensions.swift */, + E2F627661F063849005D8026 /* Localization.swift */, + ); + path = CoreUI; + sourceTree = ""; + }; + E20AD0471EFAB0E00065B70E /* Assets */ = { + isa = PBXGroup; + children = ( + E20AD0491EFAB0E00065B70E /* Media.xcassets */, + E2F627651F063842005D8026 /* Localizable.strings */, + ); + path = Assets; + sourceTree = ""; + }; + E20AD0501EFAB0E00065B70E /* Plugins */ = { + isa = PBXGroup; + children = ( + E20AD0511EFAB0E00065B70E /* ApplePay */, + E20AD0541EFAB0E00065B70E /* Cards */, + E20AD05E1EFAB0E00065B70E /* Ideal */, + E226F1471EFD0A36009E04C9 /* SEPADirectDebit */, + ); + path = Plugins; + sourceTree = ""; + }; + E20AD0511EFAB0E00065B70E /* ApplePay */ = { + isa = PBXGroup; + children = ( + E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */, + E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */, + ); + path = ApplePay; + sourceTree = ""; + }; + E20AD0541EFAB0E00065B70E /* Cards */ = { + isa = PBXGroup; + children = ( + E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */, + E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */, + E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */, + E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */, + E20AD0581EFAB0E00065B70E /* CardType.swift */, + E20AD0591EFAB0E00065B70E /* CardValidator.swift */, + E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */, + E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */, + E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */, + ); + path = Cards; + sourceTree = ""; + }; + E20AD05E1EFAB0E00065B70E /* Ideal */ = { + isa = PBXGroup; + children = ( + E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */, + E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */, + E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */, + ); + path = Ideal; + sourceTree = ""; + }; + E20AD0621EFAB0E00065B70E /* UI */ = { + isa = PBXGroup; + children = ( + E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */, + E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */, + E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */, + E255C4011F0103DF0075254F /* NavigationController.swift */, + E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */, + E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */, + E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */, + ); + path = UI; + sourceTree = ""; + }; + E20AD0A41EFAB1950065B70E /* Cards */ = { + isa = PBXGroup; + children = ( + E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */, + ); + path = Cards; + sourceTree = ""; + }; + E20AD0A61EFAB1950065B70E /* Core */ = { + isa = PBXGroup; + children = ( + E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */, + E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */, + E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */, + E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */, + E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */, + E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */, + E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */, + E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */, + E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */, + E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */, + E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */, + ); + path = Core; + sourceTree = ""; + }; + E20AD0B11EFAB1950065B70E /* CoreUI */ = { + isa = PBXGroup; + children = ( + ); + path = CoreUI; + sourceTree = ""; + }; + E20AD0B31EFAB1950065B70E /* Resources */ = { + isa = PBXGroup; + children = ( + E20AD0B41EFAB1950065B70E /* Json */, + ); + path = Resources; + sourceTree = ""; + }; + E20AD0B41EFAB1950065B70E /* Json */ = { + isa = PBXGroup; + children = ( + E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */, + E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */, + E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */, + E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */, + E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */, + E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */, + E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */, + E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */, + ); + path = Json; + sourceTree = ""; + }; + E20AD0D11EFAB1BF0065B70E /* Helpers */ = { + isa = PBXGroup; + children = ( + E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + E20AD1E71EFBE7630065B70E /* Frameworks */ = { + isa = PBXGroup; + children = ( + E20AD1E81EFBE7630065B70E /* AdyenCSE.framework */, + B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */, + D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */, + 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E226F1471EFD0A36009E04C9 /* SEPADirectDebit */ = { + isa = PBXGroup; + children = ( + E2EE2E501F026746008DC96D /* IBAN */, + E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */, + E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */, + E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */, + E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */, + E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */, + ); + path = SEPADirectDebit; + sourceTree = ""; + }; + E2BF6CC21F03952C0065E574 /* AdyenUITests */ = { + isa = PBXGroup; + children = ( + E2BF6CCB1F0395600065E574 /* Base */, + E2BF6CD21F03A8240065E574 /* CardsTests.swift */, + E2BF6CD61F03CEF60065E574 /* IdealTests.swift */, + E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */, + E2BF6CC51F03952D0065E574 /* Info.plist */, + ); + path = AdyenUITests; + sourceTree = ""; + }; + E2BF6CCB1F0395600065E574 /* Base */ = { + isa = PBXGroup; + children = ( + E2BF6CCC1F0395670065E574 /* TestCase.swift */, + E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */, + ); + path = Base; + sourceTree = ""; + }; + E2E9D01C1F0389C80056E0AC /* AdyenUIHost */ = { + isa = PBXGroup; + children = ( + E2A167C21F0E643A00A27E4A /* Configuration.swift */, + E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */, + E2E9D01F1F0389C80056E0AC /* ViewController.swift */, + E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */, + E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */, + E2E9D0241F0389C80056E0AC /* Assets.xcassets */, + E2E9D0291F0389C80056E0AC /* Info.plist */, + ); + path = AdyenUIHost; + sourceTree = ""; + }; + E2EE2E481F0141C3008DC96D /* Plugins */ = { + isa = PBXGroup; + children = ( + E2EE2E491F0141C3008DC96D /* SEPADirectDebit */, + ); + path = Plugins; + sourceTree = ""; + }; + E2EE2E491F0141C3008DC96D /* SEPADirectDebit */ = { + isa = PBXGroup; + children = ( + E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */, + ); + path = SEPADirectDebit; + sourceTree = ""; + }; + E2EE2E501F026746008DC96D /* IBAN */ = { + isa = PBXGroup; + children = ( + E2EE2E511F026746008DC96D /* IBANSpecification.swift */, + E2EE2E521F026746008DC96D /* IBANTextField.swift */, + E2EE2E531F026746008DC96D /* IBANValidator.swift */, + ); + path = IBAN; + sourceTree = ""; + }; + E2F6276B1F064127005D8026 /* Plugins */ = { + isa = PBXGroup; + children = ( + E2F6276D1F064127005D8026 /* UIPresentable.swift */, + E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */, + ); + path = Plugins; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + E20AD0061EFAB0310065B70E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E20AD01A1EFAB0310065B70E /* Adyen.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + E20AD0081EFAB0310065B70E /* Adyen */ = { + isa = PBXNativeTarget; + buildConfigurationList = E20AD01D1EFAB0310065B70E /* Build configuration list for PBXNativeTarget "Adyen" */; + buildPhases = ( + 6B95865FF45820DB15409BA1 /* [CP] Check Pods Manifest.lock */, + E20AD0041EFAB0310065B70E /* Sources */, + E20AD0051EFAB0310065B70E /* Frameworks */, + E20AD0061EFAB0310065B70E /* Headers */, + E20AD0071EFAB0310065B70E /* Resources */, + E226F1431EFCF50A009E04C9 /* SwiftLint */, + 02474A22ADD502EEE43DCD38 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Adyen; + productName = Adyen; + productReference = E20AD0091EFAB0310065B70E /* Adyen.framework */; + productType = "com.apple.product-type.framework"; + }; + E20AD0111EFAB0310065B70E /* AdyenTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E20AD0201EFAB0310065B70E /* Build configuration list for PBXNativeTarget "AdyenTests" */; + buildPhases = ( + FE27A79BD5717B7A94254E4D /* [CP] Check Pods Manifest.lock */, + E20AD00E1EFAB0310065B70E /* Sources */, + E20AD00F1EFAB0310065B70E /* Frameworks */, + E20AD0101EFAB0310065B70E /* Resources */, + B2D23B80357D0CC2DABA91CB /* [CP] Embed Pods Frameworks */, + 8DAFF072F5EADA4FC2A33B45 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + E20AD0151EFAB0310065B70E /* PBXTargetDependency */, + ); + name = AdyenTests; + productName = AdyenTests; + productReference = E20AD0121EFAB0310065B70E /* AdyenTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E2BF6CC01F03952C0065E574 /* AdyenUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E2BF6CC81F03952D0065E574 /* Build configuration list for PBXNativeTarget "AdyenUITests" */; + buildPhases = ( + E2BF6CBD1F03952C0065E574 /* Sources */, + E2BF6CBE1F03952C0065E574 /* Frameworks */, + E2BF6CBF1F03952C0065E574 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E2BF6CC71F03952D0065E574 /* PBXTargetDependency */, + ); + name = AdyenUITests; + productName = AdyenUITests; + productReference = E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + E2E9D01A1F0389C80056E0AC /* AdyenUIHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = E2E9D02C1F0389C80056E0AC /* Build configuration list for PBXNativeTarget "AdyenUIHost" */; + buildPhases = ( + B07087D0BC32240A0F60E2AC /* [CP] Check Pods Manifest.lock */, + E2E9D0171F0389C80056E0AC /* Sources */, + E2E9D0181F0389C80056E0AC /* Frameworks */, + E2E9D0191F0389C80056E0AC /* Resources */, + 2DC1652936EDFD1499FBF286 /* [CP] Embed Pods Frameworks */, + 6F9EB542D6DFC7ED0AD003A8 /* [CP] Copy Pods Resources */, + E250E1431F0E606000BFFF2F /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E250E1421F0E606000BFFF2F /* PBXTargetDependency */, + ); + name = AdyenUIHost; + productName = AdyenUIHost; + productReference = E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E20AD0001EFAB0310065B70E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = Adyen; + TargetAttributes = { + E20AD0081EFAB0310065B70E = { + CreatedOnToolsVersion = 8.3.3; + DevelopmentTeam = B2NYSS5932; + ProvisioningStyle = Manual; + }; + E20AD0111EFAB0310065B70E = { + CreatedOnToolsVersion = 8.3.3; + ProvisioningStyle = Manual; + }; + E2BF6CC01F03952C0065E574 = { + CreatedOnToolsVersion = 8.3.3; + ProvisioningStyle = Automatic; + TestTargetID = E2E9D01A1F0389C80056E0AC; + }; + E2E9D01A1F0389C80056E0AC = { + CreatedOnToolsVersion = 8.3.3; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = E20AD0031EFAB0310065B70E /* Build configuration list for PBXProject "Adyen" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + nl, + fr, + de, + es, + it, + pt, + sv, + ); + mainGroup = E20ACFFF1EFAB0310065B70E; + productRefGroup = E20AD00A1EFAB0310065B70E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E20AD0081EFAB0310065B70E /* Adyen */, + E20AD0111EFAB0310065B70E /* AdyenTests */, + E2BF6CC01F03952C0065E574 /* AdyenUITests */, + E2E9D01A1F0389C80056E0AC /* AdyenUIHost */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E20AD0071EFAB0310065B70E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E28A799D1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib in Resources */, + E2F627681F06386C005D8026 /* Localizable.strings in Resources */, + E20AD0931EFAB0E00065B70E /* CardFormViewController.xib in Resources */, + E20AD0891EFAB0E00065B70E /* Media.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E20AD0101EFAB0310065B70E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E20AD0CF1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json in Resources */, + E20AD0CD1EFAB1950065B70E /* PaymentMethodKlarna.json in Resources */, + E20AD0C91EFAB1950065B70E /* PaymentMethodApplePay.json in Resources */, + E20AD0CC1EFAB1950065B70E /* PaymentMethodIdeal.json in Resources */, + E20AD0CA1EFAB1950065B70E /* PaymentMethodCard.json in Resources */, + E20AD0CE1EFAB1950065B70E /* PaymentMethodPaypal.json in Resources */, + E20AD0D01EFAB1950065B70E /* PaymentMethodSepa.json in Resources */, + E20AD0CB1EFAB1950065B70E /* PaymentMethodCardCvc.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2BF6CBF1F03952C0065E574 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2E9D0191F0389C80056E0AC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E2B6207F1F0E5F0F001D4C27 /* LaunchScreen.storyboard in Resources */, + E2E9D0251F0389C80056E0AC /* Assets.xcassets in Resources */, + E2B6207D1F0E5EA5001D4C27 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 02474A22ADD502EEE43DCD38 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Adyen/Pods-Adyen-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 2DC1652936EDFD1499FBF286 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 6B95865FF45820DB15409BA1 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 6F9EB542D6DFC7ED0AD003A8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8DAFF072F5EADA4FC2A33B45 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B07087D0BC32240A0F60E2AC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + B2D23B80357D0CC2DABA91CB /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + E226F1431EFCF50A009E04C9 /* SwiftLint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = SwiftLint; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\""; + }; + FE27A79BD5717B7A94254E4D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E20AD0041EFAB0310065B70E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E2F627701F064270005D8026 /* AppearanceConfiguration.swift in Sources */, + E20AD0911EFAB0E00065B70E /* ApplePayPlugin.swift in Sources */, + E2F6276E1F06413B005D8026 /* UIPresentable.swift in Sources */, + E20AD0711EFAB0E00065B70E /* PaymentStatus.swift in Sources */, + E20AD0941EFAB0E00065B70E /* CardPaymentFieldManager.swift in Sources */, + E226F1491EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift in Sources */, + E20AD09B1EFAB0E00065B70E /* IdealDetailsPresenter.swift in Sources */, + E2EE2E541F026746008DC96D /* IBANSpecification.swift in Sources */, + E20AD08A1EFAB0E00065B70E /* CheckoutButton.swift in Sources */, + E20AD0921EFAB0E00065B70E /* CardFormViewController.swift in Sources */, + E20AD0721EFAB0E00065B70E /* ArrayExtensions.swift in Sources */, + E2F6276F1F06413D005D8026 /* PaymentMethodDetailsPresenter.swift in Sources */, + E20AD06C1EFAB0E00065B70E /* Error.swift in Sources */, + E20AD07D1EFAB0E00065B70E /* PaymentMethod.swift in Sources */, + E240E7531F0BC5600059FA0E /* UITableViewControllerExtensions.swift in Sources */, + E20AD06A1EFAB0E00065B70E /* Currency.swift in Sources */, + E20AD06F1EFAB0E00065B70E /* PaymentMethodType.swift in Sources */, + E20AD0731EFAB0E00065B70E /* BoolExtensions.swift in Sources */, + E20AD0701EFAB0E00065B70E /* PaymentRequestResult.swift in Sources */, + E28A799C1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift in Sources */, + E20AD07C1EFAB0E00065B70E /* PaymentDetails.swift in Sources */, + E20AD0791EFAB0E00065B70E /* InputSelectItem.swift in Sources */, + E20AD0811EFAB0E00065B70E /* PluginLoader.swift in Sources */, + E20AD0771EFAB0E00065B70E /* URLExtensions.swift in Sources */, + E20AD09D1EFAB0E00065B70E /* IdealPlugin.swift in Sources */, + E20AD0951EFAB0E00065B70E /* CardType.swift in Sources */, + E20AD0971EFAB0E00065B70E /* CardsAlertController.swift in Sources */, + E20AD0801EFAB0E00065B70E /* PaymentServer.swift in Sources */, + E25C87A71F0B81FF00FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift in Sources */, + E28A799F1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift in Sources */, + E20AD09C1EFAB0E00065B70E /* IdealIssuerPickerViewController.swift in Sources */, + E20AD0691EFAB0E00065B70E /* BasePlugin.swift in Sources */, + E20AD0991EFAB0E00065B70E /* CardsPlugin.swift in Sources */, + E20AD06D1EFAB0E00065B70E /* InputType.swift in Sources */, + E20AD0841EFAB0E00065B70E /* PaymentRequestDelegate.swift in Sources */, + E20AD07A1EFAB0E00065B70E /* InternalPaymentRequest.swift in Sources */, + E28A79991EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift in Sources */, + E20AD06B1EFAB0E00065B70E /* CardBrandCode.swift in Sources */, + E20AD06E1EFAB0E00065B70E /* MethodRequiresPlugin.swift in Sources */, + E20AD0901EFAB0E00065B70E /* ApplePayDetailsPresenter.swift in Sources */, + E20AD0761EFAB0E00065B70E /* UIScreenExtensions.swift in Sources */, + E20AD0751EFAB0E00065B70E /* StringExtensions.swift in Sources */, + E20AD0961EFAB0E00065B70E /* CardValidator.swift in Sources */, + E20AD0981EFAB0E00065B70E /* CardsDetailsPresenter.swift in Sources */, + E2EE2E551F026746008DC96D /* IBANTextField.swift in Sources */, + E20AD0821EFAB0E00065B70E /* DeviceDependable.swift in Sources */, + E20AD07B1EFAB0E00065B70E /* Payment.swift in Sources */, + E28562591F0FC06F0049E442 /* BundleExtensions.swift in Sources */, + E20AD08E1EFAB0E00065B70E /* UIImageExtensions.swift in Sources */, + E20AD09F1EFAB0E00065B70E /* CheckoutViewController.swift in Sources */, + E20AD07F1EFAB0E00065B70E /* PaymentRequest.swift in Sources */, + E20AD09E1EFAB0E00065B70E /* CheckoutHeaderView.swift in Sources */, + E20AD0871EFAB0E00065B70E /* Version.swift in Sources */, + E20AD08D1EFAB0E00065B70E /* UIColorExtensions.swift in Sources */, + E255C4021F0103DF0075254F /* NavigationController.swift in Sources */, + E25A3FC11F0686F800679DCD /* Localization.swift in Sources */, + E20AD08B1EFAB0E00065B70E /* LoadingTableViewCell.swift in Sources */, + E20AD0A01EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift in Sources */, + E25C87A61F0B81FC00FF3EA0 /* PaymentMethodPickerViewController.swift in Sources */, + E20AD08C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift in Sources */, + E20AD0741EFAB0E00065B70E /* DictionaryExtensions.swift in Sources */, + E20AD0781EFAB0E00065B70E /* InputDetail.swift in Sources */, + E20AD08F1EFAB0E00065B70E /* UIImageViewExtensions.swift in Sources */, + E20AD0851EFAB0E00065B70E /* RequiresFinalState.swift in Sources */, + E2EE2E561F026746008DC96D /* IBANValidator.swift in Sources */, + E20AD09A1EFAB0E00065B70E /* CheckoutTextField.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E20AD00E1EFAB0310065B70E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E20AD0C21EFAB1950065B70E /* InputDetailsTests.swift in Sources */, + E20AD0BD1EFAB1950065B70E /* CardValidatorTests.swift in Sources */, + E20AD0D31EFAB1BF0065B70E /* JsonReader.swift in Sources */, + E20AD0C61EFAB1950065B70E /* StringExtensionsTests.swift in Sources */, + E28562641F13BA5D0049E442 /* PaymentStatusTests.swift in Sources */, + E20AD0C01EFAB1950065B70E /* CurrencyTests.swift in Sources */, + E20AD0C71EFAB1950065B70E /* URLExtensionsTests.swift in Sources */, + E20AD0C41EFAB1950065B70E /* PaymentDetailsTests.swift in Sources */, + E20AD0C11EFAB1950065B70E /* DictionaryExtensionTests.swift in Sources */, + E20AD0BE1EFAB1950065B70E /* ArrayExtensionTests.swift in Sources */, + E20AD0C51EFAB1950065B70E /* PaymentMethodTests.swift in Sources */, + E20AD0BF1EFAB1950065B70E /* BoolExtensionsTests.swift in Sources */, + E2EE2E4B1F0141CD008DC96D /* IBANValidatorTests.swift in Sources */, + E20AD0C31EFAB1950065B70E /* InputSelectItemTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2BF6CBD1F03952C0065E574 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E2BF6CCF1F0397060065E574 /* SEPADirectDebitTests.swift in Sources */, + E2BF6CD71F03CEF60065E574 /* IdealTests.swift in Sources */, + E2BF6CD11F0397AC0065E574 /* XCUIElementQueryExtensions.swift in Sources */, + E2BF6CCD1F0395670065E574 /* TestCase.swift in Sources */, + E2BF6CD31F03A8240065E574 /* CardsTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2E9D0171F0389C80056E0AC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E2A167C31F0E643A00A27E4A /* Configuration.swift in Sources */, + E2E9D0201F0389C80056E0AC /* ViewController.swift in Sources */, + E2E9D01E1F0389C80056E0AC /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E20AD0151EFAB0310065B70E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E20AD0081EFAB0310065B70E /* Adyen */; + targetProxy = E20AD0141EFAB0310065B70E /* PBXContainerItemProxy */; + }; + E250E1421F0E606000BFFF2F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E20AD0081EFAB0310065B70E /* Adyen */; + targetProxy = E250E1411F0E606000BFFF2F /* PBXContainerItemProxy */; + }; + E2BF6CC71F03952D0065E574 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E2E9D01A1F0389C80056E0AC /* AdyenUIHost */; + targetProxy = E2BF6CC61F03952D0065E574 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + E2F627651F063842005D8026 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + E2F627641F063842005D8026 /* en */, + E28ECE001F065383004FCEA6 /* nl */, + E214EF681F0A2C41009A7E3A /* fr */, + E214EF691F0A2C49009A7E3A /* de */, + E214EF6A1F0A2C51009A7E3A /* es */, + E2AB20EE1F0A31400006FF2A /* it */, + E2AB20F01F0A65000006FF2A /* pt */, + E2AB20F11F0A650D0006FF2A /* sv */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + E20AD01B1EFAB0310065B70E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1.4.0; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E20AD01C1EFAB0310065B70E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1.4.0; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + E20AD01E1EFAB0310065B70E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */; + buildSettings = { + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1.4.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Adyen/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Adyen; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + E20AD01F1EFAB0310065B70E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */; + buildSettings = { + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1.4.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Adyen/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Adyen; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + E20AD0211EFAB0310065B70E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */; + buildSettings = { + INFOPLIST_FILE = AdyenTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + E20AD0221EFAB0310065B70E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */; + buildSettings = { + INFOPLIST_FILE = AdyenTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + E2BF6CC91F03952D0065E574 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = AdyenUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AdyenUIHost; + }; + name = Debug; + }; + E2BF6CCA1F03952D0065E574 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = AdyenUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = AdyenUIHost; + }; + name = Release; + }; + E2E9D02A1F0389C80056E0AC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AdyenUIHost/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUIHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + E2E9D02B1F0389C80056E0AC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AdyenUIHost/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUIHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E20AD0031EFAB0310065B70E /* Build configuration list for PBXProject "Adyen" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E20AD01B1EFAB0310065B70E /* Debug */, + E20AD01C1EFAB0310065B70E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E20AD01D1EFAB0310065B70E /* Build configuration list for PBXNativeTarget "Adyen" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E20AD01E1EFAB0310065B70E /* Debug */, + E20AD01F1EFAB0310065B70E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E20AD0201EFAB0310065B70E /* Build configuration list for PBXNativeTarget "AdyenTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E20AD0211EFAB0310065B70E /* Debug */, + E20AD0221EFAB0310065B70E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E2BF6CC81F03952D0065E574 /* Build configuration list for PBXNativeTarget "AdyenUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E2BF6CC91F03952D0065E574 /* Debug */, + E2BF6CCA1F03952D0065E574 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E2E9D02C1F0389C80056E0AC /* Build configuration list for PBXNativeTarget "AdyenUIHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E2E9D02A1F0389C80056E0AC /* Debug */, + E2E9D02B1F0389C80056E0AC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E20AD0001EFAB0310065B70E /* Project object */; +} diff --git a/Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 71% rename from Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 66e100c0e5..9177a9816f 100644 --- a/Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:Adyen.xcodeproj"> diff --git a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme b/Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme similarity index 60% rename from Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme rename to Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme index 0502f10e27..104ef93850 100644 --- a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme +++ b/Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme @@ -14,10 +14,10 @@ buildForAnalyzing = "YES"> + BlueprintIdentifier = "E20AD0081EFAB0310065B70E" + BuildableName = "Adyen.framework" + BlueprintName = "Adyen" + ReferencedContainer = "container:Adyen.xcodeproj"> @@ -32,30 +32,20 @@ skipped = "NO"> - - - - + ReferencedContainer = "container:Adyen.xcodeproj"> + BlueprintIdentifier = "E20AD0081EFAB0310065B70E" + BuildableName = "Adyen.framework" + BlueprintName = "Adyen" + ReferencedContainer = "container:Adyen.xcodeproj"> @@ -71,16 +61,15 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> - + + BlueprintIdentifier = "E20AD0081EFAB0310065B70E" + BuildableName = "Adyen.framework" + BlueprintName = "Adyen" + ReferencedContainer = "container:Adyen.xcodeproj"> - + @@ -90,16 +79,15 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - + + BlueprintIdentifier = "E20AD0081EFAB0310065B70E" + BuildableName = "Adyen.framework" + BlueprintName = "Adyen" + ReferencedContainer = "container:Adyen.xcodeproj"> - + diff --git a/Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata b/Adyen.xcworkspace/contents.xcworkspacedata similarity index 80% rename from Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata rename to Adyen.xcworkspace/contents.xcworkspacedata index fea1c60fe1..9b11c9bbef 100644 --- a/Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata +++ b/Adyen.xcworkspace/contents.xcworkspacedata @@ -2,7 +2,7 @@ + location = "group:Adyen.xcodeproj"> diff --git a/Adyen/Adyen.h b/Adyen/Adyen.h new file mode 100644 index 0000000000..5bd21cf92e --- /dev/null +++ b/Adyen/Adyen.h @@ -0,0 +1,13 @@ +// +// Copyright (c) 2017 Adyen B.V. +// +// This file is open source and available under the MIT license. See the LICENSE file for more info. +// + +#import + +//! Project version number for Adyen. +FOUNDATION_EXPORT double AdyenVersionNumber; + +//! Project version string for Adyen. +FOUNDATION_EXPORT const unsigned char AdyenVersionString[]; diff --git a/Adyen/Core/BasePlugin.swift b/Adyen/Core/BasePlugin.swift index e8faf8296f..f9e55be208 100644 --- a/Adyen/Core/BasePlugin.swift +++ b/Adyen/Core/BasePlugin.swift @@ -19,15 +19,6 @@ class BasePlugin: NSObject { return UIApplication.shared.keyWindow?.rootViewController } - var isRedirectType: Bool { - // Groupped methods are not redirects. - guard let method = self.method, method.members != nil else { - return false - } - - return method.inputDetails.count == 0 - } - public required override init() { super.init() } @@ -79,10 +70,6 @@ class BasePlugin: NSObject { return providedPaymentData } - func linnearFlow() -> Bool { - return false - } - func reset() { providedPaymentData = nil } diff --git a/Adyen/Core/Enum/Error.swift b/Adyen/Core/Enum/Error.swift index f35a71d956..4f725fadce 100644 --- a/Adyen/Core/Enum/Error.swift +++ b/Adyen/Core/Enum/Error.swift @@ -25,6 +25,7 @@ public enum Error: Swift.Error { /// Payment was canceled. case canceled + } extension Error: LocalizedError { diff --git a/Adyen/Core/Extensions/ArrayExtensions.swift b/Adyen/Core/Extensions/ArrayExtensions.swift index 0ae80a6136..7d8814822d 100644 --- a/Adyen/Core/Extensions/ArrayExtensions.swift +++ b/Adyen/Core/Extensions/ArrayExtensions.swift @@ -37,3 +37,17 @@ internal extension Array { return groups } } + +internal extension Optional where Wrapped: Collection { + + /// Returns a boolean value indicating whether the wrapped collection is either nil or empty. + internal var isNilOrEmpty: Bool { + switch self { + case let .some(array): + return array.isEmpty + case .none: + return true + } + } + +} diff --git a/Adyen/Core/Extensions/StringExtensions.swift b/Adyen/Core/Extensions/StringExtensions.swift index 8371c7493c..968dfa3e49 100644 --- a/Adyen/Core/Extensions/StringExtensions.swift +++ b/Adyen/Core/Extensions/StringExtensions.swift @@ -38,4 +38,24 @@ extension String { let lowerBound = range.lowerBound < 0 ? 0 : range.lowerBound return substring(with: lowerIndex..<(index(lowerIndex, offsetBy: range.upperBound - lowerBound + 1, limitedBy: endIndex) ?? endIndex)) } + + /// Separates the string into groups of the given length. + /// + /// - Parameters: + /// - length: The maximum length of the groups the string should be separated in. + /// - separator: The separator to use inbetween the groups. + /// - Returns: A grouped string. + internal func grouped(length: Int, separator: String = " ") -> String { + let groups = stride(from: 0, to: characters.count, by: length).map { index -> String in + let startIndex = self.index(self.startIndex, offsetBy: index) + + let offset = min(length, self.distance(from: startIndex, to: self.endIndex)) + let endIndex = self.index(startIndex, offsetBy: offset) + + return self.substring(with: startIndex.. Bool { @@ -85,15 +89,7 @@ public final class PaymentMethod { } func requiresPaymentData() -> Bool { - return !inputDetails.isEmpty && plugin?.fullfilledFields() == nil - } - - func canProvideUI() -> Bool { - guard (plugin as? UIPresentable) != nil else { - return false - } - - return true + return inputDetails?.isEmpty == false && plugin?.fullfilledFields() == nil } func requiresURLAuth() -> Bool { @@ -107,7 +103,7 @@ public final class PaymentMethod { internal extension PaymentMethod { - convenience init?(info: [String: Any], logoBaseURL: String, oneClick: Bool = false) { + convenience init?(info: [String: Any], logoBaseURL: String, isOneClick: Bool) { guard let type = info["type"] as? String, let data = info["paymentMethodData"] as? String, @@ -117,7 +113,6 @@ internal extension PaymentMethod { } var displayName = name - if let cardInfo = info["card"] as? [String: Any], let digits = cardInfo["number"] as? String { displayName = "•••• \(digits)" @@ -125,37 +120,59 @@ internal extension PaymentMethod { displayName = emailInfo } - self.init(name: name, displayName: displayName, type: type, oneClick: oneClick) + let logoURL = URL(string: logoBaseURL + type + UIScreen.retinaExtension() + ".png") + let inputDetails = (info["inputDetails"] as? [[String: Any]])?.flatMap { InputDetail(info: $0) } + + var group: Group? + if let groupInfo = info["group"] as? [String: Any] { + group = Group(info: groupInfo) + } + + self.init(name: displayName, type: type, isOneClick: isOneClick, logoURL: logoURL, inputDetails: inputDetails, members: nil, group: group) paymentMethodData = data configuration = info["configuration"] as? [String: Any] self.logoBaseURL = logoBaseURL - logoURL = URL(string: logoBaseURL + type + UIScreen.retinaExtension() + ".png") - - if let inputDetails = info["inputDetails"] as? [[String: Any]] { - self.inputDetails = inputDetails.flatMap({ InputDetail(info: $0) }) - } - - if let groupInfo = info["group"] as? [String: Any] { - group = PaymentMethodGroup(info: groupInfo) - } } - convenience init?(group: [PaymentMethod]) { - guard group.count > 0 else { + convenience init?(members: [PaymentMethod]) { + guard members.count > 0 else { return nil } - let method = group[0] + let method = members[0] + let group = method.group! - self.init(name: method.group!.name, displayName: method.group!.name, type: method.group!.type) + self.init(name: group.name, type: group.type, isOneClick: false, logoURL: method.groupLogoURL, inputDetails: method.inputDetails, members: members, group: nil) - members = group - logoURL = method.groupLogoURL - inputDetails = method.inputDetails paymentMethodData = method.group!.data } + + internal struct Group { + + internal let type: String + + internal let name: String + + internal let data: String + + internal init?(info: [String: Any]) { + guard + let type = info["type"] as? String, + let name = info["name"] as? String, + let data = info["paymentMethodData"] as? String + else { + return nil + } + + self.type = type + self.name = name + self.data = data + } + + } + } extension PaymentMethod: Equatable { @@ -165,3 +182,15 @@ extension PaymentMethod: Equatable { return lhs.name == rhs.name && lhs.type == rhs.type } } + +// MARK: - Deprecated + +public extension PaymentMethod { + + /// A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user. + @available(*, deprecated, message: "Use isOneClick instead.") + public var oneClick: Bool { + return isOneClick + } + +} diff --git a/Adyen/Core/PaymentMethodGroup.swift b/Adyen/Core/PaymentMethodGroup.swift deleted file mode 100644 index 39d8e63a3c..0000000000 --- a/Adyen/Core/PaymentMethodGroup.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2017 Adyen B.V. -// -// This file is open source and available under the MIT license. See the LICENSE file for more info. -// - -import Foundation - -class PaymentMethodGroup { - - let type: String - let name: String - let data: String - - init(type: String, name: String, data: String) { - self.type = type - self.name = name - self.data = data - } - - convenience init?(info: [String: Any]) { - - guard - let type = info["type"] as? String, - let name = info["name"] as? String, - let data = info["paymentMethodData"] as? String - else { - return nil - } - - self.init(type: type, name: name, data: data) - } -} diff --git a/Adyen/Core/PaymentRequest.swift b/Adyen/Core/PaymentRequest.swift index aaff8732ce..830f334ff0 100644 --- a/Adyen/Core/PaymentRequest.swift +++ b/Adyen/Core/PaymentRequest.swift @@ -18,34 +18,34 @@ public typealias PaymentDetailsCompletion = (PaymentDetails) -> Void public final class PaymentRequest { /// Delegate for controlling the payment flow. See `PaymentRequestDelegate`. - internal(set) public weak var delegate: PaymentRequestDelegate? + public internal(set) weak var delegate: PaymentRequestDelegate? /// The selected payment method. - private(set) public var paymentMethod: PaymentMethod? + public private(set) var paymentMethod: PaymentMethod? /// Amount to be charged. - private(set) public var amount: Int? + public private(set) var amount: Int? /// Payment currency. - private(set) public var currency: String? + public private(set) var currency: String? /// Payment reference. - private(set) public var reference: String? + public private(set) var reference: String? /// Payment country code. - private(set) public var countryCode: String? + public private(set) var countryCode: String? /// Shopper locale. - private(set) public var shopperLocale: String? + public private(set) var shopperLocale: String? /// Shopper reference. - private(set) public var shopperReference: String? + public private(set) var shopperReference: String? /// Generation time. Used for generating a token for card payments. - private(set) public var generationTime: String? + public private(set) var generationTime: String? /// Public key. Used for generating a token for card payments. - private(set) public var publicKey: String? + public private(set) var publicKey: String? var paymentRequest: InternalPaymentRequest? @@ -300,21 +300,21 @@ public final class PaymentRequest { return } - let available = methodsInfo.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL) }) + let available = methodsInfo.flatMap { PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, isOneClick: false) } // Group available PM's let groupped = available.groupBy { element in return element.group?.type ?? UUID().uuidString } - let availableGroupped = groupped.flatMap { group -> PaymentMethod? in - return group.count == 1 ? group[0] : PaymentMethod(group: group) + let availableGroupped = groupped.flatMap { members -> PaymentMethod? in + return members.count == 1 ? members[0] : PaymentMethod(members: members) } // Parse one-click methods var preferredMethods = [PaymentMethod]() if let recurringDetails = info["recurringDetails"] as? [[String: Any]] { - preferredMethods = recurringDetails.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, oneClick: true) }) + preferredMethods = recurringDetails.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, isOneClick: true) }) } completion(preferredMethods, availableGroupped, nil) @@ -398,7 +398,10 @@ internal extension PaymentRequest { return } - let result = Payment(payment: paymentRequest, status: status, payload: payload) + let result = Payment(status: status, + method: paymentMethod!, + payload: payload, + internalRequest: paymentRequest) processorFinished(with: result) } diff --git a/Adyen/Core/Protocols/PaymentRequestDelegate.swift b/Adyen/Core/Protocols/PaymentRequestDelegate.swift index e02b298969..b909b944a2 100644 --- a/Adyen/Core/Protocols/PaymentRequestDelegate.swift +++ b/Adyen/Core/Protocols/PaymentRequestDelegate.swift @@ -21,4 +21,5 @@ public protocol PaymentRequestDelegate: class { /// This method is called when the payment flow is finished. func paymentRequest(_ request: PaymentRequest, didFinishWith result: PaymentRequestResult) + } diff --git a/Adyen/Core/Version.swift b/Adyen/Core/Version.swift index 5b38b98704..69e817bbbf 100644 --- a/Adyen/Core/Version.swift +++ b/Adyen/Core/Version.swift @@ -7,11 +7,10 @@ import Foundation var sdkVersion: String { - if let file = Bundle(for: PaymentRequest.self).path(forResource: "VERSION", ofType: ""), - let lines = try? String(contentsOfFile: file).components(separatedBy: .newlines), - let version = lines.first { - return version + let bundle = Bundle(for: PaymentRequest.self) + guard let version = bundle.infoDictionary?["CFBundleShortVersionString"] as? String else { + fatalError("Failed to read version number from Info.plist.") } - fatalError("Could not read VERSION file") + return version } diff --git a/Adyen/CoreUI/AppearanceConfiguration.swift b/Adyen/CoreUI/AppearanceConfiguration.swift new file mode 100644 index 0000000000..d0b51dcbff --- /dev/null +++ b/Adyen/CoreUI/AppearanceConfiguration.swift @@ -0,0 +1,124 @@ +// +// Copyright (c) 2017 Adyen B.V. +// +// This file is open source and available under the MIT license. See the LICENSE file for more info. +// + +import Foundation + +/// Provides properties to customize the appearance of the UI components provided by this library. +/// Note that `AppearanceConfiguration` is only used when the `CheckoutViewController` is first initialized. Changes to this object after it has been created are ignored. +public final class AppearanceConfiguration { + + /// Initializes the appearance configuration. + public init() { + + } + + // MARK: Status Bar + + /// The preferred status bar style. + public var preferredStatusBarStyle = UIStatusBarStyle.default + + // MARK: Navigation Bar + + /// The attributes used for the navigation bar's title. + public var navigationBarTitleTextAttributes: [String: Any]? + + /// The navigation bar's tint color. + public var navigationBarTintColor: UIColor? + + /// The navigation bar's background color. + public var navigationBarBackgroundColor: UIColor? + + /// A Boolean value indicating whether the navigation bar is translucent. + public var isNavigationBarTranslucent = true + + /// The image of the cancel button in the navigation bar, or `nil` if a title should be used instead. + public var navigationBarCancelButtonImage: UIImage? + + // MARK: Checkout Button + + /// The attributes used for the checkout button's title. + public var checkoutButtonTitleTextAttributes: [String: Any]? + + /// The insets from the edges of the checkout button to the title. + public var checkoutButtonTitleEdgeInsets: UIEdgeInsets? + + /// The corner radius of the checkout button. + public var checkoutButtonCornerRadius: CGFloat = 0.0 + + // MARK: Other + + /// The tint color of most buttons and actionable elements. + public var tintColor: UIColor? + + // MARK: Default Configuration + + /// The default appearance configuration. + public static var `default`: AppearanceConfiguration = { + let appearanceConfiguration = AppearanceConfiguration() + appearanceConfiguration.navigationBarTitleTextAttributes = [ + NSFontAttributeName: UIFont.systemFont(ofSize: 18.0), + NSForegroundColorAttributeName: UIColor.checkoutDarkGray + ] + appearanceConfiguration.navigationBarTintColor = UIColor.checkoutDarkGray + appearanceConfiguration.navigationBarBackgroundColor = UIColor.white + appearanceConfiguration.isNavigationBarTranslucent = false + appearanceConfiguration.navigationBarCancelButtonImage = UIImage.bundleImage("close") + + appearanceConfiguration.checkoutButtonTitleTextAttributes = [ + NSFontAttributeName: UIFont.systemFont(ofSize: 18.0), + NSForegroundColorAttributeName: UIColor.white + ] + appearanceConfiguration.checkoutButtonTitleEdgeInsets = UIEdgeInsets(top: 16.0, left: 0.0, bottom: 16.0, right: 0.0) + appearanceConfiguration.checkoutButtonCornerRadius = 4.0 + + appearanceConfiguration.tintColor = #colorLiteral(red: 0.03921568627, green: 0.7490196078, blue: 0.3254901961, alpha: 1) + + return appearanceConfiguration + }() + +} + +extension AppearanceConfiguration: NSCopying { + + /// :nodoc: + public func copy(with zone: NSZone? = nil) -> Any { + let appearanceConfiguration = AppearanceConfiguration() + appearanceConfiguration.preferredStatusBarStyle = preferredStatusBarStyle + appearanceConfiguration.navigationBarTitleTextAttributes = navigationBarTitleTextAttributes + appearanceConfiguration.navigationBarTintColor = navigationBarTintColor + appearanceConfiguration.navigationBarBackgroundColor = navigationBarBackgroundColor + appearanceConfiguration.isNavigationBarTranslucent = isNavigationBarTranslucent + appearanceConfiguration.navigationBarCancelButtonImage = navigationBarCancelButtonImage + appearanceConfiguration.checkoutButtonTitleTextAttributes = checkoutButtonTitleTextAttributes + appearanceConfiguration.checkoutButtonTitleEdgeInsets = checkoutButtonTitleEdgeInsets + appearanceConfiguration.checkoutButtonCornerRadius = checkoutButtonCornerRadius + appearanceConfiguration.tintColor = tintColor + + return appearanceConfiguration + } + + /// Creates and returns a copied version of the receiver. + internal var copied: AppearanceConfiguration { + return copy() as! AppearanceConfiguration // swiftlint:disable:this force_cast + } + +} + +internal extension AppearanceConfiguration { + + internal func cancelButtonItem(target: Any, selector: Selector) -> UIBarButtonItem { + var cancelButtonItem: UIBarButtonItem! + if let cancelButtonImage = navigationBarCancelButtonImage { + cancelButtonItem = UIBarButtonItem(image: cancelButtonImage, style: .plain, target: target, action: selector) + cancelButtonItem.accessibilityLabel = ADYLocalizedString("cancelButton.title") + } else { + cancelButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: target, action: selector) + } + + return cancelButtonItem + } + +} diff --git a/Adyen/CoreUI/Assets/.gitkeep b/Adyen/CoreUI/Assets/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json deleted file mode 100644 index 3340abb0b1..0000000000 --- a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "back-button.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "back-button@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "back-button@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png deleted file mode 100644 index ab0b7782de..0000000000 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png and /dev/null differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png deleted file mode 100644 index cfa2fc9e3f..0000000000 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png and /dev/null differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png deleted file mode 100644 index 528b4e5b56..0000000000 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png and /dev/null differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json index afe31cefcd..529efd661f 100644 --- a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json +++ b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "version" : 1, "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" } } \ No newline at end of file diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png index 8e7f533820..a8f00ce411 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png index 8840886d93..08883848d2 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png index aaaf036e74..b6de5a34ca 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json index ee217d61ff..a1a1a18dbd 100644 --- a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json +++ b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "version" : 1, "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" } } \ No newline at end of file diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png index 7978455d4a..84b12f58af 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png index c07a4c4086..60751a269c 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png differ diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png index 51a129c53b..4f725ba8db 100644 Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png differ diff --git a/Adyen/CoreUI/Assets/de.lproj/Localizable.strings b/Adyen/CoreUI/Assets/de.lproj/Localizable.strings new file mode 100644 index 0000000000..187cbbc1f8 --- /dev/null +++ b/Adyen/CoreUI/Assets/de.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Bezahlmöglichkeiten"; +"paymentMethods.storedMethods.title" = "Ihre Bezahlmethoden"; +"paymentMethods.otherMethods.title" = "Andere Bezahlmöglichkeiten"; +"creditCard.title" = "Karteneingabe"; +"creditCard.numberField.title" = "Kartennummer"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Verfalldatum"; +"creditCard.expiryDateField.placeholder" = "MM/JJ"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Karte speichern"; +"creditCard.oneClickVerification.title" = "Karte verifizieren"; +"creditCard.oneClickVerification.message" = "Bitte CVC code für %@ eingeben."; +"creditCard.oneClickVerification.invalidInput.title" = "Ungültiger Bestätigungscode"; +"creditCard.oneClickVerification.invalidInput.message" = "Bitte geben Sie einen gültigen Bestätigungscode ein."; +"sepaDirectDebit.ibanField.title" = "Kontonummer (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Name des Kontoinhabers"; +"sepaDirectDebit.nameField.placeholder" = "L. Schmidt"; +"sepaDirectDebit.consentButton.title" = "Ich bin damit einverstanden, dass der folgende genannten Betrage von meinem Konto abgebucht wird."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Mindestens drei Zeichen"; +"cancelButton.title" = "Abbrechen"; +"dismissButton.title" = "Okay"; +"payButton.title" = "Zahlen"; +"payButton.title.formatted" = "%@ bezahlen"; diff --git a/Adyen/CoreUI/Assets/en.lproj/Localizable.strings b/Adyen/CoreUI/Assets/en.lproj/Localizable.strings new file mode 100644 index 0000000000..a13aae5aa5 --- /dev/null +++ b/Adyen/CoreUI/Assets/en.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Payment Methods"; +"paymentMethods.storedMethods.title" = "Your payment methods"; +"paymentMethods.otherMethods.title" = "Select other method"; +"creditCard.title" = "Card Details"; +"creditCard.numberField.title" = "Card Number"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Expiry Date"; +"creditCard.expiryDateField.placeholder" = "MM/YY"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Remember this card for my next payment"; +"creditCard.oneClickVerification.title" = "Verify your card"; +"creditCard.oneClickVerification.message" = "Please enter the CVC code for %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Invalid CVC"; +"creditCard.oneClickVerification.invalidInput.message" = "Please enter a valid CVC to continue."; +"sepaDirectDebit.ibanField.title" = "Account Number (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Holder Name"; +"sepaDirectDebit.nameField.placeholder" = "J. Smith"; +"sepaDirectDebit.consentButton.title" = "I agree that the amount below will be debited from my bank account."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Min. 3 characters"; +"cancelButton.title" = "Cancel"; +"dismissButton.title" = "OK"; +"payButton.title" = "Pay"; +"payButton.title.formatted" = "Pay %@"; diff --git a/Adyen/CoreUI/Assets/es.lproj/Localizable.strings b/Adyen/CoreUI/Assets/es.lproj/Localizable.strings new file mode 100644 index 0000000000..a69b10706d --- /dev/null +++ b/Adyen/CoreUI/Assets/es.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Métodos de pago"; +"paymentMethods.storedMethods.title" = "Métodos de pago anteriores"; +"paymentMethods.otherMethods.title" = "Otros métodos de pago"; +"creditCard.title" = "Detalles de la tarjeta"; +"creditCard.numberField.title" = "Número de tarjeta"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Fecha de caducidad"; +"creditCard.expiryDateField.placeholder" = "MM/AA"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Recordar estos detalles"; +"creditCard.oneClickVerification.title" = "Validar tarjeta"; +"creditCard.oneClickVerification.message" = "Porfavor entre el número CVC para %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Código de verificación invalido"; +"creditCard.oneClickVerification.invalidInput.message" = "Por favor, introduzca un código de verificación válido."; +"sepaDirectDebit.ibanField.title" = "Número de cuenta (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Nombre del titular de cuenta"; +"sepaDirectDebit.nameField.placeholder" = "C. Smith"; +"sepaDirectDebit.consentButton.title" = "Estoy de acuerdo en que la cantidad descripta será deducida de mi cuenta bancaria."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Mínimo 3 caracteres"; +"cancelButton.title" = "Cancelar"; +"dismissButton.title" = "Okay"; +"payButton.title" = "Pagar"; +"payButton.title.formatted" = "Pagar %@"; diff --git a/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings b/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings new file mode 100644 index 0000000000..4988b53ab1 --- /dev/null +++ b/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Méthodes de paiement"; +"paymentMethods.storedMethods.title" = "Votre méthodes the paiement"; +"paymentMethods.otherMethods.title" = "Autre méthode de paiement"; +"creditCard.title" = "Détails de paiement"; +"creditCard.numberField.title" = "Numéro de carte"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Date d'expiration"; +"creditCard.expiryDateField.placeholder" = "MM/AA"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Se souvenir de ma carte"; +"creditCard.oneClickVerification.title" = "Vérifiez votre carte"; +"creditCard.oneClickVerification.message" = "Entrez votre CVC code pour %@ s'il vous plaît."; +"creditCard.oneClickVerification.invalidInput.title" = "Code de vérification invalide"; +"creditCard.oneClickVerification.invalidInput.message" = "S'il vous plaît entrer un code de vérification valide."; +"sepaDirectDebit.ibanField.title" = "Numéro de compte (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Au nom de"; +"sepaDirectDebit.nameField.placeholder" = "N. Bernard"; +"sepaDirectDebit.consentButton.title" = "J'accepte que le montant ci-dessous soit débité de mon compte bancaire."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "3 caractères minimum"; +"cancelButton.title" = "Annuler"; +"dismissButton.title" = "OK"; +"payButton.title" = "Valider"; +"payButton.title.formatted" = "Payer %@"; diff --git a/Adyen/CoreUI/Assets/it.lproj/Localizable.strings b/Adyen/CoreUI/Assets/it.lproj/Localizable.strings new file mode 100644 index 0000000000..372d461246 --- /dev/null +++ b/Adyen/CoreUI/Assets/it.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Metodo di Pagamento"; +"paymentMethods.storedMethods.title" = "Metodi di pagamento"; +"paymentMethods.otherMethods.title" = "Scegli altro metodo di pagamento"; +"creditCard.title" = "Dettagli Carta"; +"creditCard.numberField.title" = "Numero di Carta"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Data di Scadenza"; +"creditCard.expiryDateField.placeholder" = "MM/AA"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Salva i Dettagli della Carta"; +"creditCard.oneClickVerification.title" = "Verifica la Carta"; +"creditCard.oneClickVerification.message" = "Inserire il codice CVC per %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Codice di verifica non valido."; +"creditCard.oneClickVerification.invalidInput.message" = "Si prega di inserire un codice di verifica valido."; +"sepaDirectDebit.ibanField.title" = "Numero di conto (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Nome Intestatario Conto"; +"sepaDirectDebit.nameField.placeholder" = "A. Bianchi"; +"sepaDirectDebit.consentButton.title" = "Accetto che l'importo indicato sia addebitato sul mio conto corrente."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Mínimo 3 caracteres"; +"cancelButton.title" = "Annulla"; +"dismissButton.title" = "OK"; +"payButton.title" = "Paga"; +"payButton.title.formatted" = "Paga %@"; diff --git a/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings b/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings new file mode 100644 index 0000000000..c3b1d51ae6 --- /dev/null +++ b/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Betaalmethodes"; +"paymentMethods.storedMethods.title" = "Opgeslagen betaalmethodes"; +"paymentMethods.otherMethods.title" = "Alle betaalmethodes"; +"creditCard.title" = "Kaartgegevens"; +"creditCard.numberField.title" = "Kaartnummer"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Vervaldatum"; +"creditCard.expiryDateField.placeholder" = "MM/JJ"; +"creditCard.cvcField.title" = "Verificatiecode"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Bewaar deze kaart voor mijn volgende betaling"; +"creditCard.oneClickVerification.title" = "Verifieer uw kaart"; +"creditCard.oneClickVerification.message" = "Voer de verificatiecode in voor %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Ongeldige verificatiecode"; +"creditCard.oneClickVerification.invalidInput.message" = "Gelieve een geldige verificatiecode in te voeren om de betaling af te ronden."; +"sepaDirectDebit.ibanField.title" = "Rekeningnummer (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Ten name van"; +"sepaDirectDebit.nameField.placeholder" = "P. de Ridder"; +"sepaDirectDebit.consentButton.title" = "Ik ga akkoord met een eenmalige afschrijving van het onderstaande bedrag."; +"giropay.searchField.placeholder" = "Banknaam / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Min. 3 karakters"; +"cancelButton.title" = "Annuleer"; +"dismissButton.title" = "Oké"; +"payButton.title" = "Betaal"; +"payButton.title.formatted" = "Betaal %@"; diff --git a/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings b/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings new file mode 100644 index 0000000000..8936432bc4 --- /dev/null +++ b/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Meios de pagamento"; +"paymentMethods.storedMethods.title" = "Meus métodos de pagamento"; +"paymentMethods.otherMethods.title" = "Todos os métodos de pagamento"; +"creditCard.title" = "Detalhes do cartão"; +"creditCard.numberField.title" = "Número do Cartão"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Data de Vencimento"; +"creditCard.expiryDateField.placeholder" = "MM/AA"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Lembrar o cartão"; +"creditCard.oneClickVerification.title" = "Verifique o seu cartão"; +"creditCard.oneClickVerification.message" = "Por favor insira o código CVC para %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Código de verificação inválido."; +"creditCard.oneClickVerification.invalidInput.message" = "Por favor insira um código de verificação válido."; +"sepaDirectDebit.ibanField.title" = "Número de conta (NIB)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Nome do titular da conta bancária"; +"sepaDirectDebit.nameField.placeholder" = "J. Silva"; +"sepaDirectDebit.consentButton.title" = "Concordo que o seguinte valor será deduzido da minha conta bancária."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Mínimo de 3 caracteres"; +"cancelButton.title" = "Cancelar"; +"dismissButton.title" = "OK"; +"payButton.title" = "Pagar"; +"payButton.title.formatted" = "Pagar %@"; diff --git a/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings b/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings new file mode 100644 index 0000000000..5e89d4a418 --- /dev/null +++ b/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings @@ -0,0 +1,26 @@ +"paymentMethods.title" = "Betalningsmetoder"; +"paymentMethods.storedMethods.title" = "Dina sparade betalningsmetoder"; +"paymentMethods.otherMethods.title" = "Välj annan betalningsmetod"; +"creditCard.title" = "Kortuppgifter"; +"creditCard.numberField.title" = "Kortnummer"; +"creditCard.numberField.placeholder" = "1234 5678 9012 3456"; +"creditCard.expiryDateField.title" = "Förfallodatum"; +"creditCard.expiryDateField.placeholder" = "MM/AA"; +"creditCard.cvcField.title" = "CVC / CVV"; +"creditCard.cvcField.placeholder" = "123"; +"creditCard.storeDetailsButton.title" = "Spara kortuppgifter"; +"creditCard.oneClickVerification.title" = "Verifiera ditt kort"; +"creditCard.oneClickVerification.message" = "Vänligen fyll i CVC kod för %@"; +"creditCard.oneClickVerification.invalidInput.title" = "Ogiltig verifieringskod."; +"creditCard.oneClickVerification.invalidInput.message" = "Ange en giltig verifieringskod."; +"sepaDirectDebit.ibanField.title" = "Kontonummer (IBAN)"; +"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122"; +"sepaDirectDebit.nameField.title" = "Känt av kontoinnehavaren"; +"sepaDirectDebit.nameField.placeholder" = "J. Johansson"; +"sepaDirectDebit.consentButton.title" = "Jag håller med om att beloppet nedan debiteras från mitt bankkonto."; +"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl"; +"giropay.minimumLength.title" = "Minst 3 tecken"; +"cancelButton.title" = "Avbryt"; +"dismissButton.title" = "OK"; +"payButton.title" = "Betala"; +"payButton.title.formatted" = "Betala %@"; diff --git a/Adyen/CoreUI/BundleExtensions.swift b/Adyen/CoreUI/BundleExtensions.swift new file mode 100644 index 0000000000..d5d81e5577 --- /dev/null +++ b/Adyen/CoreUI/BundleExtensions.swift @@ -0,0 +1,27 @@ +// +// Copyright (c) 2017 Adyen B.V. +// +// This file is open source and available under the MIT license. See the LICENSE file for more info. +// + +import Foundation + +internal extension Bundle { + + /// The bundle in which the framework's resources are located. + internal static let resources: Bundle = { + let mainBundle = Bundle(for: PaymentRequest.self) + + // If we're installed through CocoaPods, there should be a CoreUI bundle with the resources. + // If not, simply return the main bundle. + guard + let resourcesBundlePath = mainBundle.path(forResource: "CoreUI", ofType: "bundle"), + let resourcesBundle = Bundle(path: resourcesBundlePath) + else { + return mainBundle + } + + return resourcesBundle + }() + +} diff --git a/Adyen/CoreUI/CheckoutButton.swift b/Adyen/CoreUI/CheckoutButton.swift index 1aec5a4c2e..b39c0f19ed 100644 --- a/Adyen/CoreUI/CheckoutButton.swift +++ b/Adyen/CoreUI/CheckoutButton.swift @@ -6,46 +6,158 @@ import UIKit -class CheckoutButton: UIButton { +/// The CheckoutButton class provides a large, tinted button to complete a checkout. +@IBDesignable +internal class CheckoutButton: UIControl { - override var isEnabled: Bool { + internal override init(frame: CGRect) { + super.init(frame: frame) + + commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + commonInit() + } + + private func commonInit() { + layer.cornerRadius = 4.0 + + accessibilityTraits = UIAccessibilityTraitButton + + addSubview(titleLabel) + addSubview(activityIndicatorView) + + configureConstraints() + updateAppearance() + + isAccessibilityElement = true + accessibilityTraits = UIAccessibilityTraitButton + } + + override func tintColorDidChange() { + super.tintColorDidChange() + + backgroundColor = tintColor + } + + // MARK: Layout + + private func configureConstraints() { + let constraints = [ + titleLabelTopAnchorConstraint, + titleLabelBottomAnchorConstraint, + titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), + activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor), + activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor) + ] + + NSLayoutConstraint.activate(constraints) + } + + private lazy var titleLabelTopAnchorConstraint: NSLayoutConstraint = { + self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor) + }() + + private lazy var titleLabelBottomAnchorConstraint: NSLayoutConstraint = { + self.titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) + }() + + // MARK: Appearance Configuration + + internal var appearanceConfiguration: AppearanceConfiguration = .default { didSet { - backgroundColor = backgroundColor?.withAlphaComponent(isEnabled ? 1 : 0.5) + updateAppearance() } } - func startLoading() { - let indicator = UIActivityIndicatorView(activityIndicatorStyle: .white) - indicator.hidesWhenStopped = true - indicator.translatesAutoresizingMaskIntoConstraints = false + private func updateAppearance() { + tintColor = appearanceConfiguration.tintColor - addSubview(indicator) - addConstraints(indicator) + let cornerRadius = appearanceConfiguration.checkoutButtonCornerRadius + clipsToBounds = cornerRadius > 0.0 + layer.cornerRadius = cornerRadius - setTitleColor(titleColor(for: .normal)?.withAlphaComponent(0), for: .normal) + let titleLabelEdgeInsets = appearanceConfiguration.checkoutButtonTitleEdgeInsets ?? .zero + titleLabelTopAnchorConstraint.constant = titleLabelEdgeInsets.top + titleLabelBottomAnchorConstraint.constant = -titleLabelEdgeInsets.bottom - indicator.startAnimating() + updateTitle() } - private func addConstraints(_ indicator: UIActivityIndicatorView) { - addConstraint(NSLayoutConstraint( - item: indicator, - attribute: .centerX, - relatedBy: .equal, - toItem: self, - attribute: .centerX, - multiplier: 1, - constant: 0 - )) + // MARK: Title Label + + private lazy var titleLabel: UILabel = { + let titleLabel = UILabel() + titleLabel.isUserInteractionEnabled = false + titleLabel.isAccessibilityElement = false + titleLabel.translatesAutoresizingMaskIntoConstraints = false - addConstraint(NSLayoutConstraint( - item: indicator, - attribute: .centerY, - relatedBy: .equal, - toItem: self, - attribute: .centerY, - multiplier: 1, - constant: 0 - )) + return titleLabel + }() + + @IBInspectable + internal var title: String? { + didSet { + updateTitle() + + accessibilityLabel = title + } + } + + private func updateTitle() { + let attributedTitle = NSAttributedString(string: title ?? "", + attributes: appearanceConfiguration.checkoutButtonTitleTextAttributes) + titleLabel.attributedText = attributedTitle + } + + // MARK: Enabled State + + override var isEnabled: Bool { + didSet { + alpha = isEnabled ? 1.0 : 0.5 + + if isEnabled { + accessibilityTraits = UIAccessibilityTraitButton + } else { + accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled + } + } + } + + // MARK: Highlighted State + + override var isHighlighted: Bool { + didSet { + alpha = isHighlighted ? 0.75 : 1.0 + } + } + + // MARK: Loading State + + /// Boolean value indicating whether the button should display an activity indicator. + internal var isLoading: Bool = false { + didSet { + titleLabel.isHidden = isLoading + + if isLoading { + activityIndicatorView.startAnimating() + } else { + activityIndicatorView.stopAnimating() + } + + isUserInteractionEnabled = !isLoading + } } + + private lazy var activityIndicatorView: UIActivityIndicatorView = { + let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .white) + activityIndicatorView.isUserInteractionEnabled = false + activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false + + return activityIndicatorView + }() + } diff --git a/Adyen/CoreUI/Localization.swift b/Adyen/CoreUI/Localization.swift new file mode 100644 index 0000000000..d03c5e709d --- /dev/null +++ b/Adyen/CoreUI/Localization.swift @@ -0,0 +1,80 @@ +// +// Copyright (c) 2017 Adyen B.V. +// +// This file is open source and available under the MIT license. See the LICENSE file for more info. +// + +import Foundation + +/// Returns a localized string for the given key, and optionally uses it as a template in which the remaining argument values are substituted. +/// +/// - Parameters: +/// - key: The key used to identify the localized string. +/// - arguments: The arguments to substitute in the templated localized string. +/// - Returns: The localized string for the given key, or the key itself if the localized string could not be found. +internal func ADYLocalizedString(_ key: String, _ arguments: CVarArg...) -> String { + let localizedString = NSLocalizedString(key, + tableName: nil, + bundle: .resources, + comment: "") + + guard arguments.isEmpty == false else { + return localizedString + } + + return String(format: localizedString, arguments: arguments) +} + +internal extension UIView { + + /// The key to the localized string that should be set to the label's accessibility label property. + @IBInspectable + internal var localizedAccessibilityLabelKey: String? { + get { return nil } + + set { + if let key = newValue { + accessibilityLabel = ADYLocalizedString(key) + } else { + accessibilityLabel = nil + } + } + } + +} + +internal extension UILabel { + + /// The key to the localized string that should be set to the label's text property. + @IBInspectable + internal var localizedTextKey: String? { + get { return nil } + + set { + if let key = newValue { + text = ADYLocalizedString(key) + } else { + text = nil + } + } + } + +} + +internal extension UITextField { + + /// The key to the localized string that should be set to the text field's placeholder property. + @IBInspectable + internal var localizedPlaceholderKey: String? { + get { return nil } + + set { + if let key = newValue { + placeholder = ADYLocalizedString(key) + } else { + placeholder = nil + } + } + } + +} diff --git a/Adyen/CoreUI/PaymentMethodTableViewCell.swift b/Adyen/CoreUI/PaymentMethodTableViewCell.swift index be0ba2076c..e454066ae8 100644 --- a/Adyen/CoreUI/PaymentMethodTableViewCell.swift +++ b/Adyen/CoreUI/PaymentMethodTableViewCell.swift @@ -7,147 +7,132 @@ import UIKit class PaymentMethodTableViewCell: LoadingTableViewCell { - fileprivate let nameLabel = UILabel() - fileprivate let logoImageView = UIImageView() - var name: String? { - didSet { - nameLabel.text = name - } + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + commonInit() } + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + commonInit() + } + + private func commonInit() { + contentView.addSubview(logoView) + contentView.addSubview(nameLabel) + + accessibilityTraits |= UIAccessibilityTraitButton + + configureConstraints() + } + + override func stopLoadingAnimation() { + super.stopLoadingAnimation() + + // Reset the disclosure indicator, in case it was visible before the loading animation was shown. + let showsDisclosureIndicator = self.showsDisclosureIndicator + self.showsDisclosureIndicator = showsDisclosureIndicator + } + + // MARK: Layout + + private func configureConstraints() { + let marginsGuide = contentView.layoutMarginsGuide + + let constraints = [ + logoView.leadingAnchor.constraint(equalTo: marginsGuide.leadingAnchor), + logoView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + logoView.widthAnchor.constraint(equalToConstant: 40.0), + logoView.heightAnchor.constraint(equalToConstant: 26.0), + nameLabel.leadingAnchor.constraint(equalTo: logoView.trailingAnchor, constant: 20.0), + nameLabel.trailingAnchor.constraint(lessThanOrEqualTo: marginsGuide.trailingAnchor), + nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) + ] + + NSLayoutConstraint.activate(constraints) + } + + // MARK: Logo Image View + var logoURL: URL? { didSet { guard let url = logoURL else { - logoImageView.image = nil + logoView.image = nil return } - logoImageView.downloadedFrom(url: url) - logoImageView.contentMode = .scaleAspectFit - logoImageView.layer.cornerRadius = 4 - logoImageView.layer.borderWidth = 1 / UIScreen.main.nativeScale - logoImageView.layer.borderColor = UIColor.black.withAlphaComponent(0.2).cgColor - logoImageView.clipsToBounds = true + logoView.downloadedFrom(url: url) + logoView.contentMode = .scaleAspectFit + logoView.layer.cornerRadius = 4 + logoView.layer.borderWidth = 1 / UIScreen.main.nativeScale + logoView.layer.borderColor = UIColor.black.withAlphaComponent(0.2).cgColor + logoView.clipsToBounds = true } } - override init(style: UITableViewCellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupViews() - } + fileprivate lazy var logoView: UIImageView = { + let logoView = UIImageView() + logoView.contentMode = .scaleAspectFit + logoView.translatesAutoresizingMaskIntoConstraints = false + + return logoView + }() - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - setupViews() + // MARK: Name Label + + var name: String? { + didSet { + nameLabel.text = name + + accessibilityLabel = name + } } -} - -// MARK: Subviews Stack - -extension PaymentMethodTableViewCell { - func setupViews() { + fileprivate lazy var nameLabel: UILabel = { + let nameLabel = UILabel() + nameLabel.font = UIFont.systemFont(ofSize: 16.0) + nameLabel.textColor = UIColor.checkoutDarkGray nameLabel.translatesAutoresizingMaskIntoConstraints = false - logoImageView.translatesAutoresizingMaskIntoConstraints = false + nameLabel.isAccessibilityElement = false - addSubview(nameLabel) - addSubview(logoImageView) - - applyLogoConstraints() - applyNameConstraints() - applyStyling() - } + return nameLabel + }() - func applyLogoConstraints() { - self.addConstraint(NSLayoutConstraint( - item: logoImageView, - attribute: .width, - relatedBy: .equal, - toItem: nil, - attribute: .notAnAttribute, - multiplier: 1, - constant: 40 - )) - self.addConstraint(NSLayoutConstraint( - item: logoImageView, - attribute: .height, - relatedBy: .equal, - toItem: nil, - attribute: .notAnAttribute, - multiplier: 1, - constant: 26 - )) - self.addConstraint(NSLayoutConstraint( - item: logoImageView, - attribute: .centerY, - relatedBy: .equal, - toItem: self, - attribute: .centerY, - multiplier: 1, - constant: 0 - )) - self.addConstraint(NSLayoutConstraint( - item: logoImageView, - attribute: .leading, - relatedBy: .equal, - toItem: self, - attribute: .leading, - multiplier: 1, - constant: 20 - )) - } + // MARK: Disclosure Indicator - func applyNameConstraints() { - self.addConstraint(NSLayoutConstraint( - item: nameLabel, - attribute: .centerY, - relatedBy: .equal, - toItem: self, - attribute: .centerY, - multiplier: 1, - constant: 0 - )) - self.addConstraint(NSLayoutConstraint( - item: nameLabel, - attribute: .leading, - relatedBy: .equal, - toItem: logoImageView, - attribute: .trailing, - multiplier: 1, - constant: 20 - )) - self.addConstraint(NSLayoutConstraint( - item: nameLabel, - attribute: .trailing, - relatedBy: .lessThanOrEqual, - toItem: self, - attribute: .trailing, - multiplier: 1, - constant: -35 - )) + /// Boolean value indicating whether the detail indicator should be shown as an accessory. + internal var showsDisclosureIndicator: Bool = false { + didSet { + if showsDisclosureIndicator { + accessoryView = UIImageView(image: UIImage.bundleImage("cell_disclosure_indicator")) + } else { + accessoryView = nil + } + } } - func applyStyling() { - logoImageView.contentMode = .scaleAspectFit - - nameLabel.font = UIFont.systemFont(ofSize: 16) - nameLabel.textColor = UIColor.checkoutDark() - - self.accessoryView = UIImageView(image: UIImage.bundleImage("cell_disclosure_indicator")) - } } -// MARK: Configuration +// MARK: PaymentMethod Configuration extension PaymentMethodTableViewCell { func configure(with method: PaymentMethod) { - self.name = method.name - self.logoURL = method.logoURL - - if let linnearFlow = method.plugin?.linnearFlow(), linnearFlow == false { - self.accessoryView = nil + name = method.name + logoURL = method.logoURL + showsDisclosureIndicator = shouldShowDisclosureIndicator(for: method) + } + + fileprivate func shouldShowDisclosureIndicator(for method: PaymentMethod) -> Bool { + switch method.txVariant { + case .ideal, .card, .sepadirectdebit: + return true + default: + return false } } + } diff --git a/Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift b/Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift similarity index 69% rename from Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift rename to Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift index a32380a6f8..b1e02e302a 100644 --- a/Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift +++ b/Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift @@ -7,7 +7,7 @@ import Foundation protocol PaymentMethodDetailsPresenter { - func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void) + func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) func present() func dismiss(animated: Bool, completion: @escaping () -> Void) } diff --git a/Adyen/Core/Protocols/UIPresentable.swift b/Adyen/CoreUI/Plugins/UIPresentable.swift similarity index 100% rename from Adyen/Core/Protocols/UIPresentable.swift rename to Adyen/CoreUI/Plugins/UIPresentable.swift diff --git a/Adyen/CoreUI/UIColorExtensions.swift b/Adyen/CoreUI/UIColorExtensions.swift index dda04e03b1..68ad76b94e 100644 --- a/Adyen/CoreUI/UIColorExtensions.swift +++ b/Adyen/CoreUI/UIColorExtensions.swift @@ -9,36 +9,20 @@ import UIKit internal extension UIColor { - convenience init(hexString: String, alpha: Double = 1.0) { - - let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) - var int = UInt32() - Scanner(string: hex).scanHexInt32(&int) - let r, g, b: UInt32 - switch hex.characters.count { - case 3: // RGB (12-bit) - (r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) - case 6: // RGB (24-bit) - (r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF) - default: - (r, g, b) = (1, 1, 0) - } - - self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(255 * alpha) / 255) + internal static var checkoutLightGray: UIColor { + return #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1) } -} - -internal extension UIColor { - class func checkoutDark() -> UIColor { - return UIColor(hexString: "353535") + internal static var checkoutGray: UIColor { + return #colorLiteral(red: 0.4431372549, green: 0.4431372549, blue: 0.4431372549, alpha: 1) } - class func checkoutBackground() -> UIColor { - return UIColor(hexString: "F9F9F9") + internal static var checkoutDarkGray: UIColor { + return #colorLiteral(red: 0.2078431373, green: 0.2078431373, blue: 0.2078431373, alpha: 1) } - class func checkoutLightDark() -> UIColor { - return UIColor(hexString: "717171") + internal static var checkoutBackground: UIColor { + return checkoutLightGray } + } diff --git a/Adyen/CoreUI/UIImageExtensions.swift b/Adyen/CoreUI/UIImageExtensions.swift index d63dac51c6..ca000ed75c 100644 --- a/Adyen/CoreUI/UIImageExtensions.swift +++ b/Adyen/CoreUI/UIImageExtensions.swift @@ -8,8 +8,6 @@ import Foundation internal extension UIImage { class func bundleImage(_ name: String) -> UIImage? { - let bundle = Bundle(for: PaymentRequest.self) - let image = UIImage(named: name, in: bundle, compatibleWith: nil) - return image + return UIImage(named: name, in: .resources, compatibleWith: nil) } } diff --git a/Adyen/Info.plist b/Adyen/Info.plist new file mode 100644 index 0000000000..09738dfd75 --- /dev/null +++ b/Adyen/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift b/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift index aae0bf8717..74725bda81 100644 --- a/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift +++ b/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift @@ -32,7 +32,7 @@ class ApplePayDetailsPresenter: NSObject, PaymentMethodDetailsPresenter { return request } - func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void) { + func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) { self.hostViewController = hostViewController requiredPaymentDetails = paymentDetails detailsCompletion = completion diff --git a/Adyen/Plugins/Cards/CardFormViewController.swift b/Adyen/Plugins/Cards/CardFormViewController.swift index 6df84a2917..f1dd3c796b 100644 --- a/Adyen/Plugins/Cards/CardFormViewController.swift +++ b/Adyen/Plugins/Cards/CardFormViewController.swift @@ -7,45 +7,21 @@ import UIKit import QuartzCore -class CardFormViewController: UIViewController { - // Interface Builder - @IBOutlet weak var lockImageView: UIImageView! - - // Card Number Field - @IBOutlet weak var cardNumberLabel: UILabel! - @IBOutlet weak var cardNumberLogoImageView: UIImageView! - @IBOutlet weak var cardNumberUnderlineView: UIView! - @IBOutlet weak var cardNumberTextField: CardNumberField! - - // Expiry Date Field - @IBOutlet weak var expiryDateLabel: UILabel! - @IBOutlet weak var expiryDateUnderlineView: UIView! - @IBOutlet weak var expiryDateTextField: CardExpirationField! - - // CVC Field - @IBOutlet weak var cvcLabel: UILabel! - @IBOutlet weak var cvcUnderlineView: UIView! - @IBOutlet weak var cvcTextField: CardCvcField! - - // Store Details - @IBOutlet weak var storeDetailsLabel: UILabel! - @IBOutlet weak var storeDetailsButton: UIButton! +class CardFormViewController: UIViewController, CheckoutPaymentFieldDelegate { - @IBOutlet weak var payButton: CheckoutButton! - @IBOutlet weak var scrollView: UIScrollView! - @IBOutlet weak var keyboardTopLineBottomConstraint: NSLayoutConstraint! - @IBOutlet weak var formHeightConstraint: NSLayoutConstraint! + // MARK: - Object Lifecycle - fileprivate let inactiveColor = UIColor(hexString: "D8D8D8") - fileprivate let activeColor = UIColor(hexString: "757575") + init(appearanceConfiguration: AppearanceConfiguration) { + self.appearanceConfiguration = appearanceConfiguration + + super.init(nibName: "CardFormViewController", bundle: Bundle(for: CardFormViewController.self)) + } - fileprivate var cardFieldManager: CardPaymentFieldManager? - fileprivate var detectedCardType = CardType.unknown + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } - var cardDetailsHandler: (([String: Any], @escaping ((Bool) -> Void)) -> Void)? - var formattedAmount: String? - var paymentMethod: PaymentMethod? - var shouldHideStoreDetails = false + // MARK: - UIViewController override func viewDidLoad() { super.viewDidLoad() @@ -56,17 +32,78 @@ class CardFormViewController: UIViewController { cardFieldManager?.delegate = self } + // MARK: - CheckoutPaymentFieldDelegate + + func paymentFieldChangedValidity(_ valid: Bool) { + payButton.isEnabled = valid + } + + func paymentFieldDidDetectCard(type: CardType) { + updateCardLogoWith(type: type) + updateCvcRequirementWith(type: type) + } + + func paymentFieldDidUpdateActive(field: UITextField) { + updateFieldsPresentationWith(field: field) + } + + // MARK: - Public + + var cardDetailsHandler: (([String: Any], @escaping ((Bool) -> Void)) -> Void)? + var formattedAmount: String? + var paymentMethod: PaymentMethod? + var shouldHideStoreDetails = false + + // MARK: - Private + + // Interface Builder + @IBOutlet private weak var lockImageView: UIImageView! + + // Card Number Field + @IBOutlet private weak var cardNumberLabel: UILabel! + @IBOutlet private weak var cardNumberLogoImageView: UIImageView! + @IBOutlet private weak var cardNumberUnderlineView: UIView! + @IBOutlet private weak var cardNumberTextField: CardNumberField! + + // Expiry Date Field + @IBOutlet private weak var expiryDateLabel: UILabel! + @IBOutlet private weak var expiryDateUnderlineView: UIView! + @IBOutlet private weak var expiryDateTextField: CardExpirationField! + + // CVC Field + @IBOutlet private weak var cvcLabel: UILabel! + @IBOutlet private weak var cvcUnderlineView: UIView! + @IBOutlet private weak var cvcTextField: CardCvcField! + + // Store Details + @IBOutlet private weak var storeDetailsLabel: UILabel! + @IBOutlet private weak var storeDetailsButton: UIButton! + + @IBOutlet private weak var payButton: CheckoutButton! + @IBOutlet private weak var scrollView: UIScrollView! + @IBOutlet private weak var keyboardTopLineBottomConstraint: NSLayoutConstraint! + @IBOutlet private weak var formHeightConstraint: NSLayoutConstraint! + + private let inactiveColor = #colorLiteral(red: 0.8470588235, green: 0.8470588235, blue: 0.8470588235, alpha: 1) + private let activeColor = #colorLiteral(red: 0.4588235294, green: 0.4588235294, blue: 0.4588235294, alpha: 1) + + private var cardFieldManager: CardPaymentFieldManager? + private var detectedCardType: CardType? + + private let appearanceConfiguration: AppearanceConfiguration + private func applyStyling() { - title = "Card Details" + title = ADYLocalizedString("creditCard.title") cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon") lockImageView.image = UIImage.bundleImage("lock") storeDetailsButton.setImage(UIImage.bundleImage("checkbox_inactive"), for: .normal) storeDetailsButton.setImage(UIImage.bundleImage("checkbox_active"), for: .selected) + storeDetailsButton.tintColor = appearanceConfiguration.tintColor payButton.isEnabled = false - payButton.layer.cornerRadius = 4 - payButton.setTitle("Pay \(formattedAmount ?? "")", for: .normal) + payButton.title = ADYLocalizedString("payButton.title.formatted", formattedAmount ?? "") + payButton.appearanceConfiguration = appearanceConfiguration if shouldHideStoreDetails { hideStoreDetails() @@ -83,7 +120,7 @@ class CardFormViewController: UIViewController { formHeightConstraint.constant -= 40 } - fileprivate func updateFieldsPresentationWith(field: UITextField) { + private func updateFieldsPresentationWith(field: UITextField) { cardNumberUnderlineView.backgroundColor = inactiveColor expiryDateUnderlineView.backgroundColor = inactiveColor cvcUnderlineView.backgroundColor = inactiveColor @@ -125,14 +162,14 @@ class CardFormViewController: UIViewController { } } - fileprivate func updateCardLogoWith(type: CardType) { - if detectedCardType == type { + private func updateCardLogoWith(type: CardType?) { + guard detectedCardType != type else { return } detectedCardType = type - if detectedCardType == .unknown { + guard detectedCardType != nil else { cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon") return } @@ -141,7 +178,7 @@ class CardFormViewController: UIViewController { return } - for member in members where member.type == detectedCardType.rawValue { + for member in members where member.type == detectedCardType!.rawValue { if let url = member.logoURL { cardNumberLogoImageView.downloadedFrom(url: url) cardNumberLogoImageView.contentMode = .scaleAspectFit @@ -157,10 +194,12 @@ class CardFormViewController: UIViewController { // change to unknown if couldn't find anything cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon") } -} - -extension CardFormViewController { - @IBAction func pay(_ sender: Any) { + + private func updateCvcRequirementWith(type: CardType?) { + // TODO: update + } + + @IBAction private func pay(_ sender: Any) { // start animation guard let number = cardNumberTextField.text, @@ -186,31 +225,19 @@ extension CardFormViewController { "storeDetails": storeDetailsButton.isSelected ] + resignFirstResponder() + cardNumberTextField.resignFirstResponder() expiryDateTextField.resignFirstResponder() cvcTextField.resignFirstResponder() - payButton.startLoading() + payButton.isLoading = true cardDetailsHandler?(info) { success in } } - @IBAction func storeDetailsToggle(_ sender: Any) { + @IBAction private func storeDetailsToggle(_ sender: Any) { storeDetailsButton.isSelected = !storeDetailsButton.isSelected } -} - -extension CardFormViewController: CheckoutPaymentFieldDelegate { - func paymentFieldChangedValidity(_ valid: Bool) { - payButton.isEnabled = valid - } - - func paymentFieldDidDetectCard(type: CardType) { - updateCardLogoWith(type: type) - } - - func paymentFieldDidUpdateActive(field: UITextField) { - updateFieldsPresentationWith(field: field) - } } diff --git a/Adyen/Plugins/Cards/CardFormViewController.xib b/Adyen/Plugins/Cards/CardFormViewController.xib index f20e218486..4b8b37c525 100644 --- a/Adyen/Plugins/Cards/CardFormViewController.xib +++ b/Adyen/Plugins/Cards/CardFormViewController.xib @@ -1,10 +1,11 @@ - + - + + @@ -20,10 +21,9 @@ - - + @@ -39,13 +39,13 @@ - + - + - + @@ -60,9 +60,15 @@ @@ -73,9 +79,14 @@ + + + + + @@ -98,15 +109,26 @@ + + + + + @@ -135,22 +157,33 @@ + + + + + - + @@ -175,14 +208,25 @@ - - - - + + - + + @@ -256,7 +299,7 @@