diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..312d1f65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,68 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output diff --git a/README.md b/README.md index 73f60d6c..88870dba 100644 --- a/README.md +++ b/README.md @@ -81,3 +81,9 @@ Faça um fork desse desse repositório em seu Github e nos envie um Pull Request ### # Importante: não há prazo de entrega, faça com qualidade! # BOA SORTE! + +### Execução do projeto. + +* git clone em um repositorio local. +* Abrir workspace no Xcode +* Execute o projeto em dispositivo fisico para desfrutar do layout. diff --git a/SantanderTest/SantanderTest.xcodeproj/project.pbxproj b/SantanderTest/SantanderTest.xcodeproj/project.pbxproj new file mode 100644 index 00000000..3fa19e89 --- /dev/null +++ b/SantanderTest/SantanderTest.xcodeproj/project.pbxproj @@ -0,0 +1,765 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + A039D15B22C8DE1D001F8772 /* ScrollViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D15A22C8DE1D001F8772 /* ScrollViewExtension.swift */; }; + A039D15F22C8EA5F001F8772 /* ButtonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D15E22C8EA5F001F8772 /* ButtonTableViewCell.swift */; }; + A039D16122C8EA6E001F8772 /* InvestmentInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16022C8EA6E001F8772 /* InvestmentInfoTableViewCell.swift */; }; + A039D16322C8EFC2001F8772 /* ContactTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16222C8EFC2001F8772 /* ContactTableViewController.swift */; }; + A039D16622C8FEA1001F8772 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16522C8FEA1001F8772 /* LabelTableViewCell.swift */; }; + A039D16822C90620001F8772 /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16722C90620001F8772 /* TextFieldTableViewCell.swift */; }; + A039D16A22C908E8001F8772 /* CheckBoxTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16922C908E8001F8772 /* CheckBoxTableViewCell.swift */; }; + A039D16C22C90E1A001F8772 /* ImageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16B22C90E1A001F8772 /* ImageTableViewCell.swift */; }; + A039D16E22C957DF001F8772 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039D16D22C957DF001F8772 /* StringExtension.swift */; }; + A08FFCFC22C6D0B50087F29A /* SantanderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08FFCFB22C6D0B50087F29A /* SantanderAPI.swift */; }; + A08FFCFE22C6DA3A0087F29A /* InvestmentScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08FFCFD22C6DA3A0087F29A /* InvestmentScreen.swift */; }; + A08FFD0022C78D5C0087F29A /* ContactScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08FFCFF22C78D5C0087F29A /* ContactScreen.swift */; }; + A08FFD0422C7CFF30087F29A /* FloatExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08FFD0322C7CFF30087F29A /* FloatExtension.swift */; }; + A0CBACFC22C7E72400B66CDB /* InvestmentDownInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0CBACFB22C7E72400B66CDB /* InvestmentDownInfoTableViewCell.swift */; }; + A0CBACFE22C8005800B66CDB /* InvestmentTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0CBACFD22C8005800B66CDB /* InvestmentTableViewController.swift */; }; + A0CBAD0222C8043100B66CDB /* InvestmentStaticInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0CBAD0122C8043100B66CDB /* InvestmentStaticInfoTableViewCell.swift */; }; + A0D4321022C597D500E116EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4320F22C597D500E116EE /* AppDelegate.swift */; }; + A0D4321722C597D500E116EE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A0D4321522C597D500E116EE /* Main.storyboard */; }; + A0D4321922C597D700E116EE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0D4321822C597D700E116EE /* Assets.xcassets */; }; + A0D4321C22C597D700E116EE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A0D4321A22C597D700E116EE /* LaunchScreen.storyboard */; }; + A0D4322722C597D700E116EE /* SantanderTestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4322622C597D700E116EE /* SantanderTestTests.swift */; }; + A0D4323222C597D700E116EE /* SantanderTestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4323122C597D700E116EE /* SantanderTestUITests.swift */; }; + A0D4324022C59D0F00E116EE /* CustomTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4323F22C59D0F00E116EE /* CustomTabBarController.swift */; }; + A0D4324922C6B28200E116EE /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4324822C6B28200E116EE /* UIImageExtension.swift */; }; + A0D4324B22C6BC4800E116EE /* FinishContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D4324A22C6BC4800E116EE /* FinishContactViewController.swift */; }; + A0D4326822C6C37000E116EE /* DINPro-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4325F22C6C36F00E116EE /* DINPro-Regular.otf */; }; + A0D4326922C6C37000E116EE /* DINNeuzeitGroteskStd-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326022C6C36F00E116EE /* DINNeuzeitGroteskStd-Light.otf */; }; + A0D4326A22C6C37000E116EE /* DINPro-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326122C6C36F00E116EE /* DINPro-Medium.otf */; }; + A0D4326B22C6C37000E116EE /* DINPro-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326222C6C36F00E116EE /* DINPro-Bold.otf */; }; + A0D4326C22C6C37000E116EE /* DINNeuzeitGroteskStd-BdCond.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326322C6C36F00E116EE /* DINNeuzeitGroteskStd-BdCond.otf */; }; + A0D4326D22C6C37000E116EE /* DINEngschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326422C6C36F00E116EE /* DINEngschriftStd.otf */; }; + A0D4326E22C6C37000E116EE /* DINMittelschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326522C6C36F00E116EE /* DINMittelschriftStd.otf */; }; + A0D4326F22C6C37000E116EE /* DINPro-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326622C6C36F00E116EE /* DINPro-Black.otf */; }; + A0D4327022C6C37000E116EE /* DINPro-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = A0D4326722C6C37000E116EE /* DINPro-Light.otf */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + A0D4322322C597D700E116EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A0D4320422C597D500E116EE /* Project object */; + proxyType = 1; + remoteGlobalIDString = A0D4320B22C597D500E116EE; + remoteInfo = SantanderTest; + }; + A0D4322E22C597D700E116EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A0D4320422C597D500E116EE /* Project object */; + proxyType = 1; + remoteGlobalIDString = A0D4320B22C597D500E116EE; + remoteInfo = SantanderTest; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + A039D15A22C8DE1D001F8772 /* ScrollViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewExtension.swift; sourceTree = ""; }; + A039D15E22C8EA5F001F8772 /* ButtonTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonTableViewCell.swift; sourceTree = ""; }; + A039D16022C8EA6E001F8772 /* InvestmentInfoTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvestmentInfoTableViewCell.swift; sourceTree = ""; }; + A039D16222C8EFC2001F8772 /* ContactTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactTableViewController.swift; sourceTree = ""; }; + A039D16522C8FEA1001F8772 /* LabelTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelTableViewCell.swift; sourceTree = ""; }; + A039D16722C90620001F8772 /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = ""; }; + A039D16922C908E8001F8772 /* CheckBoxTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckBoxTableViewCell.swift; sourceTree = ""; }; + A039D16B22C90E1A001F8772 /* ImageTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTableViewCell.swift; sourceTree = ""; }; + A039D16D22C957DF001F8772 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; }; + A08FFCFB22C6D0B50087F29A /* SantanderAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SantanderAPI.swift; sourceTree = ""; }; + A08FFCFD22C6DA3A0087F29A /* InvestmentScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvestmentScreen.swift; sourceTree = ""; }; + A08FFCFF22C78D5C0087F29A /* ContactScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactScreen.swift; sourceTree = ""; }; + A08FFD0322C7CFF30087F29A /* FloatExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatExtension.swift; sourceTree = ""; }; + A0CBACFB22C7E72400B66CDB /* InvestmentDownInfoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvestmentDownInfoTableViewCell.swift; sourceTree = ""; }; + A0CBACFD22C8005800B66CDB /* InvestmentTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvestmentTableViewController.swift; sourceTree = ""; }; + A0CBAD0122C8043100B66CDB /* InvestmentStaticInfoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvestmentStaticInfoTableViewCell.swift; sourceTree = ""; }; + A0D4320C22C597D500E116EE /* SantanderTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SantanderTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A0D4320F22C597D500E116EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A0D4321622C597D500E116EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A0D4321822C597D700E116EE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A0D4321B22C597D700E116EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + A0D4321D22C597D700E116EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A0D4322222C597D700E116EE /* SantanderTestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SantanderTestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A0D4322622C597D700E116EE /* SantanderTestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SantanderTestTests.swift; sourceTree = ""; }; + A0D4322822C597D700E116EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A0D4322D22C597D700E116EE /* SantanderTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SantanderTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A0D4323122C597D700E116EE /* SantanderTestUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SantanderTestUITests.swift; sourceTree = ""; }; + A0D4323322C597D700E116EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A0D4323F22C59D0F00E116EE /* CustomTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabBarController.swift; sourceTree = ""; }; + A0D4324822C6B28200E116EE /* UIImageExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = ""; }; + A0D4324A22C6BC4800E116EE /* FinishContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinishContactViewController.swift; sourceTree = ""; }; + A0D4325F22C6C36F00E116EE /* DINPro-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Regular.otf"; sourceTree = ""; }; + A0D4326022C6C36F00E116EE /* DINNeuzeitGroteskStd-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-Light.otf"; sourceTree = ""; }; + A0D4326122C6C36F00E116EE /* DINPro-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Medium.otf"; sourceTree = ""; }; + A0D4326222C6C36F00E116EE /* DINPro-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Bold.otf"; sourceTree = ""; }; + A0D4326322C6C36F00E116EE /* DINNeuzeitGroteskStd-BdCond.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-BdCond.otf"; sourceTree = ""; }; + A0D4326422C6C36F00E116EE /* DINEngschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINEngschriftStd.otf; sourceTree = ""; }; + A0D4326522C6C36F00E116EE /* DINMittelschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINMittelschriftStd.otf; sourceTree = ""; }; + A0D4326622C6C36F00E116EE /* DINPro-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Black.otf"; sourceTree = ""; }; + A0D4326722C6C37000E116EE /* DINPro-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Light.otf"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A0D4320922C597D500E116EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4321F22C597D700E116EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4322A22C597D700E116EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A039D16422C8FDFC001F8772 /* View */ = { + isa = PBXGroup; + children = ( + A039D16522C8FEA1001F8772 /* LabelTableViewCell.swift */, + A039D16722C90620001F8772 /* TextFieldTableViewCell.swift */, + A039D16922C908E8001F8772 /* CheckBoxTableViewCell.swift */, + A039D16B22C90E1A001F8772 /* ImageTableViewCell.swift */, + ); + path = View; + sourceTree = ""; + }; + A0CBACFA22C7E6F800B66CDB /* View */ = { + isa = PBXGroup; + children = ( + A0CBAD0122C8043100B66CDB /* InvestmentStaticInfoTableViewCell.swift */, + A039D16022C8EA6E001F8772 /* InvestmentInfoTableViewCell.swift */, + A0CBACFB22C7E72400B66CDB /* InvestmentDownInfoTableViewCell.swift */, + A039D15E22C8EA5F001F8772 /* ButtonTableViewCell.swift */, + ); + path = View; + sourceTree = ""; + }; + A0D4320322C597D500E116EE = { + isa = PBXGroup; + children = ( + A0D4320E22C597D500E116EE /* SantanderTest */, + A0D4322522C597D700E116EE /* SantanderTestTests */, + A0D4323022C597D700E116EE /* SantanderTestUITests */, + A0D4320D22C597D500E116EE /* Products */, + ); + sourceTree = ""; + }; + A0D4320D22C597D500E116EE /* Products */ = { + isa = PBXGroup; + children = ( + A0D4320C22C597D500E116EE /* SantanderTest.app */, + A0D4322222C597D700E116EE /* SantanderTestTests.xctest */, + A0D4322D22C597D700E116EE /* SantanderTestUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + A0D4320E22C597D500E116EE /* SantanderTest */ = { + isa = PBXGroup; + children = ( + A0D4324322C6B16800E116EE /* InvestmentFlow */, + A0D4324522C6B18800E116EE /* ContactFlow */, + A0D4324722C6B25800E116EE /* Utils */, + A0D4320F22C597D500E116EE /* AppDelegate.swift */, + A0D4321522C597D500E116EE /* Main.storyboard */, + A0D4321822C597D700E116EE /* Assets.xcassets */, + A0D4321A22C597D700E116EE /* LaunchScreen.storyboard */, + A0D4321D22C597D700E116EE /* Info.plist */, + A08FFCFB22C6D0B50087F29A /* SantanderAPI.swift */, + A0D4323F22C59D0F00E116EE /* CustomTabBarController.swift */, + ); + path = SantanderTest; + sourceTree = ""; + }; + A0D4322522C597D700E116EE /* SantanderTestTests */ = { + isa = PBXGroup; + children = ( + A0D4322622C597D700E116EE /* SantanderTestTests.swift */, + A0D4322822C597D700E116EE /* Info.plist */, + ); + path = SantanderTestTests; + sourceTree = ""; + }; + A0D4323022C597D700E116EE /* SantanderTestUITests */ = { + isa = PBXGroup; + children = ( + A0D4323122C597D700E116EE /* SantanderTestUITests.swift */, + A0D4323322C597D700E116EE /* Info.plist */, + ); + path = SantanderTestUITests; + sourceTree = ""; + }; + A0D4324322C6B16800E116EE /* InvestmentFlow */ = { + isa = PBXGroup; + children = ( + A0D4324422C6B17500E116EE /* Model */, + A0CBACFA22C7E6F800B66CDB /* View */, + A0CBACFD22C8005800B66CDB /* InvestmentTableViewController.swift */, + ); + path = InvestmentFlow; + sourceTree = ""; + }; + A0D4324422C6B17500E116EE /* Model */ = { + isa = PBXGroup; + children = ( + A08FFCFD22C6DA3A0087F29A /* InvestmentScreen.swift */, + ); + path = Model; + sourceTree = ""; + }; + A0D4324522C6B18800E116EE /* ContactFlow */ = { + isa = PBXGroup; + children = ( + A0D4324622C6B23100E116EE /* Model */, + A039D16422C8FDFC001F8772 /* View */, + A039D16222C8EFC2001F8772 /* ContactTableViewController.swift */, + A0D4324A22C6BC4800E116EE /* FinishContactViewController.swift */, + ); + path = ContactFlow; + sourceTree = ""; + }; + A0D4324622C6B23100E116EE /* Model */ = { + isa = PBXGroup; + children = ( + A08FFCFF22C78D5C0087F29A /* ContactScreen.swift */, + ); + path = Model; + sourceTree = ""; + }; + A0D4324722C6B25800E116EE /* Utils */ = { + isa = PBXGroup; + children = ( + A0D4324C22C6C33000E116EE /* Fonts */, + A0D4324822C6B28200E116EE /* UIImageExtension.swift */, + A08FFD0322C7CFF30087F29A /* FloatExtension.swift */, + A039D15A22C8DE1D001F8772 /* ScrollViewExtension.swift */, + A039D16D22C957DF001F8772 /* StringExtension.swift */, + ); + path = Utils; + sourceTree = ""; + }; + A0D4324C22C6C33000E116EE /* Fonts */ = { + isa = PBXGroup; + children = ( + A0D4326422C6C36F00E116EE /* DINEngschriftStd.otf */, + A0D4326522C6C36F00E116EE /* DINMittelschriftStd.otf */, + A0D4326322C6C36F00E116EE /* DINNeuzeitGroteskStd-BdCond.otf */, + A0D4326022C6C36F00E116EE /* DINNeuzeitGroteskStd-Light.otf */, + A0D4326622C6C36F00E116EE /* DINPro-Black.otf */, + A0D4326222C6C36F00E116EE /* DINPro-Bold.otf */, + A0D4326722C6C37000E116EE /* DINPro-Light.otf */, + A0D4326122C6C36F00E116EE /* DINPro-Medium.otf */, + A0D4325F22C6C36F00E116EE /* DINPro-Regular.otf */, + ); + path = Fonts; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A0D4320B22C597D500E116EE /* SantanderTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = A0D4323622C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTest" */; + buildPhases = ( + A0D4320822C597D500E116EE /* Sources */, + A0D4320922C597D500E116EE /* Frameworks */, + A0D4320A22C597D500E116EE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SantanderTest; + productName = SantanderTest; + productReference = A0D4320C22C597D500E116EE /* SantanderTest.app */; + productType = "com.apple.product-type.application"; + }; + A0D4322122C597D700E116EE /* SantanderTestTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A0D4323922C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTestTests" */; + buildPhases = ( + A0D4321E22C597D700E116EE /* Sources */, + A0D4321F22C597D700E116EE /* Frameworks */, + A0D4322022C597D700E116EE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A0D4322422C597D700E116EE /* PBXTargetDependency */, + ); + name = SantanderTestTests; + productName = SantanderTestTests; + productReference = A0D4322222C597D700E116EE /* SantanderTestTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + A0D4322C22C597D700E116EE /* SantanderTestUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A0D4323C22C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTestUITests" */; + buildPhases = ( + A0D4322922C597D700E116EE /* Sources */, + A0D4322A22C597D700E116EE /* Frameworks */, + A0D4322B22C597D700E116EE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A0D4322F22C597D700E116EE /* PBXTargetDependency */, + ); + name = SantanderTestUITests; + productName = SantanderTestUITests; + productReference = A0D4322D22C597D700E116EE /* SantanderTestUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A0D4320422C597D500E116EE /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1020; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Filipe Oliveira"; + TargetAttributes = { + A0D4320B22C597D500E116EE = { + CreatedOnToolsVersion = 10.2.1; + }; + A0D4322122C597D700E116EE = { + CreatedOnToolsVersion = 10.2.1; + TestTargetID = A0D4320B22C597D500E116EE; + }; + A0D4322C22C597D700E116EE = { + CreatedOnToolsVersion = 10.2.1; + TestTargetID = A0D4320B22C597D500E116EE; + }; + }; + }; + buildConfigurationList = A0D4320722C597D500E116EE /* Build configuration list for PBXProject "SantanderTest" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A0D4320322C597D500E116EE; + productRefGroup = A0D4320D22C597D500E116EE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A0D4320B22C597D500E116EE /* SantanderTest */, + A0D4322122C597D700E116EE /* SantanderTestTests */, + A0D4322C22C597D700E116EE /* SantanderTestUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A0D4320A22C597D500E116EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A0D4326822C6C37000E116EE /* DINPro-Regular.otf in Resources */, + A0D4321C22C597D700E116EE /* LaunchScreen.storyboard in Resources */, + A0D4326922C6C37000E116EE /* DINNeuzeitGroteskStd-Light.otf in Resources */, + A0D4326D22C6C37000E116EE /* DINEngschriftStd.otf in Resources */, + A0D4326E22C6C37000E116EE /* DINMittelschriftStd.otf in Resources */, + A0D4321922C597D700E116EE /* Assets.xcassets in Resources */, + A0D4326B22C6C37000E116EE /* DINPro-Bold.otf in Resources */, + A0D4326A22C6C37000E116EE /* DINPro-Medium.otf in Resources */, + A0D4327022C6C37000E116EE /* DINPro-Light.otf in Resources */, + A0D4326F22C6C37000E116EE /* DINPro-Black.otf in Resources */, + A0D4326C22C6C37000E116EE /* DINNeuzeitGroteskStd-BdCond.otf in Resources */, + A0D4321722C597D500E116EE /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4322022C597D700E116EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4322B22C597D700E116EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A0D4320822C597D500E116EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A0CBAD0222C8043100B66CDB /* InvestmentStaticInfoTableViewCell.swift in Sources */, + A08FFCFE22C6DA3A0087F29A /* InvestmentScreen.swift in Sources */, + A08FFD0422C7CFF30087F29A /* FloatExtension.swift in Sources */, + A039D15B22C8DE1D001F8772 /* ScrollViewExtension.swift in Sources */, + A039D15F22C8EA5F001F8772 /* ButtonTableViewCell.swift in Sources */, + A039D16A22C908E8001F8772 /* CheckBoxTableViewCell.swift in Sources */, + A039D16122C8EA6E001F8772 /* InvestmentInfoTableViewCell.swift in Sources */, + A0D4321022C597D500E116EE /* AppDelegate.swift in Sources */, + A0D4324B22C6BC4800E116EE /* FinishContactViewController.swift in Sources */, + A08FFD0022C78D5C0087F29A /* ContactScreen.swift in Sources */, + A039D16622C8FEA1001F8772 /* LabelTableViewCell.swift in Sources */, + A0D4324022C59D0F00E116EE /* CustomTabBarController.swift in Sources */, + A039D16E22C957DF001F8772 /* StringExtension.swift in Sources */, + A0CBACFE22C8005800B66CDB /* InvestmentTableViewController.swift in Sources */, + A0CBACFC22C7E72400B66CDB /* InvestmentDownInfoTableViewCell.swift in Sources */, + A08FFCFC22C6D0B50087F29A /* SantanderAPI.swift in Sources */, + A039D16822C90620001F8772 /* TextFieldTableViewCell.swift in Sources */, + A039D16C22C90E1A001F8772 /* ImageTableViewCell.swift in Sources */, + A0D4324922C6B28200E116EE /* UIImageExtension.swift in Sources */, + A039D16322C8EFC2001F8772 /* ContactTableViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4321E22C597D700E116EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A0D4322722C597D700E116EE /* SantanderTestTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0D4322922C597D700E116EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A0D4323222C597D700E116EE /* SantanderTestUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + A0D4322422C597D700E116EE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A0D4320B22C597D500E116EE /* SantanderTest */; + targetProxy = A0D4322322C597D700E116EE /* PBXContainerItemProxy */; + }; + A0D4322F22C597D700E116EE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A0D4320B22C597D500E116EE /* SantanderTest */; + targetProxy = A0D4322E22C597D700E116EE /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + A0D4321522C597D500E116EE /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A0D4321622C597D500E116EE /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + A0D4321A22C597D700E116EE /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A0D4321B22C597D700E116EE /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A0D4323422C597D700E116EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 12.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A0D4323522C597D700E116EE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 12.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A0D4323722C597D700E116EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + A0D4323822C597D700E116EE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + A0D4323A22C597D700E116EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTestTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTestTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SantanderTest.app/SantanderTest"; + }; + name = Debug; + }; + A0D4323B22C597D700E116EE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTestTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTestTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SantanderTest.app/SantanderTest"; + }; + name = Release; + }; + A0D4323D22C597D700E116EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SantanderTest; + }; + name = Debug; + }; + A0D4323E22C597D700E116EE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = QDM8KY5J4B; + INFOPLIST_FILE = SantanderTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.fdso.SantanderTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SantanderTest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A0D4320722C597D500E116EE /* Build configuration list for PBXProject "SantanderTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A0D4323422C597D700E116EE /* Debug */, + A0D4323522C597D700E116EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A0D4323622C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A0D4323722C597D700E116EE /* Debug */, + A0D4323822C597D700E116EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A0D4323922C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTestTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A0D4323A22C597D700E116EE /* Debug */, + A0D4323B22C597D700E116EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A0D4323C22C597D700E116EE /* Build configuration list for PBXNativeTarget "SantanderTestUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A0D4323D22C597D700E116EE /* Debug */, + A0D4323E22C597D700E116EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A0D4320422C597D500E116EE /* Project object */; +} diff --git a/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..7432e55c --- /dev/null +++ b/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/SantanderTest/SantanderTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/SantanderTest/SantanderTest/AppDelegate.swift b/SantanderTest/SantanderTest/AppDelegate.swift new file mode 100644 index 00000000..e39888b7 --- /dev/null +++ b/SantanderTest/SantanderTest/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// SantanderTest +// +// Created by Filipe Oliveira on 27/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/SantanderTest/SantanderTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/Contents.json new file mode 100644 index 00000000..d95ee239 --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "checked_checkbox@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/checked_checkbox@2x.png b/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/checked_checkbox@2x.png new file mode 100644 index 00000000..f29e3b68 Binary files /dev/null and b/SantanderTest/SantanderTest/Assets.xcassets/checked_checkbox.imageset/checked_checkbox@2x.png differ diff --git a/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/Contents.json new file mode 100644 index 00000000..4daf64e6 --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "download@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/download@2x.png b/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/download@2x.png new file mode 100644 index 00000000..543b2225 Binary files /dev/null and b/SantanderTest/SantanderTest/Assets.xcassets/download.imageset/download@2x.png differ diff --git a/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/Contents.json new file mode 100644 index 00000000..24afa3a4 --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "expand_arrow@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/expand_arrow@2x.png b/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/expand_arrow@2x.png new file mode 100644 index 00000000..ad8d8701 Binary files /dev/null and b/SantanderTest/SantanderTest/Assets.xcassets/expand_arrow.imageset/expand_arrow@2x.png differ diff --git a/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/Contents.json b/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/Contents.json new file mode 100644 index 00000000..e5b03851 --- /dev/null +++ b/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "unchecked_checkbox@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/unchecked_checkbox@2x.png b/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/unchecked_checkbox@2x.png new file mode 100644 index 00000000..8dd7a471 Binary files /dev/null and b/SantanderTest/SantanderTest/Assets.xcassets/unchecked_checkbox.imageset/unchecked_checkbox@2x.png differ diff --git a/SantanderTest/SantanderTest/Base.lproj/LaunchScreen.storyboard b/SantanderTest/SantanderTest/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..bfa36129 --- /dev/null +++ b/SantanderTest/SantanderTest/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SantanderTest/SantanderTest/Base.lproj/Main.storyboard b/SantanderTest/SantanderTest/Base.lproj/Main.storyboard new file mode 100644 index 00000000..845cdbe9 --- /dev/null +++ b/SantanderTest/SantanderTest/Base.lproj/Main.storyboard @@ -0,0 +1,866 @@ + + + + + + + + + + + + + + DINPro-Medium + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SantanderTest/SantanderTest/ContactFlow/ContactTableViewController.swift b/SantanderTest/SantanderTest/ContactFlow/ContactTableViewController.swift new file mode 100644 index 00000000..9e507b2d --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/ContactTableViewController.swift @@ -0,0 +1,317 @@ +// +// ContactTableViewController.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +extension ContactTableViewController: TextFieldCellDelegate +{ + func onEditing(text: String, type: CustomTypeField, id: Int) + { + tableView.scrollToRow(at: .init(row: 0, section: id), at: .bottom, animated: false) + + if type == .email + { + fields.email = text + } + else if type == .telNumber + { + fields.phone = text + } + else + { + fields.name = text + } + } +} + +extension ContactTableViewController: CheckBoxCellDelegate +{ + func onAction(isChecked: Bool, componentId: UInt8?) + { + if let index = model?.cells?.firstIndex(where: { $0.id == componentId }) + { + model?.cells?[index].hidden = !isChecked + + tableView.reloadData() + } + } +} + +extension ContactTableViewController: ButtonCellDelegate +{ + func onAction() + { + let requiredFields = model?.cells?.filter({ (cell) -> Bool in + + if let isRequired = cell.required, let isHidden = cell.hidden, isRequired, !isHidden, cell.typefield != nil + { + return true + } + + return false + }) + + if fields.name.isEmpty + { + if let index = model?.cells?.firstIndex(where: { (cell) -> Bool in + + if let typeField = cell.typefield, typeField == .text + { + return true + } + + return false + }) + { + if let cell = tableView.cellForRow(at: .init(row: 0, section: index)) as? TextFieldTableViewCell + { + cell.applyStatus(status: .error) + + tableView.scrollToRow(at: .init(row: 0, section: index), at: .bottom, animated: true) + } + } + + return + } + + // logica é a mesma +// if !fields.email.isValidEmail +// { +// return +// } +// +// if !fields.phone.isValidPhone +// { +// +// return +// } + + self.performSegue(withIdentifier: "ContactSegue", sender: nil) + +// fields = ("","","") +// +// model = originalModel +// +// tableView.reloadData() + } +} + +class ContactTableViewController: UITableViewController +{ + @IBOutlet var tryAgainButton: UIButton! + @IBOutlet var indicatorView: UIActivityIndicatorView! + + var fields: (name: String, email: String, phone: String) = ("","","") + + private var model: ContactScreen? + { + didSet + { + self.tableView.backgroundView = nil + } + } + + private var originalModel: ContactScreen? + + @IBAction func refreshAction() + { + Server_Request() + } + + override func viewDidLoad() + { + super.viewDidLoad() + + // Remove linha navigationBar + self.navigationController?.navigationBar.backIndicatorImage = .init() + self.navigationController?.navigationBar.isTranslucent = false + self.navigationController?.navigationBar.shadowImage = .init() + +// refreshAction() + } + + override func viewDidAppear(_ animated: Bool) + { + super.viewDidAppear(animated) + + refreshAction() + } + + override func numberOfSections(in tableView: UITableView) -> Int + { + return model?.cells?.count ?? 0 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int + { + return 1 + } + + override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat + { + if let component = model?.cells?[section], let height = component.topSpacing, let isHidden = component.hidden, !isHidden + { + return .init(height) + } + + return .zero + } + + override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? + { + let headerView: UIView = .init() + headerView.backgroundColor = .clear + + return headerView + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat + { + if let component = model?.cells?[indexPath.section], let isHidden = component.hidden, isHidden + { + return .zero + } + + return UITableView.automaticDimension + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + if let component = model?.cells?[indexPath.section], let type = component.type, let isHidden = component.hidden, !isHidden + { + if type == .text + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "TextCell", for: indexPath) as? LabelTableViewCell else + { + return .init() + } + + cell.applyContent(text: component.message) + + return cell + } + + if type == .field + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as? TextFieldTableViewCell, let typeField = component.typefield else + { + return .init() + } + + cell.delegate = self + + var text = "" + + if typeField == .email + { + text = fields.email + } + else if typeField == .telNumber + { + text = fields.phone + } + else + { + text = fields.name + } + + cell.applyContent(placeholder: component.message, text: text, type: component.typefield, id: indexPath.section) + + return cell + } + + if type == .checkbox + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "CheckBoxCell", for: indexPath) as? CheckBoxTableViewCell else + { + return .init() + } + + cell.delegate = self + cell.applyContent(text: component.message, id: component.show) + + return cell + } + + if type == .send + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as? ButtonTableViewCell else + { + return .init() + } + + cell.delegate = self + cell.applyContent(text: component.message) + + return cell + } + + if type == .image + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell", for: indexPath) as? ImageTableViewCell else + { + return .init() + } + + return cell + } + } + + return .init() + } + + private func Server_Request() + { + fields = ("","","") + + model = nil + + tableView.reloadData() + + if #available(iOS 10.0, *) + { + if let refreshControl = tableView.refreshControl, !refreshControl.isRefreshing + { + tableView.backgroundView = indicatorView + } + } + else + { + tableView.backgroundView = indicatorView + } + + SantanderApiClient.request(operation: .contactForm) { (response: Result) in + + DispatchQueue.main.async { + + if #available(iOS 10.0, *) + { + self.tableView.refreshControl?.endRefreshing() + } + + switch response + { + case .success(let result): + + self.originalModel = result + + self.model = result + + self.tableView.reloadData() + + case .failure(_): + + self.tableView.backgroundView = self.tryAgainButton + + } + + } + + } + } +} diff --git a/SantanderTest/SantanderTest/ContactFlow/FinishContactViewController.swift b/SantanderTest/SantanderTest/ContactFlow/FinishContactViewController.swift new file mode 100644 index 00000000..0240dffc --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/FinishContactViewController.swift @@ -0,0 +1,24 @@ +// +// FinishContactViewController.swift +// SantanderTest +// +// Created by Filipe Oliveira on 28/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class FinishContactViewController: UIViewController +{ + @IBAction func backAction() + { + self.navigationController?.popViewController(animated: false) + } + + override func viewDidLoad() + { + super.viewDidLoad() + + self.navigationItem.setHidesBackButton(true, animated: false) + } +} diff --git a/SantanderTest/SantanderTest/ContactFlow/Model/ContactScreen.swift b/SantanderTest/SantanderTest/ContactFlow/Model/ContactScreen.swift new file mode 100644 index 00000000..684b5d71 --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/Model/ContactScreen.swift @@ -0,0 +1,71 @@ +// +// ContactScreen.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import Foundation + +enum CustomTypeField: UInt8, Decodable +{ + case text = 1, telNumber, email +} + +struct ContactScreen: Decodable +{ + enum CustomType: UInt8, Decodable + { + case field = 1, text, image, checkbox, send + } + + struct Cells: Decodable + { + let id: UInt8? + let type: CustomType? + let message: String? + let typefield: CustomTypeField? + var hidden: Bool? + let topSpacing: Float? + let show: UInt8? + let required: Bool? + + enum CodingKeys: String, CodingKey + { + case id, type, message, typefield, hidden, topSpacing, show, required + } + + init(from decoder: Decoder) throws + { + let container = try decoder.container(keyedBy: CodingKeys.self) + + id = try? container.decode(UInt8.self, forKey: .id) + type = try? container.decode(CustomType.self, forKey: .type) + message = try? container.decode(String.self, forKey: .message) + + // conversão para tipo comum + if let value = try? container.decode(String.self, forKey: .typefield) + { + switch value.lowercased() + { + case "text": typefield = .text + case "telnumber": typefield = .telNumber + case "email": typefield = .email + default: typefield = nil + } + } + else + { + typefield = try? container.decode(CustomTypeField.self, forKey: .typefield) + } + + hidden = try? container.decode(Bool.self, forKey: .hidden) + topSpacing = try? container.decode(Float.self, forKey: .topSpacing) + show = try? container.decode(UInt8.self, forKey: .show) + required = try? container.decode(Bool.self, forKey: .required) + } + } + + var cells: [Cells]? +} diff --git a/SantanderTest/SantanderTest/ContactFlow/View/CheckBoxTableViewCell.swift b/SantanderTest/SantanderTest/ContactFlow/View/CheckBoxTableViewCell.swift new file mode 100644 index 00000000..87c37734 --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/View/CheckBoxTableViewCell.swift @@ -0,0 +1,47 @@ +// +// CheckBoxTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +protocol CheckBoxCellDelegate: NSObjectProtocol +{ + func onAction(isChecked: Bool, componentId: UInt8?) +} + +class CheckBoxTableViewCell: UITableViewCell +{ + @IBOutlet weak var actionButton: UIButton! + + weak var delegate: CheckBoxCellDelegate? + + private var componentId: UInt8? + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + @IBAction func buttonAction() + { + actionButton.setImage(actionButton.currentImage == #imageLiteral(resourceName: "unchecked_checkbox") ? #imageLiteral(resourceName: "checked_checkbox") : #imageLiteral(resourceName: "unchecked_checkbox"), for: .normal) + + delegate?.onAction(isChecked: actionButton.currentImage != #imageLiteral(resourceName: "unchecked_checkbox"), componentId: componentId) + } + + func applyContent(text: String?, id: UInt8? = nil) + { + actionButton.setTitle(text ?? "-", for: .normal) + + componentId = id + } +} diff --git a/SantanderTest/SantanderTest/ContactFlow/View/ImageTableViewCell.swift b/SantanderTest/SantanderTest/ContactFlow/View/ImageTableViewCell.swift new file mode 100644 index 00000000..c3aa71b3 --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/View/ImageTableViewCell.swift @@ -0,0 +1,24 @@ +// +// ImageTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class ImageTableViewCell: UITableViewCell +{ + @IBOutlet weak var anyImageView: UIImageView! + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } +} diff --git a/SantanderTest/SantanderTest/ContactFlow/View/LabelTableViewCell.swift b/SantanderTest/SantanderTest/ContactFlow/View/LabelTableViewCell.swift new file mode 100644 index 00000000..a2360a0d --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/View/LabelTableViewCell.swift @@ -0,0 +1,29 @@ +// +// LabelTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class LabelTableViewCell: UITableViewCell +{ + @IBOutlet weak var messageLabel: UILabel! + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + func applyContent(text: String?) + { + messageLabel.text = text ?? "-" + } +} diff --git a/SantanderTest/SantanderTest/ContactFlow/View/TextFieldTableViewCell.swift b/SantanderTest/SantanderTest/ContactFlow/View/TextFieldTableViewCell.swift new file mode 100644 index 00000000..1472f158 --- /dev/null +++ b/SantanderTest/SantanderTest/ContactFlow/View/TextFieldTableViewCell.swift @@ -0,0 +1,153 @@ +// +// TextFieldTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +protocol TextFieldCellDelegate: NSObjectProtocol +{ + func onEditing(text: String, type: CustomTypeField, id: Int) +} + +extension TextFieldTableViewCell: UITextFieldDelegate +{ + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool + { + if let text = textField.text, typeField == .telNumber + { + if string.isEmpty + { + applyStatus(status: .error) + + if text.count == 15 + { + return true + } + } + + if range.location == 14 || range.location == 15 + { + applyStatus(status: .ok) + } + + if text.count < 15 + { + nameTextField.text = text.maskPhone(pattern: "(##) #####-####", replacmentCharacter: "#") + + return true + } + + return false + } + + if let text = textField.text, typeField == .text + { + if text.count == 1 && string.isEmpty + { + applyStatus(status: .error) + } + else + { + applyStatus(status: .ok) + } + + return true + } + + if let text = textField.text, typeField == .email + { + if (text + string).isValidEmail + { + applyStatus(status: .ok) + } + else + { + applyStatus(status: .error) + } + } + + return true + } +} + +enum ColorTextFieldCell +{ + case normal, error, ok +} + +class TextFieldTableViewCell: UITableViewCell +{ + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var nameTextField: UITextField! + @IBOutlet weak var statusView: UIView! + + private var typeField: CustomTypeField! + { + didSet + { + if typeField == .email + { + nameTextField.keyboardType = .emailAddress + } + else if typeField == .telNumber + { + nameTextField.keyboardType = .numberPad + } + else + { + nameTextField.autocapitalizationType = .sentences + nameTextField.keyboardType = .default + } + } + } + + private var identifier: Int! + + weak var delegate: TextFieldCellDelegate? + + override func awakeFromNib() + { + super.awakeFromNib() + + nameTextField.delegate = self + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + @IBAction func editingChanged(_ sender: UITextField) + { + delegate?.onEditing(text: sender.text ?? "", type: typeField, id: identifier) + } + + func applyContent(placeholder: String?, text: String?, type: CustomTypeField?, id: Int) + { + nameLabel.text = placeholder ?? "-" + + nameTextField.text = text + + typeField = type ?? .text + + identifier = id + + applyStatus(status: .normal) + } + + func applyStatus(status: ColorTextFieldCell) + { + if status == .normal && nameTextField.text == nil + { + statusView.backgroundColor = #colorLiteral(red: 0.8374180198, green: 0.8374378085, blue: 0.8374271393, alpha: 1) + } + else + { + statusView.backgroundColor = status == .error ? #colorLiteral(red: 1, green: 0.1491314173, blue: 0, alpha: 1) : #colorLiteral(red: 0.6574365497, green: 0.8640290499, blue: 0.530384481, alpha: 1) + } + } +} diff --git a/SantanderTest/SantanderTest/CustomTabBarController.swift b/SantanderTest/SantanderTest/CustomTabBarController.swift new file mode 100644 index 00000000..1446501f --- /dev/null +++ b/SantanderTest/SantanderTest/CustomTabBarController.swift @@ -0,0 +1,61 @@ +// +// CustomTabBarController.swift +// SantanderTest +// +// Created by Filipe Oliveira on 27/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class CustomTabBarController: UITabBarController +{ + override func viewDidLoad() + { + super.viewDidLoad() + + tabBarAppearance() + + tabItemAppearance() + } + + private func tabBarAppearance() + { + // self.tabBar também server + let appearance = UITabBar.appearance(whenContainedInInstancesOf: [CustomTabBarController.self]) + + // Remove linha da TabBar + appearance.shadowImage = .init() + appearance.backgroundImage = .init() + + // Sobrepoe propriedade BarTintColor + appearance.backgroundColor = #colorLiteral(red: 1, green: 0.07238733253, blue: 0, alpha: 1) + + appearance.itemPositioning = .fill + appearance.itemSpacing = 0 + + // Calculo para criar imagem do tamanho BarItem + + var tabBarItemSize: CGSize = .init(width: self.tabBar.frame.width / CGFloat(self.tabBar.items?.count ?? 1), height: self.tabBar.frame.height + 10.0) + + // Correção para layout com SafeArea + if #available(iOS 11.0, *) + { + tabBarItemSize.height += UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0 + } + + // Efeito de selecao BarItem + appearance.selectionIndicatorImage = UIImage.imageWith(color: #colorLiteral(red: 0.7934507728, green: 0, blue: 0, alpha: 1), size: tabBarItemSize) + } + + private func tabItemAppearance() + { + let appearance = UITabBarItem.appearance(whenContainedInInstancesOf: [CustomTabBarController.self]) + + let attributes = [NSAttributedString.Key.font: UIFont(name: "DINPro-Medium", size: UIFont.systemFontSize) ?? UIFont.systemFont(ofSize: 40), NSAttributedString.Key.foregroundColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)] as [NSAttributedString.Key : Any] + + appearance.setTitleTextAttributes(attributes, for:.normal) + appearance.setTitleTextAttributes(attributes, for:.selected) + appearance.titlePositionAdjustment = .init(horizontal: 0, vertical: -16) + } +} diff --git a/SantanderTest/SantanderTest/Info.plist b/SantanderTest/SantanderTest/Info.plist new file mode 100644 index 00000000..3f47b7d3 --- /dev/null +++ b/SantanderTest/SantanderTest/Info.plist @@ -0,0 +1,65 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIAppFonts + + DINEngschriftStd.otf + DINMittelschriftStd.otf + DINNeuzeitGroteskStd-BdCond.otf + DINNeuzeitGroteskStd-Light.otf + DINPro-Black.otf + DINPro-Bold.otf + DINPro-Light.otf + DINPro-Medium.otf + DINPro-Regular.otf + + + diff --git a/SantanderTest/SantanderTest/InvestmentFlow/InvestmentTableViewController.swift b/SantanderTest/SantanderTest/InvestmentFlow/InvestmentTableViewController.swift new file mode 100644 index 00000000..69626079 --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/InvestmentTableViewController.swift @@ -0,0 +1,309 @@ +// +// InvestmentTableViewController.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit +import SafariServices + +extension InvestmentTableViewController: SFSafariViewControllerDelegate +{ + func safariViewControllerDidFinish(_ controller: SFSafariViewController) + { + controller.dismiss(animated: false) + } +} + +extension InvestmentTableViewController: InvestmentDownInfoCellDelegate +{ + func onDownload() + { + if let url = URL(string: "https://www.google.com") + { + let controller: SFSafariViewController = .init(url: url, entersReaderIfAvailable: true) + + controller.delegate = self + + self.present(controller, animated: false) + } + } +} + +extension InvestmentTableViewController: ButtonCellDelegate +{ + func onAction() + { + showAlert(title: "Filipe Oliveira", message: "Investimento feito com sucesso ;)") + } +} + +class InvestmentTableViewController: UITableViewController +{ + @IBOutlet var tryAgainButton: UIButton! + @IBOutlet var indicatorView: UIActivityIndicatorView! + + private var model: InvestmentScreen? + { + didSet + { + self.tableView.backgroundView = nil + + self.navigationItem.rightBarButtonItem?.isEnabled = model != nil + } + } + + @IBAction func shareAction(_ sender: UIBarButtonItem) + { + if let image = self.tableView.screenshot(correctionValue: 70) + { + let controller: UIActivityViewController = .init(activityItems: [image], applicationActivities: nil) + + self.present(controller, animated: true) + } + } + + @IBAction func reloadAction() + { + Server_Request() + } + + override func viewDidLoad() + { + super.viewDidLoad() + + // Remove linha navigationBar + self.navigationController?.navigationBar.backIndicatorImage = .init() + self.navigationController?.navigationBar.isTranslucent = false + self.navigationController?.navigationBar.shadowImage = .init() + + reloadAction() + } + +// override func viewDidAppear(_ animated: Bool) +// { +// super.viewDidAppear(animated) +// +// reloadAction() +// } + + override func numberOfSections(in tableView: UITableView) -> Int + { + var numberOfSections = 0 + + // Verifica se as estruturas possuem dados e exibe o que de fato existe + + if model != nil + { + numberOfSections = 2 // StaticInfoCell + ButtonCell + } + + if model?.screen?.info != nil + { + numberOfSections += 1 // + InfoCell + } + + if model?.screen?.downInfo != nil + { + numberOfSections += 1 // + DownInfoCell + } + + return numberOfSections + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int + { + // Verifica se as estruturas possuem dados e corrige o que é para ser exibido + + if section == 0 + { + return 1 + } + + if section == 1 + { + if model?.screen?.info != nil + { + return model?.screen?.info?.count ?? 0 + } + + if model?.screen?.downInfo != nil + { + return model?.screen?.downInfo?.count ?? 0 + } + + return 1 + } + + if section == 2 + { + if model?.screen?.info != nil && model?.screen?.downInfo != nil + { + return model?.screen?.downInfo?.count ?? 0 + } + + return 1 + } + + if section == 3 + { + return 1 + } + + return 0 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + // Verifica se as estruturas possuem dados e corrige o que é para ser exibido - mesma lógica do numberOfRowsInSection só que aqui cuidamos da contrução da cell + + if indexPath.section == 0 + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "StaticInfoCell", for: indexPath) as? InvestmentStaticInfoTableViewCell, let model = model else + { + return .init() + } + + cell.applyContent(model) + + return cell + } + else if indexPath.section == 1 + { + if let model = model?.screen?.info?[indexPath.row] + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "InfoCell", for: indexPath) as? InvestmentInfoTableViewCell else + { + return .init() + } + + cell.applyContent(name: model.name, data: model.data) + + return cell + } + + if let model = model?.screen?.downInfo?[indexPath.row] + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "DownInfoCell", for: indexPath) as? InvestmentDownInfoTableViewCell else + { + return .init() + } + + cell.applyContent(name: model.name, data: model.data) + cell.delegate = self + + return cell + } + + guard let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as? ButtonTableViewCell else + { + return .init() + } + + cell.delegate = self + + return cell + } + else if indexPath.section == 2 + { + if let downInfoModel = model?.screen?.downInfo?[indexPath.row], model?.screen?.info != nil + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "DownInfoCell", for: indexPath) as? InvestmentDownInfoTableViewCell else + { + return .init() + } + + cell.applyContent(name: downInfoModel.name, data: downInfoModel.data) + cell.delegate = self + + return cell + } + + guard let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as? ButtonTableViewCell else + { + return .init() + } + + cell.delegate = self + + return cell + } + else if indexPath.section == 3 + { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as? ButtonTableViewCell else + { + return .init() + } + + cell.applyContent(text: "Investir") + cell.delegate = self + + return cell + } + + return .init() + } + + private func Server_Request() + { + model = nil + + tableView.reloadData() + + if #available(iOS 10.0, *) + { + if let refreshControl = tableView.refreshControl, !refreshControl.isRefreshing + { + tableView.backgroundView = indicatorView + } + } + else + { + tableView.backgroundView = indicatorView + } + + SantanderApiClient.request(operation: .investiment) { (response: Result) in + + DispatchQueue.main.async { + + if #available(iOS 10.0, *) + { + self.tableView.refreshControl?.endRefreshing() + } + + switch response + { + case .success(let result): + + self.model = result + + // Teste para dados divergentes do Servidor +// self.model?.screen?.risk = 6 +// self.model?.screen?.moreInfo = nil +// self.model?.screen?.downInfo = nil +// self.model?.screen?.info = nil + + self.tableView.reloadData() + + case .failure(_): + + self.tableView.backgroundView = self.tryAgainButton + + } + + } + + } + } + + private func showAlert(title: String, message: String?) + { + let controller: UIAlertController = .init(title: title, message: message, preferredStyle: .alert) + controller.addAction(.init(title: "OK", style: .default)) + controller.view.tintColor = .red + + self.present(controller, animated: true) + } +} diff --git a/SantanderTest/SantanderTest/InvestmentFlow/Model/InvestmentScreen.swift b/SantanderTest/SantanderTest/InvestmentFlow/Model/InvestmentScreen.swift new file mode 100644 index 00000000..39389e84 --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/Model/InvestmentScreen.swift @@ -0,0 +1,62 @@ +// +// InvestmentScreen.swift +// SantanderTest +// +// Created by Filipe Oliveira on 28/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import Foundation + +struct InvestmentScreen: Decodable +{ + struct Screen: Decodable + { + struct MoreInfo: Decodable + { + struct FundCDI: Decodable + { + let fund: Float? + let cdi: Float? + + // nome de variavel com caixa alta =P + enum CodingKeys: String, CodingKey + { + case fund + case cdi = "CDI" + } + } + + var month: FundCDI? + var year: FundCDI? + var months: FundCDI? + + // nome de variavel iniciando com numero =P + enum CodingKeys: String, CodingKey + { + case month + case year + case months = "12months" + } + } + + struct Info: Decodable + { + let name: String? + let data: String? + } + + let title: String? + let fundName: String? + let whatIs: String? + let definition: String? + let riskTitle: String? + var risk: UInt8? // range de valor baixo + let infoTitle: String? + var moreInfo: MoreInfo? + var info: [Info]? + var downInfo: [Info]? + } + + var screen: Screen? +} diff --git a/SantanderTest/SantanderTest/InvestmentFlow/View/ButtonTableViewCell.swift b/SantanderTest/SantanderTest/InvestmentFlow/View/ButtonTableViewCell.swift new file mode 100644 index 00000000..ed11a79e --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/View/ButtonTableViewCell.swift @@ -0,0 +1,43 @@ +// +// ButtonTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +protocol ButtonCellDelegate: NSObjectProtocol +{ + func onAction() +} + +class ButtonTableViewCell: UITableViewCell +{ + @IBOutlet weak var actionButton: UIButton! + + weak var delegate: ButtonCellDelegate? + + @IBAction func buttonAction() + { + delegate?.onAction() + } + + override func awakeFromNib() + { + super.awakeFromNib() + + actionButton.layer.cornerRadius = 23 + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + func applyContent(text: String?) + { + actionButton.setTitle(text ?? "-", for: .normal) + } +} diff --git a/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentDownInfoTableViewCell.swift b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentDownInfoTableViewCell.swift new file mode 100644 index 00000000..d44e0d27 --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentDownInfoTableViewCell.swift @@ -0,0 +1,43 @@ +// +// InvestmentDownInfoTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +protocol InvestmentDownInfoCellDelegate: NSObjectProtocol +{ + func onDownload() +} + +class InvestmentDownInfoTableViewCell: UITableViewCell +{ + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var dataButton: UIButton! + + weak var delegate: InvestmentDownInfoCellDelegate? + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + @IBAction func downloadAction() + { + delegate?.onDownload() + } + + func applyContent(name: String?, data: String?) + { + nameLabel.text = name ?? "-" + dataButton.setTitle(data ?? "Baixar", for: .normal) + } +} diff --git a/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentInfoTableViewCell.swift b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentInfoTableViewCell.swift new file mode 100644 index 00000000..05c40b20 --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentInfoTableViewCell.swift @@ -0,0 +1,31 @@ +// +// InvestmentInfoTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class InvestmentInfoTableViewCell: UITableViewCell +{ + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var dataLabel: UILabel! + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + func applyContent(name: String?, data: String?) + { + nameLabel.text = name ?? "-" + dataLabel.text = data ?? "-" + } +} diff --git a/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentStaticInfoTableViewCell.swift b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentStaticInfoTableViewCell.swift new file mode 100644 index 00000000..5f0f01a2 --- /dev/null +++ b/SantanderTest/SantanderTest/InvestmentFlow/View/InvestmentStaticInfoTableViewCell.swift @@ -0,0 +1,82 @@ +// +// InvestmentStaticInfoTableViewCell.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +class InvestmentStaticInfoTableViewCell: UITableViewCell +{ + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var fundNameLabel: UILabel! + @IBOutlet weak var whatIsLabel: UILabel! + @IBOutlet weak var definitionLabel: UILabel! + @IBOutlet weak var riskTitleLabel: UILabel! + @IBOutlet weak var infoTitleLabel: UILabel! + + @IBOutlet weak var monthFundLabel: UILabel! + @IBOutlet weak var monthCdiLabel: UILabel! + @IBOutlet weak var yearFundLabel: UILabel! + @IBOutlet weak var yearCdiLabel: UILabel! + @IBOutlet weak var monthsFundLabel: UILabel! + @IBOutlet weak var monthsCdiLabel: UILabel! + + @IBOutlet weak var riskView: UIStackView! + + @IBOutlet weak var riskStackView: UIStackView! + @IBOutlet weak var moreInfoStackView: UIStackView! + @IBOutlet weak var monthStackView: UIStackView! + @IBOutlet weak var yearStackView: UIStackView! + @IBOutlet weak var monthsStackView: UIStackView! + + override func awakeFromNib() + { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) + { + super.setSelected(selected, animated: animated) + } + + func applyContent(_ model: InvestmentScreen) + { + titleLabel.text = model.screen?.title ?? "-" + fundNameLabel.text = model.screen?.fundName ?? "-" + whatIsLabel.text = model.screen?.whatIs ?? "-" + definitionLabel.text = model.screen?.definition ?? "-" + riskTitleLabel.text = model.screen?.riskTitle ?? "-" + infoTitleLabel.text = model.screen?.infoTitle ?? "-" + + // esconde a UI caso não venha dados + moreInfoStackView.isHidden = model.screen?.moreInfo == nil + monthStackView.isHidden = model.screen?.moreInfo?.month == nil + yearStackView.isHidden = model.screen?.moreInfo?.year == nil + monthsStackView.isHidden = model.screen?.moreInfo?.months == nil + + monthFundLabel.text = model.screen?.moreInfo?.month?.fund?.asPercent ?? "-" + monthCdiLabel.text = model.screen?.moreInfo?.month?.cdi?.asPercent ?? "-" + yearFundLabel.text = model.screen?.moreInfo?.year?.fund?.asPercent ?? "-" + yearCdiLabel.text = model.screen?.moreInfo?.year?.cdi?.asPercent ?? "-" + monthsFundLabel.text = model.screen?.moreInfo?.months?.fund?.asPercent ?? "-" + monthsCdiLabel.text = model.screen?.moreInfo?.months?.cdi?.asPercent ?? "-" + + if let risk = model.screen?.risk, risk >= 1 && risk <= 5 + { + riskStackView.isHidden = false + + let position = riskView.subviews[Int(risk) - 1] + + let imageView = position.subviews.first(where: {$0 is UIImageView}) as? UIImageView + + imageView?.image = #imageLiteral(resourceName: "expand_arrow") + } + else + { + riskStackView.isHidden = true + } + } +} diff --git a/SantanderTest/SantanderTest/SantanderAPI.swift b/SantanderTest/SantanderTest/SantanderAPI.swift new file mode 100644 index 00000000..e5925953 --- /dev/null +++ b/SantanderTest/SantanderTest/SantanderAPI.swift @@ -0,0 +1,170 @@ +// +// SantanderAPI.swift +// SantanderTest +// +// Created by Filipe Oliveira on 28/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import Foundation + +enum SantanderApiHost: String +{ + case test = "https://floating-mountain-50292.herokuapp.com/" +} + +enum SantanderApiPath: RawRepresentable +{ + enum HTTPMethod: String + { + case get = "GET"//, post = "POST" + } + + case investiment + case contactForm + + typealias RawValue = (items: [URLQueryItem], path: String, method: HTTPMethod) + + init?(rawValue: RawValue) + { + return nil + } + + var rawValue: RawValue + { +// var items = [URLQueryItem]() + + switch self + { + + case .investiment: + + do + { + return ([], "fund.json", .get) + } + + case .contactForm: + + do + { + return ([], "cells.json", .get) + } + +// case .other(let id): +// +// do +// { +// items.append(URLQueryItem(name: "any", value: String(id))) +// +// return (items, "test.json", .post) +// } + } + } +} + +final class SantanderApiClient +{ + static let host: SantanderApiHost = .test + +// static private let headers = ["Content-Type": "application/json"] + + static private var dataTask: URLSessionDataTask? + + static func cancelRequest() + { + dataTask?.cancel() + } + + static func request(operation: SantanderApiPath, completion: @escaping (Result) -> ()) + { + func debug(objects: [Any?]) + { + print("\n##########################################") + + print("\n 🔴 BASE - " + SantanderApiClient.host.rawValue.uppercased()) + + if let operation = objects.first(where: {$0 is SantanderApiPath.RawValue}) as? SantanderApiPath.RawValue + { + if let r = objects.first(where: {$0 is HTTPURLResponse}) as? HTTPURLResponse + { + print("\t⚫️ " + String(format: "%@ - %@ | %@ ( %@ )", arguments: [operation.method.rawValue, operation.path, String(r.statusCode), HTTPURLResponse.localizedString(forStatusCode: r.statusCode).capitalized])) + } + else + { + print("\t⚫️ " + String(format: "%@ - %@", arguments: [operation.method.rawValue, operation.path])) + } + } + + if let items = objects.first(where: {$0 is [URLQueryItem]}) as? [URLQueryItem] + { + print("\n 💙 JSON_SEND: \(items)") + } + + if let data = objects.first(where: {$0 is Data}) as? Data, let receiveData = String(data: data, encoding: .utf8) + { + print("\n 💚 JSON_RECV: \(receiveData)") + } + + if let e = objects.first(where: {$0 is NSError}) as? NSError + { + print("\n ⚠️ " + e.localizedDescription) + } + + print("\n##########################################\n") + } + + if var uCp = URLComponents(string: host.rawValue + operation.rawValue.path) + { + uCp.queryItems = operation.rawValue.items + + if let url = uCp.url + { + var uRq = URLRequest(url: url) + +// uRq.allHTTPHeaderFields = headers + uRq.httpMethod = operation.rawValue.method.rawValue + +// if operation.rawValue.method == .post +// { +// uRq.httpBody +// } + + let config: URLSessionConfiguration = .default + config.requestCachePolicy = .reloadIgnoringLocalCacheData + + dataTask = URLSession(configuration: config).dataTask(with: uRq) { (data, response, error) in + + debug(objects: [operation.rawValue, uCp.queryItems, data, response, error]) + + do + { + if let e = error as NSError? + { + completion(.failure(e)) + } + else + { + completion(.success(try JSONDecoder().decode(T.self, from: data ?? .init()))) + } + } + catch let e + { + completion(.failure(e as NSError)) + } + + } + + dataTask?.resume() + } + else + { + completion(.failure(.init(domain: "CUSTOM_ERROR", code: 0, userInfo: [NSLocalizedDescriptionKey: "URL Mal Formada!"]))) + } + } + else + { + completion(.failure(.init(domain: "CUSTOM_ERROR", code: 0, userInfo: [NSLocalizedDescriptionKey: "URL Mal Formada!"]))) + } + } +} diff --git a/SantanderTest/SantanderTest/Utils/FloatExtension.swift b/SantanderTest/SantanderTest/Utils/FloatExtension.swift new file mode 100644 index 00000000..892fff44 --- /dev/null +++ b/SantanderTest/SantanderTest/Utils/FloatExtension.swift @@ -0,0 +1,23 @@ +// +// FloatExtension.swift +// SantanderTest +// +// Created by Filipe Oliveira on 29/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import Foundation + +extension Float +{ + var asPercent: String? + { + let formatter: NumberFormatter = .init() + formatter.locale = .init(identifier: "PT-BR") + formatter.maximumFractionDigits = 2 + formatter.multiplier = 1 + formatter.numberStyle = .percent + + return formatter.string(from: .init(value: self)) + } +} diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINEngschriftStd.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINEngschriftStd.otf new file mode 100644 index 00000000..ae85f8ee Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINEngschriftStd.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINMittelschriftStd.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINMittelschriftStd.otf new file mode 100644 index 00000000..9a6e0d4f Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINMittelschriftStd.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-BdCond.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-BdCond.otf new file mode 100644 index 00000000..1da42b06 Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-BdCond.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-Light.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-Light.otf new file mode 100644 index 00000000..0cda2e5b Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINNeuzeitGroteskStd-Light.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Black.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Black.otf new file mode 100644 index 00000000..2092a7bb Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Black.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Bold.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Bold.otf new file mode 100644 index 00000000..7c839536 Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Bold.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Light.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Light.otf new file mode 100644 index 00000000..8a7f085a Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Light.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Medium.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Medium.otf new file mode 100644 index 00000000..b4608d06 Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Medium.otf differ diff --git a/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Regular.otf b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Regular.otf new file mode 100644 index 00000000..84d57abb Binary files /dev/null and b/SantanderTest/SantanderTest/Utils/Fonts/DINPro-Regular.otf differ diff --git a/SantanderTest/SantanderTest/Utils/ScrollViewExtension.swift b/SantanderTest/SantanderTest/Utils/ScrollViewExtension.swift new file mode 100644 index 00000000..cd0384bf --- /dev/null +++ b/SantanderTest/SantanderTest/Utils/ScrollViewExtension.swift @@ -0,0 +1,40 @@ +// +// ScrollViewExtension.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +extension UIScrollView +{ + func screenshot(correctionValue: CGFloat) -> UIImage? + { + let originalContentOffset = self.contentOffset + let originalFrame = self.frame + + var customContentSize = self.contentSize + customContentSize.height -= correctionValue + + UIGraphicsBeginImageContext(customContentSize) + self.contentOffset = .zero + self.frame = .init(origin: .zero, size: customContentSize) + + guard let context = UIGraphicsGetCurrentContext() else + { + return nil + } + + self.layer.render(in: context) + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + self.contentOffset = originalContentOffset + self.frame = originalFrame + + return image + } +} diff --git a/SantanderTest/SantanderTest/Utils/StringExtension.swift b/SantanderTest/SantanderTest/Utils/StringExtension.swift new file mode 100644 index 00000000..5925be8f --- /dev/null +++ b/SantanderTest/SantanderTest/Utils/StringExtension.swift @@ -0,0 +1,44 @@ +// +// StringExtension.swift +// SantanderTest +// +// Created by Filipe Oliveira on 30/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import Foundation + +extension String +{ + var isValidEmail: Bool + { + let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" + + return NSPredicate(format:"SELF MATCHES %@", emailRegex).evaluate(with: self) + } + + var isValidPhone: Bool + { +// let phoneRegex = "REGEX TELEFONE BR" + +// return NSPredicate(format:"SELF MATCHES %@", phoneRegex).evaluate(with: self) + + return true + } + + func maskPhone(pattern: String, replacmentCharacter: Character) -> String + { + var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression) + + for index in 0 ..< pattern.count + { + guard index < pureNumber.count else { return pureNumber } + let stringIndex = String.Index(encodedOffset: index) + let patternCharacter = pattern[stringIndex] + guard patternCharacter != replacmentCharacter else { continue } + pureNumber.insert(patternCharacter, at: stringIndex) + } + + return pureNumber + } +} diff --git a/SantanderTest/SantanderTest/Utils/UIImageExtension.swift b/SantanderTest/SantanderTest/Utils/UIImageExtension.swift new file mode 100644 index 00000000..668a58df --- /dev/null +++ b/SantanderTest/SantanderTest/Utils/UIImageExtension.swift @@ -0,0 +1,24 @@ +// +// UIImageExtension.swift +// SantanderTest +// +// Created by Filipe Oliveira on 28/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import UIKit + +extension UIImage +{ + class func imageWith(color: UIColor, size: CGSize) -> UIImage? + { + UIGraphicsBeginImageContextWithOptions(size, false, 0) + color.setFill() + UIRectFill(.init(origin: .zero, size: size)) + + let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return image + } +} diff --git a/SantanderTest/SantanderTestTests/Info.plist b/SantanderTest/SantanderTestTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/SantanderTest/SantanderTestTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/SantanderTest/SantanderTestTests/SantanderTestTests.swift b/SantanderTest/SantanderTestTests/SantanderTestTests.swift new file mode 100644 index 00000000..3590f3a9 --- /dev/null +++ b/SantanderTest/SantanderTestTests/SantanderTestTests.swift @@ -0,0 +1,38 @@ +// +// SantanderTestTests.swift +// SantanderTestTests +// +// Created by Filipe Oliveira on 27/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import XCTest +@testable import SantanderTest + +class SantanderTestTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + testExample() + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + + XCTAssertTrue("fdso@outlook.com".isValidEmail, "Email Correto") + XCTAssertFalse("fdso@outlook.c".isValidEmail, "Email Incorreto") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/SantanderTest/SantanderTestUITests/Info.plist b/SantanderTest/SantanderTestUITests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/SantanderTest/SantanderTestUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/SantanderTest/SantanderTestUITests/SantanderTestUITests.swift b/SantanderTest/SantanderTestUITests/SantanderTestUITests.swift new file mode 100644 index 00000000..9f034aa8 --- /dev/null +++ b/SantanderTest/SantanderTestUITests/SantanderTestUITests.swift @@ -0,0 +1,34 @@ +// +// SantanderTestUITests.swift +// SantanderTestUITests +// +// Created by Filipe Oliveira on 27/06/19. +// Copyright © 2019 Filipe Oliveira. All rights reserved. +// + +import XCTest + +class SantanderTestUITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +}