diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..4774569d --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# 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/ + +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +*.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. + +Carthage/ + +# 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 + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/.DS_Store diff --git a/TesteiOS/Gemfile b/TesteiOS/Gemfile new file mode 100755 index 00000000..44c02d0f --- /dev/null +++ b/TesteiOS/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +# gem "rails" +gem 'cocoapods' +gem 'cocoapods-keys' +gem 'slather' +gem 'fastlane' +gem 'danger' +gem 'danger-slather' diff --git a/TesteiOS/Gemfile.lock b/TesteiOS/Gemfile.lock new file mode 100644 index 00000000..e4a61c31 --- /dev/null +++ b/TesteiOS/Gemfile.lock @@ -0,0 +1,268 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.3.6) + RubyInline (3.12.4) + ZenTest (~> 4.3) + ZenTest (4.11.2) + activesupport (4.2.11) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + atomos (0.1.3) + babosa (1.0.2) + claide (1.0.2) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + clamp (0.6.5) + cocoapods (1.6.0) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.6.0) + cocoapods-deintegrate (>= 1.0.2, < 2.0) + cocoapods-downloader (>= 1.2.2, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-stats (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.3.1, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.2.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.6.6) + nap (~> 1.0) + ruby-macho (~> 1.3, >= 1.3.1) + xcodeproj (>= 1.8.0, < 2.0) + cocoapods-core (1.6.0) + activesupport (>= 4.0.2, < 6) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + cocoapods-deintegrate (1.0.2) + cocoapods-downloader (1.2.2) + cocoapods-keys (2.1.0) + dotenv + osx_keychain + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-stats (1.1.0) + cocoapods-trunk (1.3.1) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.1.0) + colored (1.2) + colored2 (3.1.2) + commander-fastlane (4.4.6) + highline (~> 1.7.2) + concurrent-ruby (1.1.4) + cork (0.3.0) + colored2 (~> 3.1) + danger (5.14.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (~> 0.9) + faraday-http-cache (~> 1.0) + git (~> 1.5) + kramdown (~> 1.5) + no_proxy_fix + octokit (~> 4.7) + terminal-table (~> 1) + danger-plugin-api (1.0.0) + danger (> 2.0) + danger-slather (0.0.6) + danger-plugin-api (~> 1.0) + slather (~> 2.3) + declarative (0.0.10) + declarative-option (0.1.0) + digest-crc (0.4.1) + domain_name (0.5.20180417) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.7.1) + emoji_regex (1.0.1) + escape (0.0.4) + excon (0.62.0) + faraday (0.15.4) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday-http-cache (1.3.1) + faraday (~> 0.8) + faraday_middleware (0.13.1) + faraday (>= 0.7.4, < 1.0) + fastimage (2.1.5) + fastlane (2.117.1) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.3, < 3.0.0) + babosa (>= 1.0.2, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander-fastlane (>= 4.4.6, < 5.0.0) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 2.0) + excon (>= 0.45.0, < 1.0.0) + faraday (~> 0.9) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.9) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-api-client (>= 0.21.2, < 0.24.0) + google-cloud-storage (>= 1.15.0, < 2.0.0) + highline (>= 1.7.2, < 2.0.0) + json (< 3.0.0) + mini_magick (~> 4.5.1) + multi_json + multi_xml (~> 0.5) + multipart-post (~> 2.0.0) + plist (>= 3.1.0, < 4.0.0) + public_suffix (~> 2.0.0) + rubyzip (>= 1.2.2, < 2.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + slack-notifier (>= 2.0.0, < 3.0.0) + terminal-notifier (>= 1.6.2, < 2.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.6.0, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + fourflusher (2.2.0) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + git (1.5.0) + google-api-client (0.23.9) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.5, < 0.7.0) + httpclient (>= 2.8.1, < 3.0) + mime-types (~> 3.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + signet (~> 0.9) + google-cloud-core (1.3.0) + google-cloud-env (~> 1.0) + google-cloud-env (1.0.5) + faraday (~> 0.11) + google-cloud-storage (1.16.0) + digest-crc (~> 0.4) + google-api-client (~> 0.23) + google-cloud-core (~> 1.2) + googleauth (>= 0.6.2, < 0.10.0) + googleauth (0.6.7) + faraday (~> 0.12) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (~> 0.7) + highline (1.7.10) + http-cookie (1.0.3) + domain_name (~> 0.5) + httpclient (2.8.3) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + json (2.2.0) + jwt (2.1.0) + kramdown (1.17.0) + memoist (0.16.0) + mime-types (3.2.2) + mime-types-data (~> 3.2015) + mime-types-data (3.2018.0812) + mini_magick (4.5.1) + mini_portile2 (2.3.0) + minitest (5.11.3) + molinillo (0.6.6) + multi_json (1.13.1) + multi_xml (0.6.0) + multipart-post (2.0.0) + nanaimo (0.2.6) + nap (1.1.0) + naturally (2.2.0) + netrc (0.11.0) + no_proxy_fix (0.1.2) + nokogiri (1.8.5) + mini_portile2 (~> 2.3.0) + octokit (4.13.0) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + os (1.0.0) + osx_keychain (1.0.2) + RubyInline (~> 3) + plist (3.5.0) + public_suffix (2.0.5) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rouge (2.0.7) + ruby-macho (1.3.1) + rubyzip (1.2.2) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + security (0.1.3) + signet (0.11.0) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.5) + CFPropertyList + naturally + slack-notifier (2.3.2) + slather (2.4.6) + CFPropertyList (~> 2.2) + activesupport (>= 4.0.2) + clamp (~> 0.6) + nokogiri (~> 1.8.2) + xcodeproj (~> 1.4) + terminal-notifier (1.8.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + tty-cursor (0.6.1) + tty-screen (0.6.5) + tty-spinner (0.9.0) + tty-cursor (~> 0.6.0) + tzinfo (1.2.5) + thread_safe (~> 0.1) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.5) + unicode-display_width (1.5.0) + word_wrap (1.0.0) + xcodeproj (1.8.1) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.6) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-travis-formatter (1.0.0) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods + cocoapods-keys + danger + danger-slather + fastlane + slather + +BUNDLED WITH + 2.0.1 diff --git a/TesteiOS/Podfile b/TesteiOS/Podfile new file mode 100644 index 00000000..7c8bbf64 --- /dev/null +++ b/TesteiOS/Podfile @@ -0,0 +1,27 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'TesteiOS' do + # Comment the next line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for Movs + pod 'Reusable' + pod 'SnapKit', '~> 4.0.0' + pod 'Moya' + pod "JMMaskTextField-Swift" + + target 'TesteiOSTests' do + inherit! :search_paths + # Pods for testing + pod 'Quick' + pod 'Nimble' + end + + #target 'TesteiOSUITests' do + inherit! :search_paths + # Pods for testing + #pod 'iOSSnapshotTestCase' + #end*/ + +end diff --git a/TesteiOS/Podfile.lock b/TesteiOS/Podfile.lock new file mode 100644 index 00000000..39a5d508 --- /dev/null +++ b/TesteiOS/Podfile.lock @@ -0,0 +1,50 @@ +PODS: + - Alamofire (4.8.0) + - JMMaskTextField-Swift (0.1.3) + - Moya (12.0.1): + - Moya/Core (= 12.0.1) + - Moya/Core (12.0.1): + - Alamofire (~> 4.1) + - Result (~> 4.0) + - Nimble (7.3.1) + - Quick (1.3.2) + - Result (4.1.0) + - Reusable (4.0.5): + - Reusable/Storyboard (= 4.0.5) + - Reusable/View (= 4.0.5) + - Reusable/Storyboard (4.0.5) + - Reusable/View (4.0.5) + - SnapKit (4.0.1) + +DEPENDENCIES: + - JMMaskTextField-Swift + - Moya + - Nimble + - Quick + - Reusable + - SnapKit (~> 4.0.0) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Alamofire + - JMMaskTextField-Swift + - Moya + - Nimble + - Quick + - Result + - Reusable + - SnapKit + +SPEC CHECKSUMS: + Alamofire: 3ec537f71edc9804815215393ae2b1a8ea33a844 + JMMaskTextField-Swift: 16aa552605b121285e6c2f0817ab31cea5f4704b + Moya: cf730b3cd9e005401ef37a85143aa141a12fd38f + Nimble: 04f732da099ea4d153122aec8c2a88fd0c7219ae + Quick: 2623cb30d7a7f41ca62f684f679586558f483d46 + Result: bd966fac789cc6c1563440b348ab2598cc24d5c7 + Reusable: 188be1a54ac0691bc66e5bb24ec6eb91971b315b + SnapKit: 0de968a9fec17499afa29683b05d0c775b6d1c29 + +PODFILE CHECKSUM: 150f7556c521bdbfbd19230f37d0c436fabe7925 + +COCOAPODS: 1.6.0 diff --git a/TesteiOS/TesteiOS.xcodeproj/project.pbxproj b/TesteiOS/TesteiOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..406cc68e --- /dev/null +++ b/TesteiOS/TesteiOS.xcodeproj/project.pbxproj @@ -0,0 +1,1318 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 65B2BB04221F121C009A5A7B /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB03221F121C009A5A7B /* TabBarViewController.swift */; }; + 65B2BB09221F1D1C009A5A7B /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB08221F1D1C009A5A7B /* TabBarView.swift */; }; + 65B2BB0B221F1D44009A5A7B /* ViewCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB0A221F1D44009A5A7B /* ViewCode.swift */; }; + 65B2BB0D221F252A009A5A7B /* TabBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB0C221F252A009A5A7B /* TabBarButton.swift */; }; + 65B2BB0F221F2750009A5A7B /* FontNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB0E221F2750009A5A7B /* FontNames.swift */; }; + 65B2BB18221F2AC9009A5A7B /* ContactPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB12221F2AC9009A5A7B /* ContactPresenter.swift */; }; + 65B2BB19221F2AC9009A5A7B /* ContactWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB13221F2AC9009A5A7B /* ContactWorker.swift */; }; + 65B2BB1A221F2AC9009A5A7B /* ContactRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB14221F2AC9009A5A7B /* ContactRouter.swift */; }; + 65B2BB1B221F2AC9009A5A7B /* ContactModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB15221F2AC9009A5A7B /* ContactModels.swift */; }; + 65B2BB1C221F2AC9009A5A7B /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB16221F2AC9009A5A7B /* ContactViewController.swift */; }; + 65B2BB1D221F2AC9009A5A7B /* ContactInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB17221F2AC9009A5A7B /* ContactInteractor.swift */; }; + 65B2BB24221F2ADD009A5A7B /* FundsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB1E221F2ADD009A5A7B /* FundsPresenter.swift */; }; + 65B2BB25221F2ADD009A5A7B /* FundsWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB1F221F2ADD009A5A7B /* FundsWorker.swift */; }; + 65B2BB26221F2ADD009A5A7B /* FundsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB20221F2ADD009A5A7B /* FundsRouter.swift */; }; + 65B2BB27221F2ADD009A5A7B /* FundsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB21221F2ADD009A5A7B /* FundsModels.swift */; }; + 65B2BB28221F2ADD009A5A7B /* FundsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB22221F2ADD009A5A7B /* FundsViewController.swift */; }; + 65B2BB29221F2ADD009A5A7B /* FundsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB23221F2ADD009A5A7B /* FundsInteractor.swift */; }; + 65B2BB2C221F31B4009A5A7B /* AppearanceProxyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB2B221F31B4009A5A7B /* AppearanceProxyHelper.swift */; }; + 65B2BB2E221F3342009A5A7B /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB2D221F3342009A5A7B /* ColorPalette.swift */; }; + 65B2BB31221F33FC009A5A7B /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB30221F33FC009A5A7B /* UIColor+Hex.swift */; }; + 65B2BB33221F4326009A5A7B /* ContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB32221F4326009A5A7B /* ContactView.swift */; }; + 65B2BB35221F4AAA009A5A7B /* ContactTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB34221F4AAA009A5A7B /* ContactTableView.swift */; }; + 65B2BB37221F9BC5009A5A7B /* ContactDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB36221F9BC5009A5A7B /* ContactDataSource.swift */; }; + 65B2BB39221F9BFE009A5A7B /* ContactDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB38221F9BFE009A5A7B /* ContactDelegate.swift */; }; + 65B2BB3B221F9DDB009A5A7B /* ItemsTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB3A221F9DDB009A5A7B /* ItemsTableViewDataSource.swift */; }; + 65B2BB3F221F9E45009A5A7B /* BankAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB3E221F9E45009A5A7B /* BankAPI.swift */; }; + 65B2BB41221F9F8E009A5A7B /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB40221F9F8E009A5A7B /* NetworkManager.swift */; }; + 65B2BB43221FA075009A5A7B /* BankAPI+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB42221FA075009A5A7B /* BankAPI+Testing.swift */; }; + 65B2BB45221FA2E7009A5A7B /* DefaultAlamofireManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB44221FA2E7009A5A7B /* DefaultAlamofireManager.swift */; }; + 65B2BB47221FA376009A5A7B /* FormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB46221FA376009A5A7B /* FormData.swift */; }; + 65B2BB49221FA385009A5A7B /* FundsData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB48221FA385009A5A7B /* FundsData.swift */; }; + 65B2BB4B221FA481009A5A7B /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB4A221FA481009A5A7B /* Cell.swift */; }; + 65B2BB5A221FAFDC009A5A7B /* FundHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB4C221FAFD8009A5A7B /* FundHeaderTableViewCell.swift */; }; + 65B2BB5B221FAFDC009A5A7B /* InfoTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB4D221FAFD9009A5A7B /* InfoTableViewCell.xib */; }; + 65B2BB5C221FAFDC009A5A7B /* DownInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB4E221FAFD9009A5A7B /* DownInfoTableViewCell.swift */; }; + 65B2BB5D221FAFDC009A5A7B /* InfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB4F221FAFD9009A5A7B /* InfoTableViewCell.swift */; }; + 65B2BB5E221FAFDC009A5A7B /* DownInfoTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB50221FAFDA009A5A7B /* DownInfoTableViewCell.xib */; }; + 65B2BB5F221FAFDC009A5A7B /* FundHeaderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB51221FAFDA009A5A7B /* FundHeaderTableViewCell.xib */; }; + 65B2BB61221FAFDC009A5A7B /* CheckboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB53221FAFDB009A5A7B /* CheckboxTableViewCell.xib */; }; + 65B2BB62221FAFDC009A5A7B /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB54221FAFDC009A5A7B /* TextFieldTableViewCell.swift */; }; + 65B2BB63221FAFDC009A5A7B /* SendTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB55221FAFDC009A5A7B /* SendTableViewCell.xib */; }; + 65B2BB64221FAFDC009A5A7B /* SendTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB56221FAFDC009A5A7B /* SendTableViewCell.swift */; }; + 65B2BB65221FAFDC009A5A7B /* TextFieldTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB57221FAFDC009A5A7B /* TextFieldTableViewCell.xib */; }; + 65B2BB67221FAFDC009A5A7B /* CheckboxTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB59221FAFDC009A5A7B /* CheckboxTableViewCell.swift */; }; + 65B2BB69221FB486009A5A7B /* TextTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB68221FB486009A5A7B /* TextTableViewCell.swift */; }; + 65B2BB6B221FB4AD009A5A7B /* TextTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB6A221FB4AD009A5A7B /* TextTableViewCell.xib */; }; + 65B2BB6D221FC02B009A5A7B /* ContactBaseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB6C221FC02B009A5A7B /* ContactBaseTableViewCell.swift */; }; + 65B2BB77221FEF54009A5A7B /* DINEngschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB6E221FEF53009A5A7B /* DINEngschriftStd.otf */; }; + 65B2BB78221FEF54009A5A7B /* DINPro-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB6F221FEF53009A5A7B /* DINPro-Light.otf */; }; + 65B2BB79221FEF54009A5A7B /* DINPro-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB70221FEF53009A5A7B /* DINPro-Medium.otf */; }; + 65B2BB7A221FEF54009A5A7B /* DINPro-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB71221FEF54009A5A7B /* DINPro-Black.otf */; }; + 65B2BB7B221FEF54009A5A7B /* DINNeuzeitGroteskStd-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB72221FEF54009A5A7B /* DINNeuzeitGroteskStd-Light.otf */; }; + 65B2BB7C221FEF54009A5A7B /* DINNeuzeitGroteskStd-BdCond.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB73221FEF54009A5A7B /* DINNeuzeitGroteskStd-BdCond.otf */; }; + 65B2BB7D221FEF54009A5A7B /* DINPro-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB74221FEF54009A5A7B /* DINPro-Bold.otf */; }; + 65B2BB7E221FEF54009A5A7B /* DINPro-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB75221FEF54009A5A7B /* DINPro-Regular.otf */; }; + 65B2BB7F221FEF54009A5A7B /* DINMittelschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB76221FEF54009A5A7B /* DINMittelschriftStd.otf */; }; + 65B2BB872221D411009A5A7B /* FeedbackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB862221D411009A5A7B /* FeedbackView.swift */; }; + 65B2BB892221D42A009A5A7B /* FeedbackView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BB882221D42A009A5A7B /* FeedbackView.xib */; }; + 65B2BB90222210BD009A5A7B /* Fund.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB8F222210BD009A5A7B /* Fund.swift */; }; + 65B2BB92222213E6009A5A7B /* MoreInfoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB91222213E6009A5A7B /* MoreInfoData.swift */; }; + 65B2BB9422221568009A5A7B /* Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB9322221568009A5A7B /* Info.swift */; }; + 65B2BB96222216CF009A5A7B /* MoreInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB95222216CF009A5A7B /* MoreInfo.swift */; }; + 65B2BB99222228F7009A5A7B /* FundsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB98222228F7009A5A7B /* FundsView.swift */; }; + 65B2BB9B22222A98009A5A7B /* FundsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB9A22222A98009A5A7B /* FundsDataSource.swift */; }; + 65B2BB9D22222AB3009A5A7B /* FundsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BB9C22222AB3009A5A7B /* FundsDelegate.swift */; }; + 65B2BBA122224B6A009A5A7B /* FundBaseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBA022224B6A009A5A7B /* FundBaseTableViewCell.swift */; }; + 65B2BBA322224F00009A5A7B /* FundsTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBA222224F00009A5A7B /* FundsTableView.swift */; }; + 65B2BBA822225520009A5A7B /* MoreInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBA622225520009A5A7B /* MoreInfoTableViewCell.swift */; }; + 65B2BBA922225520009A5A7B /* MoreInfoTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BBA722225520009A5A7B /* MoreInfoTableViewCell.xib */; }; + 65B2BBAB22226BAE009A5A7B /* RiskView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBAA22226BAE009A5A7B /* RiskView.swift */; }; + 65B2BBB32222A933009A5A7B /* InvestTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBB12222A933009A5A7B /* InvestTableViewCell.swift */; }; + 65B2BBB42222A933009A5A7B /* InvestTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BBB22222A933009A5A7B /* InvestTableViewCell.xib */; }; + 65B2BBB92223896C009A5A7B /* Fund.json in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BBB82223896C009A5A7B /* Fund.json */; }; + 65B2BBBB22238980009A5A7B /* Form.json in Resources */ = {isa = PBXBuildFile; fileRef = 65B2BBBA22238980009A5A7B /* Form.json */; }; + 65B2BBBF22238E5A009A5A7B /* FormDataSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBBE22238E5A009A5A7B /* FormDataSpec.swift */; }; + 65B2BBC2222390F6009A5A7B /* ContactDataSourceSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBC1222390F6009A5A7B /* ContactDataSourceSpec.swift */; }; + 65B2BBC622239D1C009A5A7B /* StringValidatorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBC522239D1C009A5A7B /* StringValidatorSpec.swift */; }; + 65B2BBCA2223A168009A5A7B /* ContactInteractSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2BBC92223A168009A5A7B /* ContactInteractSpec.swift */; }; + 65EF2626221CC3E500014212 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EF2625221CC3E500014212 /* AppDelegate.swift */; }; + 65EF262D221CC3E700014212 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65EF262C221CC3E700014212 /* Assets.xcassets */; }; + 65EF2630221CC3E700014212 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65EF262E221CC3E700014212 /* LaunchScreen.storyboard */; }; + 65EF2646221CC3E700014212 /* TesteiOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EF2645221CC3E700014212 /* TesteiOSUITests.swift */; }; + 65F791642223C5E400F1058A /* ContactWorkerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F791632223C5E400F1058A /* ContactWorkerSpec.swift */; }; + 65F791662223D01600F1058A /* FundsInteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F791652223D01600F1058A /* FundsInteractorSpec.swift */; }; + A56D8254223AA8B100A33990 /* String+Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A56D8253223AA8B100A33990 /* String+Validator.swift */; }; + BF30F532668E8706D861BA2D /* Pods_TesteiOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E53AA491062BDD9DF858AB8E /* Pods_TesteiOSTests.framework */; }; + DAC11BD224CBF944124D26B8 /* Pods_TesteiOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2C7FB9A50E98EBED4E7C177 /* Pods_TesteiOS.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 65EF2637221CC3E700014212 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 65EF261A221CC3E500014212 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 65EF2621221CC3E500014212; + remoteInfo = TesteiOS; + }; + 65EF2642221CC3E700014212 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 65EF261A221CC3E500014212 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 65EF2621221CC3E500014212; + remoteInfo = TesteiOS; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1C51913E040327570673FCE3 /* Pods-TesteiOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOSTests.release.xcconfig"; path = "Target Support Files/Pods-TesteiOSTests/Pods-TesteiOSTests.release.xcconfig"; sourceTree = ""; }; + 65B2BB03221F121C009A5A7B /* TabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = ""; }; + 65B2BB08221F1D1C009A5A7B /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; + 65B2BB0A221F1D44009A5A7B /* ViewCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewCode.swift; sourceTree = ""; }; + 65B2BB0C221F252A009A5A7B /* TabBarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarButton.swift; sourceTree = ""; }; + 65B2BB0E221F2750009A5A7B /* FontNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontNames.swift; sourceTree = ""; }; + 65B2BB12221F2AC9009A5A7B /* ContactPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPresenter.swift; sourceTree = ""; }; + 65B2BB13221F2AC9009A5A7B /* ContactWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactWorker.swift; sourceTree = ""; }; + 65B2BB14221F2AC9009A5A7B /* ContactRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactRouter.swift; sourceTree = ""; }; + 65B2BB15221F2AC9009A5A7B /* ContactModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactModels.swift; sourceTree = ""; }; + 65B2BB16221F2AC9009A5A7B /* ContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactViewController.swift; sourceTree = ""; }; + 65B2BB17221F2AC9009A5A7B /* ContactInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactInteractor.swift; sourceTree = ""; }; + 65B2BB1E221F2ADD009A5A7B /* FundsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsPresenter.swift; sourceTree = ""; }; + 65B2BB1F221F2ADD009A5A7B /* FundsWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsWorker.swift; sourceTree = ""; }; + 65B2BB20221F2ADD009A5A7B /* FundsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsRouter.swift; sourceTree = ""; }; + 65B2BB21221F2ADD009A5A7B /* FundsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsModels.swift; sourceTree = ""; }; + 65B2BB22221F2ADD009A5A7B /* FundsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsViewController.swift; sourceTree = ""; }; + 65B2BB23221F2ADD009A5A7B /* FundsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsInteractor.swift; sourceTree = ""; }; + 65B2BB2B221F31B4009A5A7B /* AppearanceProxyHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearanceProxyHelper.swift; sourceTree = ""; }; + 65B2BB2D221F3342009A5A7B /* ColorPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = ""; }; + 65B2BB30221F33FC009A5A7B /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; + 65B2BB32221F4326009A5A7B /* ContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactView.swift; sourceTree = ""; }; + 65B2BB34221F4AAA009A5A7B /* ContactTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactTableView.swift; sourceTree = ""; }; + 65B2BB36221F9BC5009A5A7B /* ContactDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDataSource.swift; sourceTree = ""; }; + 65B2BB38221F9BFE009A5A7B /* ContactDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDelegate.swift; sourceTree = ""; }; + 65B2BB3A221F9DDB009A5A7B /* ItemsTableViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemsTableViewDataSource.swift; sourceTree = ""; }; + 65B2BB3E221F9E45009A5A7B /* BankAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankAPI.swift; sourceTree = ""; }; + 65B2BB40221F9F8E009A5A7B /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; + 65B2BB42221FA075009A5A7B /* BankAPI+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BankAPI+Testing.swift"; sourceTree = ""; }; + 65B2BB44221FA2E7009A5A7B /* DefaultAlamofireManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultAlamofireManager.swift; sourceTree = ""; }; + 65B2BB46221FA376009A5A7B /* FormData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormData.swift; sourceTree = ""; }; + 65B2BB48221FA385009A5A7B /* FundsData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsData.swift; sourceTree = ""; }; + 65B2BB4A221FA481009A5A7B /* Cell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = ""; }; + 65B2BB4C221FAFD8009A5A7B /* FundHeaderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FundHeaderTableViewCell.swift; sourceTree = ""; }; + 65B2BB4D221FAFD9009A5A7B /* InfoTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = InfoTableViewCell.xib; sourceTree = ""; }; + 65B2BB4E221FAFD9009A5A7B /* DownInfoTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownInfoTableViewCell.swift; sourceTree = ""; }; + 65B2BB4F221FAFD9009A5A7B /* InfoTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfoTableViewCell.swift; sourceTree = ""; }; + 65B2BB50221FAFDA009A5A7B /* DownInfoTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DownInfoTableViewCell.xib; sourceTree = ""; }; + 65B2BB51221FAFDA009A5A7B /* FundHeaderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FundHeaderTableViewCell.xib; sourceTree = ""; }; + 65B2BB53221FAFDB009A5A7B /* CheckboxTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CheckboxTableViewCell.xib; sourceTree = ""; }; + 65B2BB54221FAFDC009A5A7B /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = ""; }; + 65B2BB55221FAFDC009A5A7B /* SendTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SendTableViewCell.xib; sourceTree = ""; }; + 65B2BB56221FAFDC009A5A7B /* SendTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendTableViewCell.swift; sourceTree = ""; }; + 65B2BB57221FAFDC009A5A7B /* TextFieldTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextFieldTableViewCell.xib; sourceTree = ""; }; + 65B2BB59221FAFDC009A5A7B /* CheckboxTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxTableViewCell.swift; sourceTree = ""; }; + 65B2BB68221FB486009A5A7B /* TextTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextTableViewCell.swift; sourceTree = ""; }; + 65B2BB6A221FB4AD009A5A7B /* TextTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextTableViewCell.xib; sourceTree = ""; }; + 65B2BB6C221FC02B009A5A7B /* ContactBaseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactBaseTableViewCell.swift; sourceTree = ""; }; + 65B2BB6E221FEF53009A5A7B /* DINEngschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINEngschriftStd.otf; sourceTree = ""; }; + 65B2BB6F221FEF53009A5A7B /* DINPro-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Light.otf"; sourceTree = ""; }; + 65B2BB70221FEF53009A5A7B /* DINPro-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Medium.otf"; sourceTree = ""; }; + 65B2BB71221FEF54009A5A7B /* DINPro-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Black.otf"; sourceTree = ""; }; + 65B2BB72221FEF54009A5A7B /* DINNeuzeitGroteskStd-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-Light.otf"; sourceTree = ""; }; + 65B2BB73221FEF54009A5A7B /* DINNeuzeitGroteskStd-BdCond.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-BdCond.otf"; sourceTree = ""; }; + 65B2BB74221FEF54009A5A7B /* DINPro-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Bold.otf"; sourceTree = ""; }; + 65B2BB75221FEF54009A5A7B /* DINPro-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Regular.otf"; sourceTree = ""; }; + 65B2BB76221FEF54009A5A7B /* DINMittelschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINMittelschriftStd.otf; sourceTree = ""; }; + 65B2BB862221D411009A5A7B /* FeedbackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackView.swift; sourceTree = ""; }; + 65B2BB882221D42A009A5A7B /* FeedbackView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeedbackView.xib; sourceTree = ""; }; + 65B2BB8F222210BD009A5A7B /* Fund.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fund.swift; sourceTree = ""; }; + 65B2BB91222213E6009A5A7B /* MoreInfoData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreInfoData.swift; sourceTree = ""; }; + 65B2BB9322221568009A5A7B /* Info.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Info.swift; sourceTree = ""; }; + 65B2BB95222216CF009A5A7B /* MoreInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreInfo.swift; sourceTree = ""; }; + 65B2BB98222228F7009A5A7B /* FundsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsView.swift; sourceTree = ""; }; + 65B2BB9A22222A98009A5A7B /* FundsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsDataSource.swift; sourceTree = ""; }; + 65B2BB9C22222AB3009A5A7B /* FundsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsDelegate.swift; sourceTree = ""; }; + 65B2BBA022224B6A009A5A7B /* FundBaseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundBaseTableViewCell.swift; sourceTree = ""; }; + 65B2BBA222224F00009A5A7B /* FundsTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsTableView.swift; sourceTree = ""; }; + 65B2BBA622225520009A5A7B /* MoreInfoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreInfoTableViewCell.swift; sourceTree = ""; }; + 65B2BBA722225520009A5A7B /* MoreInfoTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MoreInfoTableViewCell.xib; sourceTree = ""; }; + 65B2BBAA22226BAE009A5A7B /* RiskView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiskView.swift; sourceTree = ""; }; + 65B2BBB12222A933009A5A7B /* InvestTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvestTableViewCell.swift; sourceTree = ""; }; + 65B2BBB22222A933009A5A7B /* InvestTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InvestTableViewCell.xib; sourceTree = ""; }; + 65B2BBB82223896C009A5A7B /* Fund.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Fund.json; sourceTree = ""; }; + 65B2BBBA22238980009A5A7B /* Form.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Form.json; sourceTree = ""; }; + 65B2BBBE22238E5A009A5A7B /* FormDataSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormDataSpec.swift; sourceTree = ""; }; + 65B2BBC1222390F6009A5A7B /* ContactDataSourceSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDataSourceSpec.swift; sourceTree = ""; }; + 65B2BBC522239D1C009A5A7B /* StringValidatorSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringValidatorSpec.swift; sourceTree = ""; }; + 65B2BBC92223A168009A5A7B /* ContactInteractSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactInteractSpec.swift; sourceTree = ""; }; + 65EF2622221CC3E500014212 /* TesteiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TesteiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 65EF2625221CC3E500014212 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 65EF262C221CC3E700014212 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 65EF262F221CC3E700014212 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 65EF2631221CC3E700014212 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 65EF2636221CC3E700014212 /* TesteiOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TesteiOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 65EF263C221CC3E700014212 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 65EF2641221CC3E700014212 /* TesteiOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TesteiOSUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 65EF2645221CC3E700014212 /* TesteiOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TesteiOSUITests.swift; sourceTree = ""; }; + 65EF2647221CC3E700014212 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 65F791632223C5E400F1058A /* ContactWorkerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactWorkerSpec.swift; sourceTree = ""; }; + 65F791652223D01600F1058A /* FundsInteractorSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundsInteractorSpec.swift; sourceTree = ""; }; + 90D2E8A002C9BD53CCDBA5FB /* Pods-TesteiOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOS.release.xcconfig"; path = "Target Support Files/Pods-TesteiOS/Pods-TesteiOS.release.xcconfig"; sourceTree = ""; }; + A56D8253223AA8B100A33990 /* String+Validator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Validator.swift"; sourceTree = ""; }; + AC1FED7AFFCC9F0BB4F951CF /* Pods-TesteiOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOS.debug.xcconfig"; path = "Target Support Files/Pods-TesteiOS/Pods-TesteiOS.debug.xcconfig"; sourceTree = ""; }; + C2C7FB9A50E98EBED4E7C177 /* Pods_TesteiOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TesteiOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D778FDDB6EFFC6823D4DE1D7 /* Pods-TesteiOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOSTests.debug.xcconfig"; path = "Target Support Files/Pods-TesteiOSTests/Pods-TesteiOSTests.debug.xcconfig"; sourceTree = ""; }; + E53AA491062BDD9DF858AB8E /* Pods_TesteiOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TesteiOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 65EF261F221CC3E500014212 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DAC11BD224CBF944124D26B8 /* Pods_TesteiOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF2633221CC3E700014212 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BF30F532668E8706D861BA2D /* Pods_TesteiOSTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF263E221CC3E700014212 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1927B86FEC455B2EA23B93B9 /* Pods */ = { + isa = PBXGroup; + children = ( + AC1FED7AFFCC9F0BB4F951CF /* Pods-TesteiOS.debug.xcconfig */, + 90D2E8A002C9BD53CCDBA5FB /* Pods-TesteiOS.release.xcconfig */, + D778FDDB6EFFC6823D4DE1D7 /* Pods-TesteiOSTests.debug.xcconfig */, + 1C51913E040327570673FCE3 /* Pods-TesteiOSTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 65B2BAEA221F0890009A5A7B /* Scenes */ = { + isa = PBXGroup; + children = ( + 65B2BB11221F2A1A009A5A7B /* Funds */, + 65B2BB10221F2937009A5A7B /* Contact */, + ); + path = Scenes; + sourceTree = ""; + }; + 65B2BAEB221F0896009A5A7B /* Commons */ = { + isa = PBXGroup; + children = ( + 65B2BB3A221F9DDB009A5A7B /* ItemsTableViewDataSource.swift */, + 65B2BB03221F121C009A5A7B /* TabBarViewController.swift */, + ); + path = Commons; + sourceTree = ""; + }; + 65B2BAEC221F08A0009A5A7B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 65B2BB2F221F33DE009A5A7B /* Extensions */, + 65EF2625221CC3E500014212 /* AppDelegate.swift */, + 65EF2631221CC3E700014212 /* Info.plist */, + 65EF262E221CC3E700014212 /* LaunchScreen.storyboard */, + ); + path = "Supporting Files"; + sourceTree = ""; + }; + 65B2BAED221F08A9009A5A7B /* Resources */ = { + isa = PBXGroup; + children = ( + 65B2BAEE221F08C8009A5A7B /* Fonts */, + 65EF262C221CC3E700014212 /* Assets.xcassets */, + 65B2BB0E221F2750009A5A7B /* FontNames.swift */, + 65B2BB2D221F3342009A5A7B /* ColorPalette.swift */, + ); + path = Resources; + sourceTree = ""; + }; + 65B2BAEE221F08C8009A5A7B /* Fonts */ = { + isa = PBXGroup; + children = ( + 65B2BB6E221FEF53009A5A7B /* DINEngschriftStd.otf */, + 65B2BB76221FEF54009A5A7B /* DINMittelschriftStd.otf */, + 65B2BB73221FEF54009A5A7B /* DINNeuzeitGroteskStd-BdCond.otf */, + 65B2BB72221FEF54009A5A7B /* DINNeuzeitGroteskStd-Light.otf */, + 65B2BB71221FEF54009A5A7B /* DINPro-Black.otf */, + 65B2BB74221FEF54009A5A7B /* DINPro-Bold.otf */, + 65B2BB6F221FEF53009A5A7B /* DINPro-Light.otf */, + 65B2BB70221FEF53009A5A7B /* DINPro-Medium.otf */, + 65B2BB75221FEF54009A5A7B /* DINPro-Regular.otf */, + ); + path = Fonts; + sourceTree = ""; + }; + 65B2BB05221F1CE0009A5A7B /* UI */ = { + isa = PBXGroup; + children = ( + 65B2BB2A221F31A6009A5A7B /* Appearance */, + 65B2BB07221F1CF2009A5A7B /* Cells */, + 65B2BB06221F1CE9009A5A7B /* Views */, + ); + path = UI; + sourceTree = ""; + }; + 65B2BB06221F1CE9009A5A7B /* Views */ = { + isa = PBXGroup; + children = ( + 65B2BBBD22238BF7009A5A7B /* Funds */, + 65B2BBBC22238BE3009A5A7B /* Contact */, + 65B2BB0C221F252A009A5A7B /* TabBarButton.swift */, + 65B2BB08221F1D1C009A5A7B /* TabBarView.swift */, + 65B2BB0A221F1D44009A5A7B /* ViewCode.swift */, + ); + path = Views; + sourceTree = ""; + }; + 65B2BB07221F1CF2009A5A7B /* Cells */ = { + isa = PBXGroup; + children = ( + 65B2BB852221A0E5009A5A7B /* Fund */, + 65B2BB842221A0D3009A5A7B /* Contact */, + ); + path = Cells; + sourceTree = ""; + }; + 65B2BB10221F2937009A5A7B /* Contact */ = { + isa = PBXGroup; + children = ( + 65B2BB12221F2AC9009A5A7B /* ContactPresenter.swift */, + 65B2BB13221F2AC9009A5A7B /* ContactWorker.swift */, + 65B2BB14221F2AC9009A5A7B /* ContactRouter.swift */, + 65B2BB15221F2AC9009A5A7B /* ContactModels.swift */, + 65B2BB16221F2AC9009A5A7B /* ContactViewController.swift */, + 65B2BB17221F2AC9009A5A7B /* ContactInteractor.swift */, + 65B2BB36221F9BC5009A5A7B /* ContactDataSource.swift */, + 65B2BB38221F9BFE009A5A7B /* ContactDelegate.swift */, + ); + path = Contact; + sourceTree = ""; + }; + 65B2BB11221F2A1A009A5A7B /* Funds */ = { + isa = PBXGroup; + children = ( + 65B2BB1E221F2ADD009A5A7B /* FundsPresenter.swift */, + 65B2BB1F221F2ADD009A5A7B /* FundsWorker.swift */, + 65B2BB20221F2ADD009A5A7B /* FundsRouter.swift */, + 65B2BB21221F2ADD009A5A7B /* FundsModels.swift */, + 65B2BB22221F2ADD009A5A7B /* FundsViewController.swift */, + 65B2BB23221F2ADD009A5A7B /* FundsInteractor.swift */, + 65B2BB9A22222A98009A5A7B /* FundsDataSource.swift */, + 65B2BB9C22222AB3009A5A7B /* FundsDelegate.swift */, + ); + path = Funds; + sourceTree = ""; + }; + 65B2BB2A221F31A6009A5A7B /* Appearance */ = { + isa = PBXGroup; + children = ( + 65B2BB2B221F31B4009A5A7B /* AppearanceProxyHelper.swift */, + ); + path = Appearance; + sourceTree = ""; + }; + 65B2BB2F221F33DE009A5A7B /* Extensions */ = { + isa = PBXGroup; + children = ( + A56D8253223AA8B100A33990 /* String+Validator.swift */, + 65B2BB30221F33FC009A5A7B /* UIColor+Hex.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 65B2BB3C221F9E03009A5A7B /* Services */ = { + isa = PBXGroup; + children = ( + 65B2BB3E221F9E45009A5A7B /* BankAPI.swift */, + 65B2BB42221FA075009A5A7B /* BankAPI+Testing.swift */, + 65B2BBB5222388FA009A5A7B /* StubbedResponses */, + 65B2BB40221F9F8E009A5A7B /* NetworkManager.swift */, + 65B2BB44221FA2E7009A5A7B /* DefaultAlamofireManager.swift */, + ); + path = Services; + sourceTree = ""; + }; + 65B2BB3D221F9E1D009A5A7B /* Models */ = { + isa = PBXGroup; + children = ( + 65B2BB46221FA376009A5A7B /* FormData.swift */, + 65B2BB48221FA385009A5A7B /* FundsData.swift */, + 65B2BB4A221FA481009A5A7B /* Cell.swift */, + 65B2BB8F222210BD009A5A7B /* Fund.swift */, + 65B2BB91222213E6009A5A7B /* MoreInfoData.swift */, + 65B2BB95222216CF009A5A7B /* MoreInfo.swift */, + 65B2BB9322221568009A5A7B /* Info.swift */, + ); + path = Models; + sourceTree = ""; + }; + 65B2BB842221A0D3009A5A7B /* Contact */ = { + isa = PBXGroup; + children = ( + 65B2BB8D2221F04D009A5A7B /* TextFieldTableViewCell */, + 65B2BB8C2221F035009A5A7B /* SendTableViewCell */, + 65B2BB8B2221F01C009A5A7B /* CheckboxTableViewCell */, + 65B2BB8A2221F005009A5A7B /* TextTableViewCell */, + 65B2BB6C221FC02B009A5A7B /* ContactBaseTableViewCell.swift */, + ); + path = Contact; + sourceTree = ""; + }; + 65B2BB852221A0E5009A5A7B /* Fund */ = { + isa = PBXGroup; + children = ( + 65B2BBB02222A90A009A5A7B /* InvestTableViewCell */, + 65B2BBAF22229132009A5A7B /* InfoTableViewCell */, + 65B2BBAE22229019009A5A7B /* DownInfoTableViewCell */, + 65B2BBAD22227E24009A5A7B /* MoreInfoTableViewCell */, + 65B2BBAC22227E07009A5A7B /* FundHeaderTableViewCell */, + 65B2BBA022224B6A009A5A7B /* FundBaseTableViewCell.swift */, + ); + path = Fund; + sourceTree = ""; + }; + 65B2BB8A2221F005009A5A7B /* TextTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB68221FB486009A5A7B /* TextTableViewCell.swift */, + 65B2BB6A221FB4AD009A5A7B /* TextTableViewCell.xib */, + ); + path = TextTableViewCell; + sourceTree = ""; + }; + 65B2BB8B2221F01C009A5A7B /* CheckboxTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB59221FAFDC009A5A7B /* CheckboxTableViewCell.swift */, + 65B2BB53221FAFDB009A5A7B /* CheckboxTableViewCell.xib */, + ); + path = CheckboxTableViewCell; + sourceTree = ""; + }; + 65B2BB8C2221F035009A5A7B /* SendTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB56221FAFDC009A5A7B /* SendTableViewCell.swift */, + 65B2BB55221FAFDC009A5A7B /* SendTableViewCell.xib */, + ); + path = SendTableViewCell; + sourceTree = ""; + }; + 65B2BB8D2221F04D009A5A7B /* TextFieldTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB54221FAFDC009A5A7B /* TextFieldTableViewCell.swift */, + 65B2BB57221FAFDC009A5A7B /* TextFieldTableViewCell.xib */, + ); + path = TextFieldTableViewCell; + sourceTree = ""; + }; + 65B2BB8E2221FA13009A5A7B /* FeedbackView */ = { + isa = PBXGroup; + children = ( + 65B2BB862221D411009A5A7B /* FeedbackView.swift */, + 65B2BB882221D42A009A5A7B /* FeedbackView.xib */, + ); + path = FeedbackView; + sourceTree = ""; + }; + 65B2BBAC22227E07009A5A7B /* FundHeaderTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB4C221FAFD8009A5A7B /* FundHeaderTableViewCell.swift */, + 65B2BB51221FAFDA009A5A7B /* FundHeaderTableViewCell.xib */, + ); + path = FundHeaderTableViewCell; + sourceTree = ""; + }; + 65B2BBAD22227E24009A5A7B /* MoreInfoTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BBA622225520009A5A7B /* MoreInfoTableViewCell.swift */, + 65B2BBA722225520009A5A7B /* MoreInfoTableViewCell.xib */, + ); + path = MoreInfoTableViewCell; + sourceTree = ""; + }; + 65B2BBAE22229019009A5A7B /* DownInfoTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB4E221FAFD9009A5A7B /* DownInfoTableViewCell.swift */, + 65B2BB50221FAFDA009A5A7B /* DownInfoTableViewCell.xib */, + ); + path = DownInfoTableViewCell; + sourceTree = ""; + }; + 65B2BBAF22229132009A5A7B /* InfoTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BB4F221FAFD9009A5A7B /* InfoTableViewCell.swift */, + 65B2BB4D221FAFD9009A5A7B /* InfoTableViewCell.xib */, + ); + path = InfoTableViewCell; + sourceTree = ""; + }; + 65B2BBB02222A90A009A5A7B /* InvestTableViewCell */ = { + isa = PBXGroup; + children = ( + 65B2BBB12222A933009A5A7B /* InvestTableViewCell.swift */, + 65B2BBB22222A933009A5A7B /* InvestTableViewCell.xib */, + ); + path = InvestTableViewCell; + sourceTree = ""; + }; + 65B2BBB5222388FA009A5A7B /* StubbedResponses */ = { + isa = PBXGroup; + children = ( + 65B2BBB82223896C009A5A7B /* Fund.json */, + 65B2BBBA22238980009A5A7B /* Form.json */, + ); + path = StubbedResponses; + sourceTree = ""; + }; + 65B2BBBC22238BE3009A5A7B /* Contact */ = { + isa = PBXGroup; + children = ( + 65B2BB8E2221FA13009A5A7B /* FeedbackView */, + 65B2BB32221F4326009A5A7B /* ContactView.swift */, + 65B2BB34221F4AAA009A5A7B /* ContactTableView.swift */, + ); + path = Contact; + sourceTree = ""; + }; + 65B2BBBD22238BF7009A5A7B /* Funds */ = { + isa = PBXGroup; + children = ( + 65B2BB98222228F7009A5A7B /* FundsView.swift */, + 65B2BBA222224F00009A5A7B /* FundsTableView.swift */, + 65B2BBAA22226BAE009A5A7B /* RiskView.swift */, + ); + path = Funds; + sourceTree = ""; + }; + 65B2BBC02223901B009A5A7B /* Models */ = { + isa = PBXGroup; + children = ( + 65B2BBBE22238E5A009A5A7B /* FormDataSpec.swift */, + ); + path = Models; + sourceTree = ""; + }; + 65B2BBC3222392E0009A5A7B /* DataSources */ = { + isa = PBXGroup; + children = ( + 65B2BBC1222390F6009A5A7B /* ContactDataSourceSpec.swift */, + ); + path = DataSources; + sourceTree = ""; + }; + 65B2BBC422239CF6009A5A7B /* Extensions */ = { + isa = PBXGroup; + children = ( + 65B2BBC522239D1C009A5A7B /* StringValidatorSpec.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 65B2BBC72223A14B009A5A7B /* Scenes */ = { + isa = PBXGroup; + children = ( + 65F791672223D01C00F1058A /* Funds */, + 65B2BBC82223A152009A5A7B /* Contact */, + ); + path = Scenes; + sourceTree = ""; + }; + 65B2BBC82223A152009A5A7B /* Contact */ = { + isa = PBXGroup; + children = ( + 65B2BBC92223A168009A5A7B /* ContactInteractSpec.swift */, + 65F791632223C5E400F1058A /* ContactWorkerSpec.swift */, + ); + path = Contact; + sourceTree = ""; + }; + 65EF2619221CC3E500014212 = { + isa = PBXGroup; + children = ( + 65EF2624221CC3E500014212 /* TesteiOS */, + 65EF2639221CC3E700014212 /* TesteiOSTests */, + 65EF2644221CC3E700014212 /* TesteiOSUITests */, + 65EF2623221CC3E500014212 /* Products */, + 1927B86FEC455B2EA23B93B9 /* Pods */, + F27A8A997A75DFBE5CC78888 /* Frameworks */, + ); + sourceTree = ""; + }; + 65EF2623221CC3E500014212 /* Products */ = { + isa = PBXGroup; + children = ( + 65EF2622221CC3E500014212 /* TesteiOS.app */, + 65EF2636221CC3E700014212 /* TesteiOSTests.xctest */, + 65EF2641221CC3E700014212 /* TesteiOSUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 65EF2624221CC3E500014212 /* TesteiOS */ = { + isa = PBXGroup; + children = ( + 65B2BB3C221F9E03009A5A7B /* Services */, + 65B2BB3D221F9E1D009A5A7B /* Models */, + 65B2BB05221F1CE0009A5A7B /* UI */, + 65B2BAEB221F0896009A5A7B /* Commons */, + 65B2BAEA221F0890009A5A7B /* Scenes */, + 65B2BAED221F08A9009A5A7B /* Resources */, + 65B2BAEC221F08A0009A5A7B /* Supporting Files */, + ); + path = TesteiOS; + sourceTree = ""; + }; + 65EF2639221CC3E700014212 /* TesteiOSTests */ = { + isa = PBXGroup; + children = ( + 65B2BBC72223A14B009A5A7B /* Scenes */, + 65B2BBC422239CF6009A5A7B /* Extensions */, + 65B2BBC3222392E0009A5A7B /* DataSources */, + 65B2BBC02223901B009A5A7B /* Models */, + 65EF263C221CC3E700014212 /* Info.plist */, + ); + path = TesteiOSTests; + sourceTree = ""; + }; + 65EF2644221CC3E700014212 /* TesteiOSUITests */ = { + isa = PBXGroup; + children = ( + 65EF2645221CC3E700014212 /* TesteiOSUITests.swift */, + 65EF2647221CC3E700014212 /* Info.plist */, + ); + path = TesteiOSUITests; + sourceTree = ""; + }; + 65F791672223D01C00F1058A /* Funds */ = { + isa = PBXGroup; + children = ( + 65F791652223D01600F1058A /* FundsInteractorSpec.swift */, + ); + path = Funds; + sourceTree = ""; + }; + F27A8A997A75DFBE5CC78888 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C2C7FB9A50E98EBED4E7C177 /* Pods_TesteiOS.framework */, + E53AA491062BDD9DF858AB8E /* Pods_TesteiOSTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 65EF2621221CC3E500014212 /* TesteiOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 65EF264A221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOS" */; + buildPhases = ( + 22B64DAD4B136BFBEC1AC845 /* [CP] Check Pods Manifest.lock */, + 65EF261E221CC3E500014212 /* Sources */, + 65EF261F221CC3E500014212 /* Frameworks */, + 65EF2620221CC3E500014212 /* Resources */, + 4D1F9A8A5F24DCE3A5EFA0D1 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TesteiOS; + productName = TesteiOS; + productReference = 65EF2622221CC3E500014212 /* TesteiOS.app */; + productType = "com.apple.product-type.application"; + }; + 65EF2635221CC3E700014212 /* TesteiOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 65EF264D221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOSTests" */; + buildPhases = ( + 0A7BF9C629D3FA0B1F2200C6 /* [CP] Check Pods Manifest.lock */, + 65EF2632221CC3E700014212 /* Sources */, + 65EF2633221CC3E700014212 /* Frameworks */, + 65EF2634221CC3E700014212 /* Resources */, + 75D4754FCB19361CD2BA3DE7 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 65EF2638221CC3E700014212 /* PBXTargetDependency */, + ); + name = TesteiOSTests; + productName = TesteiOSTests; + productReference = 65EF2636221CC3E700014212 /* TesteiOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 65EF2640221CC3E700014212 /* TesteiOSUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 65EF2650221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOSUITests" */; + buildPhases = ( + 65EF263D221CC3E700014212 /* Sources */, + 65EF263E221CC3E700014212 /* Frameworks */, + 65EF263F221CC3E700014212 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 65EF2643221CC3E700014212 /* PBXTargetDependency */, + ); + name = TesteiOSUITests; + productName = TesteiOSUITests; + productReference = 65EF2641221CC3E700014212 /* TesteiOSUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 65EF261A221CC3E500014212 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Brendoon Ryos"; + TargetAttributes = { + 65EF2621221CC3E500014212 = { + CreatedOnToolsVersion = 10.1; + }; + 65EF2635221CC3E700014212 = { + CreatedOnToolsVersion = 10.1; + TestTargetID = 65EF2621221CC3E500014212; + }; + 65EF2640221CC3E700014212 = { + CreatedOnToolsVersion = 10.1; + TestTargetID = 65EF2621221CC3E500014212; + }; + }; + }; + buildConfigurationList = 65EF261D221CC3E500014212 /* Build configuration list for PBXProject "TesteiOS" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 65EF2619221CC3E500014212; + productRefGroup = 65EF2623221CC3E500014212 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 65EF2621221CC3E500014212 /* TesteiOS */, + 65EF2635221CC3E700014212 /* TesteiOSTests */, + 65EF2640221CC3E700014212 /* TesteiOSUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 65EF2620221CC3E500014212 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 65B2BB7E221FEF54009A5A7B /* DINPro-Regular.otf in Resources */, + 65B2BB5B221FAFDC009A5A7B /* InfoTableViewCell.xib in Resources */, + 65B2BB7B221FEF54009A5A7B /* DINNeuzeitGroteskStd-Light.otf in Resources */, + 65EF2630221CC3E700014212 /* LaunchScreen.storyboard in Resources */, + 65B2BB61221FAFDC009A5A7B /* CheckboxTableViewCell.xib in Resources */, + 65EF262D221CC3E700014212 /* Assets.xcassets in Resources */, + 65B2BBB92223896C009A5A7B /* Fund.json in Resources */, + 65B2BB7C221FEF54009A5A7B /* DINNeuzeitGroteskStd-BdCond.otf in Resources */, + 65B2BB5F221FAFDC009A5A7B /* FundHeaderTableViewCell.xib in Resources */, + 65B2BBB42222A933009A5A7B /* InvestTableViewCell.xib in Resources */, + 65B2BBA922225520009A5A7B /* MoreInfoTableViewCell.xib in Resources */, + 65B2BB7D221FEF54009A5A7B /* DINPro-Bold.otf in Resources */, + 65B2BB63221FAFDC009A5A7B /* SendTableViewCell.xib in Resources */, + 65B2BB892221D42A009A5A7B /* FeedbackView.xib in Resources */, + 65B2BB65221FAFDC009A5A7B /* TextFieldTableViewCell.xib in Resources */, + 65B2BBBB22238980009A5A7B /* Form.json in Resources */, + 65B2BB7F221FEF54009A5A7B /* DINMittelschriftStd.otf in Resources */, + 65B2BB6B221FB4AD009A5A7B /* TextTableViewCell.xib in Resources */, + 65B2BB78221FEF54009A5A7B /* DINPro-Light.otf in Resources */, + 65B2BB79221FEF54009A5A7B /* DINPro-Medium.otf in Resources */, + 65B2BB77221FEF54009A5A7B /* DINEngschriftStd.otf in Resources */, + 65B2BB7A221FEF54009A5A7B /* DINPro-Black.otf in Resources */, + 65B2BB5E221FAFDC009A5A7B /* DownInfoTableViewCell.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF2634221CC3E700014212 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF263F221CC3E700014212 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0A7BF9C629D3FA0B1F2200C6 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TesteiOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 22B64DAD4B136BFBEC1AC845 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TesteiOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 4D1F9A8A5F24DCE3A5EFA0D1 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TesteiOS/Pods-TesteiOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", + "${BUILT_PRODUCTS_DIR}/JMMaskTextField-Swift/JMMaskTextField_Swift.framework", + "${BUILT_PRODUCTS_DIR}/Moya/Moya.framework", + "${BUILT_PRODUCTS_DIR}/Result/Result.framework", + "${BUILT_PRODUCTS_DIR}/Reusable/Reusable.framework", + "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JMMaskTextField_Swift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Moya.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Result.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reusable.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TesteiOS/Pods-TesteiOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 75D4754FCB19361CD2BA3DE7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TesteiOSTests/Pods-TesteiOSTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TesteiOSTests/Pods-TesteiOSTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 65EF261E221CC3E500014212 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 65B2BB31221F33FC009A5A7B /* UIColor+Hex.swift in Sources */, + 65B2BB9422221568009A5A7B /* Info.swift in Sources */, + 65B2BBB32222A933009A5A7B /* InvestTableViewCell.swift in Sources */, + 65B2BB33221F4326009A5A7B /* ContactView.swift in Sources */, + 65B2BBA122224B6A009A5A7B /* FundBaseTableViewCell.swift in Sources */, + 65B2BB27221F2ADD009A5A7B /* FundsModels.swift in Sources */, + 65B2BB3B221F9DDB009A5A7B /* ItemsTableViewDataSource.swift in Sources */, + 65B2BBA322224F00009A5A7B /* FundsTableView.swift in Sources */, + 65B2BB39221F9BFE009A5A7B /* ContactDelegate.swift in Sources */, + 65B2BB3F221F9E45009A5A7B /* BankAPI.swift in Sources */, + 65B2BB25221F2ADD009A5A7B /* FundsWorker.swift in Sources */, + 65B2BB04221F121C009A5A7B /* TabBarViewController.swift in Sources */, + 65B2BBAB22226BAE009A5A7B /* RiskView.swift in Sources */, + 65B2BB9D22222AB3009A5A7B /* FundsDelegate.swift in Sources */, + 65B2BB69221FB486009A5A7B /* TextTableViewCell.swift in Sources */, + 65B2BB4B221FA481009A5A7B /* Cell.swift in Sources */, + 65B2BB64221FAFDC009A5A7B /* SendTableViewCell.swift in Sources */, + 65B2BB09221F1D1C009A5A7B /* TabBarView.swift in Sources */, + 65B2BB2C221F31B4009A5A7B /* AppearanceProxyHelper.swift in Sources */, + 65B2BB26221F2ADD009A5A7B /* FundsRouter.swift in Sources */, + 65B2BB28221F2ADD009A5A7B /* FundsViewController.swift in Sources */, + 65EF2626221CC3E500014212 /* AppDelegate.swift in Sources */, + 65B2BB1A221F2AC9009A5A7B /* ContactRouter.swift in Sources */, + 65B2BB18221F2AC9009A5A7B /* ContactPresenter.swift in Sources */, + 65B2BB43221FA075009A5A7B /* BankAPI+Testing.swift in Sources */, + 65B2BB49221FA385009A5A7B /* FundsData.swift in Sources */, + 65B2BB67221FAFDC009A5A7B /* CheckboxTableViewCell.swift in Sources */, + 65B2BB1D221F2AC9009A5A7B /* ContactInteractor.swift in Sources */, + 65B2BB19221F2AC9009A5A7B /* ContactWorker.swift in Sources */, + 65B2BB24221F2ADD009A5A7B /* FundsPresenter.swift in Sources */, + 65B2BB5D221FAFDC009A5A7B /* InfoTableViewCell.swift in Sources */, + 65B2BB92222213E6009A5A7B /* MoreInfoData.swift in Sources */, + 65B2BB62221FAFDC009A5A7B /* TextFieldTableViewCell.swift in Sources */, + 65B2BB96222216CF009A5A7B /* MoreInfo.swift in Sources */, + 65B2BB1C221F2AC9009A5A7B /* ContactViewController.swift in Sources */, + 65B2BB872221D411009A5A7B /* FeedbackView.swift in Sources */, + 65B2BB0D221F252A009A5A7B /* TabBarButton.swift in Sources */, + 65B2BB99222228F7009A5A7B /* FundsView.swift in Sources */, + 65B2BB37221F9BC5009A5A7B /* ContactDataSource.swift in Sources */, + 65B2BB2E221F3342009A5A7B /* ColorPalette.swift in Sources */, + 65B2BB0B221F1D44009A5A7B /* ViewCode.swift in Sources */, + 65B2BB35221F4AAA009A5A7B /* ContactTableView.swift in Sources */, + 65B2BB5A221FAFDC009A5A7B /* FundHeaderTableViewCell.swift in Sources */, + 65B2BB6D221FC02B009A5A7B /* ContactBaseTableViewCell.swift in Sources */, + 65B2BB5C221FAFDC009A5A7B /* DownInfoTableViewCell.swift in Sources */, + 65B2BB41221F9F8E009A5A7B /* NetworkManager.swift in Sources */, + 65B2BB1B221F2AC9009A5A7B /* ContactModels.swift in Sources */, + 65B2BB47221FA376009A5A7B /* FormData.swift in Sources */, + A56D8254223AA8B100A33990 /* String+Validator.swift in Sources */, + 65B2BB0F221F2750009A5A7B /* FontNames.swift in Sources */, + 65B2BBA822225520009A5A7B /* MoreInfoTableViewCell.swift in Sources */, + 65B2BB45221FA2E7009A5A7B /* DefaultAlamofireManager.swift in Sources */, + 65B2BB9B22222A98009A5A7B /* FundsDataSource.swift in Sources */, + 65B2BB90222210BD009A5A7B /* Fund.swift in Sources */, + 65B2BB29221F2ADD009A5A7B /* FundsInteractor.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF2632221CC3E700014212 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 65F791662223D01600F1058A /* FundsInteractorSpec.swift in Sources */, + 65B2BBC2222390F6009A5A7B /* ContactDataSourceSpec.swift in Sources */, + 65F791642223C5E400F1058A /* ContactWorkerSpec.swift in Sources */, + 65B2BBCA2223A168009A5A7B /* ContactInteractSpec.swift in Sources */, + 65B2BBC622239D1C009A5A7B /* StringValidatorSpec.swift in Sources */, + 65B2BBBF22238E5A009A5A7B /* FormDataSpec.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65EF263D221CC3E700014212 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 65EF2646221CC3E700014212 /* TesteiOSUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 65EF2638221CC3E700014212 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 65EF2621221CC3E500014212 /* TesteiOS */; + targetProxy = 65EF2637221CC3E700014212 /* PBXContainerItemProxy */; + }; + 65EF2643221CC3E700014212 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 65EF2621221CC3E500014212 /* TesteiOS */; + targetProxy = 65EF2642221CC3E700014212 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 65EF262E221CC3E700014212 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 65EF262F221CC3E700014212 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 65EF2648221CC3E700014212 /* 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.1; + 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; + }; + 65EF2649221CC3E700014212 /* 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.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 65EF264B221CC3E700014212 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AC1FED7AFFCC9F0BB4F951CF /* Pods-TesteiOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = "$(SRCROOT)/TesteiOS/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 65EF264C221CC3E700014212 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 90D2E8A002C9BD53CCDBA5FB /* Pods-TesteiOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = "$(SRCROOT)/TesteiOS/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 65EF264E221CC3E700014212 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D778FDDB6EFFC6823D4DE1D7 /* Pods-TesteiOSTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = TesteiOSTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOSTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TesteiOS.app/TesteiOS"; + }; + name = Debug; + }; + 65EF264F221CC3E700014212 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1C51913E040327570673FCE3 /* Pods-TesteiOSTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = TesteiOSTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOSTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TesteiOS.app/TesteiOS"; + }; + name = Release; + }; + 65EF2651221CC3E700014212 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = TesteiOSUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOSUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TesteiOS; + }; + name = Debug; + }; + 65EF2652221CC3E700014212 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8G633XVRJD; + INFOPLIST_FILE = TesteiOSUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = br.bryos.TesteiOSUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TesteiOS; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 65EF261D221CC3E500014212 /* Build configuration list for PBXProject "TesteiOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65EF2648221CC3E700014212 /* Debug */, + 65EF2649221CC3E700014212 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 65EF264A221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65EF264B221CC3E700014212 /* Debug */, + 65EF264C221CC3E700014212 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 65EF264D221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65EF264E221CC3E700014212 /* Debug */, + 65EF264F221CC3E700014212 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 65EF2650221CC3E700014212 /* Build configuration list for PBXNativeTarget "TesteiOSUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65EF2651221CC3E700014212 /* Debug */, + 65EF2652221CC3E700014212 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 65EF261A221CC3E500014212 /* Project object */; +} diff --git a/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..313ba99d --- /dev/null +++ b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/bryos.xcuserdatad/UserInterfaceState.xcuserstate b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/bryos.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..15a24807 Binary files /dev/null and b/TesteiOS/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/bryos.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TesteiOS/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme b/TesteiOS/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme new file mode 100644 index 00000000..96baf381 --- /dev/null +++ b/TesteiOS/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS.xcodeproj/xcuserdata/bryos.xcuserdatad/xcschemes/xcschememanagement.plist b/TesteiOS/TesteiOS.xcodeproj/xcuserdata/bryos.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..ff25e13e --- /dev/null +++ b/TesteiOS/TesteiOS.xcodeproj/xcuserdata/bryos.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + TesteiOS.xcscheme_^#shared#^_ + + orderHint + 9 + + + SuppressBuildableAutocreation + + 65EF2621221CC3E500014212 + + primary + + + 65EF2635221CC3E700014212 + + primary + + + 65EF2640221CC3E700014212 + + primary + + + + + diff --git a/TesteiOS/TesteiOS/Commons/ItemsTableViewDataSource.swift b/TesteiOS/TesteiOS/Commons/ItemsTableViewDataSource.swift new file mode 100644 index 00000000..cc1f33c7 --- /dev/null +++ b/TesteiOS/TesteiOS/Commons/ItemsTableViewDataSource.swift @@ -0,0 +1,32 @@ +// +// ItemsTableViewDataSource.swift +// TesteiOS +// +// Created by Brendoon Ryos on 04/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +protocol ItemsTableViewDataSource: UITableViewDataSource { + associatedtype T + var items:[T] { get } + var tableView: UITableView? { get } + var delegate: UITableViewDelegate? { get } + + init(tableView: UITableView, delegate: UITableViewDelegate) + + func setupTableView() + func registerTableView() +} + +extension ItemsTableViewDataSource { + func setupTableView() { + registerTableView() + self.tableView?.dataSource = self + self.tableView?.delegate = self.delegate + self.tableView?.reloadData() + } + + func registerTableView() {} +} diff --git a/TesteiOS/TesteiOS/Commons/TabBarViewController.swift b/TesteiOS/TesteiOS/Commons/TabBarViewController.swift new file mode 100644 index 00000000..cac14515 --- /dev/null +++ b/TesteiOS/TesteiOS/Commons/TabBarViewController.swift @@ -0,0 +1,48 @@ +// +// TabBarViewController.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit +import SnapKit + +class TabBarViewController: UITabBarController { + + let tabBarView = TabBarView() + + override func viewDidLoad() { + super.viewDidLoad() + setup() + } + + private func setup() { + self.tabBar.isHidden = true + view.addSubview(tabBarView) + setupConstraints() + selectedIndex = tabBarView.button1.tag + tabBarView.button1.isSelected = true + tabBarView.button1.addTarget(self, action: #selector(tabbarItemPressed(_:)), for: .touchUpInside) + tabBarView.button2.addTarget(self, action: #selector(tabbarItemPressed(_:)), for: .touchUpInside) + } + + func setupConstraints() { + tabBarView.snp.makeConstraints { make in + make.bottom.equalToSuperview() + make.height.equalTo(57) + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + } + } + + @objc func tabbarItemPressed(_ sender: UIButton) { + selectedIndex = sender.tag + tabBarView.button1.isSelected = tabBarView.button1.tag == sender.tag + tabBarView.button2.isSelected = tabBarView.button2.tag == sender.tag + + tabBarView.button1.isUserInteractionEnabled = !tabBarView.button1.isSelected + tabBarView.button2.isUserInteractionEnabled = !tabBarView.button2.isSelected + } +} diff --git a/TesteiOS/TesteiOS/Models/Cell.swift b/TesteiOS/TesteiOS/Models/Cell.swift new file mode 100644 index 00000000..385e20da --- /dev/null +++ b/TesteiOS/TesteiOS/Models/Cell.swift @@ -0,0 +1,170 @@ +// +// Cell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation +import Reusable + +enum CellType: Int { + case field = 1 + case text + case image + case checkbox + case send + case fundHeader + case moreInfo + case info + case downInfo + case invest + + func getNib() -> UINib { + switch self { + case .field: + return TextFieldTableViewCell.nib + case .text: + return TextTableViewCell.nib + case .checkbox: + return CheckboxTableViewCell.nib + case .send: + return SendTableViewCell.nib + case .fundHeader: + return FundHeaderTableViewCell.nib + case .moreInfo: + return MoreInfoTableViewCell.nib + case .info: + return InfoTableViewCell.nib + case .downInfo: + return DownInfoTableViewCell.nib + default: + return InvestTableViewCell.nib + } + } + + func getIdentifier() -> String { + switch self { + case .field: + return TextFieldTableViewCell.reuseIdentifier + case .text: + return TextTableViewCell.reuseIdentifier + case .checkbox: + return CheckboxTableViewCell.reuseIdentifier + case .send: + return SendTableViewCell.reuseIdentifier + case .fundHeader: + return FundHeaderTableViewCell.reuseIdentifier + case .moreInfo: + return MoreInfoTableViewCell.reuseIdentifier + case .info: + return InfoTableViewCell.reuseIdentifier + case .downInfo: + return DownInfoTableViewCell.reuseIdentifier + default: + return InvestTableViewCell.reuseIdentifier + } + } + + func getClass() -> UITableViewCell.Type { + switch self { + case .field: + return TextFieldTableViewCell.self + case .text: + return TextTableViewCell.self + case .checkbox: + return CheckboxTableViewCell.self + case .send: + return SendTableViewCell.self + case .fundHeader: + return FundHeaderTableViewCell.self + case .moreInfo: + return MoreInfoTableViewCell.self + case .info: + return InfoTableViewCell.self + case .downInfo: + return DownInfoTableViewCell.self + default: + return InvestTableViewCell.self + } + } + + func getHeight() -> CGFloat { + switch self { + case .fundHeader: + return 410 + case .moreInfo: + return 200 + case .info, .downInfo: + return 30 + default: + return 80 + } + } +} + +enum TypeField: Int { + case text = 1 + case telNumber + case email + + var contentType: UITextContentType { + switch self { + case .telNumber: + return .telephoneNumber + case .email: + return .emailAddress + default: + return .name + } + } + + var keyboardType: UIKeyboardType { + switch self { + case .telNumber: + return .phonePad + case .email: + return .emailAddress + default: + return .default + } + } +} + +struct Cell { + let id: Int + let type: Int + let message: String + let typefield: Int? + let hidden: Bool + let topSpacing: Int + let show: Int? + let required: Bool +} + +extension Cell: Decodable { + private enum CodingKeys: String, CodingKey { + case id + case type + case message + case typefield + case hidden + case topSpacing + case show + case required + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + id = try container.decode(Int.self, forKey: .id) + type = try container.decode(Int.self, forKey: .type) + message = try container.decode(String.self, forKey: .message) + typefield = try? container.decode(Int.self, forKey: .typefield) + hidden = try container.decode(Bool.self, forKey: .hidden) + topSpacing = try container.decode(Int.self, forKey: .topSpacing) + show = try? container.decode(Int.self, forKey: .show) + required = try container.decode(Bool.self, forKey: .required) + } +} diff --git a/TesteiOS/TesteiOS/Models/FormData.swift b/TesteiOS/TesteiOS/Models/FormData.swift new file mode 100644 index 00000000..5a12968e --- /dev/null +++ b/TesteiOS/TesteiOS/Models/FormData.swift @@ -0,0 +1,25 @@ +// +// FormData.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct FormData { + let cells: [Cell] +} + +extension FormData: Decodable { + private enum CodingKeys: String, CodingKey { + case cells + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + cells = try container.decode([Cell].self, forKey: .cells) + } +} diff --git a/TesteiOS/TesteiOS/Models/Fund.swift b/TesteiOS/TesteiOS/Models/Fund.swift new file mode 100644 index 00000000..961d7b23 --- /dev/null +++ b/TesteiOS/TesteiOS/Models/Fund.swift @@ -0,0 +1,51 @@ +// +// Fund.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct Fund { + let title: String + let fundName: String + let whatIs: String + let definition: String + let riskTitle: String + let risk: Int + let infoTitle: String + let moreInfo: MoreInfoData + let info: [Info] + let downInfo: [Info] +} + +extension Fund: Decodable { + private enum CodingKeys: String, CodingKey { + case title + case fundName + case whatIs + case definition + case riskTitle + case risk + case infoTitle + case moreInfo + case info + case downInfo + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + title = try container.decode(String.self, forKey: .title) + fundName = try container.decode(String.self, forKey: .fundName) + whatIs = try container.decode(String.self, forKey: .whatIs) + definition = try container.decode(String.self, forKey: .definition) + riskTitle = try container.decode(String.self, forKey: .riskTitle) + risk = try container.decode(Int.self, forKey: .risk) + infoTitle = try container.decode(String.self, forKey: .infoTitle) + moreInfo = try container.decode(MoreInfoData.self, forKey: .moreInfo) + info = try container.decode([Info].self, forKey: .info) + downInfo = try container.decode([Info].self, forKey: .downInfo) + } +} diff --git a/TesteiOS/TesteiOS/Models/FundsData.swift b/TesteiOS/TesteiOS/Models/FundsData.swift new file mode 100644 index 00000000..a071fb7f --- /dev/null +++ b/TesteiOS/TesteiOS/Models/FundsData.swift @@ -0,0 +1,24 @@ +// +// FundsData.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct FundsData { + let fund: Fund +} + +extension FundsData: Decodable { + private enum CodingKeys: String, CodingKey { + case fund = "screen" + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + fund = try container.decode(Fund.self, forKey: .fund) + } +} diff --git a/TesteiOS/TesteiOS/Models/Info.swift b/TesteiOS/TesteiOS/Models/Info.swift new file mode 100644 index 00000000..200df1f9 --- /dev/null +++ b/TesteiOS/TesteiOS/Models/Info.swift @@ -0,0 +1,29 @@ +// +// Info.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct Info { + let name: String + let data: String? +} + +extension Info: Decodable { + private enum CodingKeys: String, CodingKey { + case name + case data + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + name = try container.decode(String.self, forKey: .name) + data = try? container.decode(String.self, forKey: .data) + } +} + + diff --git a/TesteiOS/TesteiOS/Models/MoreInfo.swift b/TesteiOS/TesteiOS/Models/MoreInfo.swift new file mode 100644 index 00000000..748e273e --- /dev/null +++ b/TesteiOS/TesteiOS/Models/MoreInfo.swift @@ -0,0 +1,27 @@ +// +// MoreInfo.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct MoreInfo { + let fund: Double + let cdi: Double +} + +extension MoreInfo: Decodable { + private enum CodingKeys: String, CodingKey { + case fund + case cdi = "CDI" + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + fund = try container.decode(Double.self, forKey: .fund) + cdi = try container.decode(Double.self, forKey: .cdi) + } +} diff --git a/TesteiOS/TesteiOS/Models/MoreInfoData.swift b/TesteiOS/TesteiOS/Models/MoreInfoData.swift new file mode 100644 index 00000000..ccd1b010 --- /dev/null +++ b/TesteiOS/TesteiOS/Models/MoreInfoData.swift @@ -0,0 +1,30 @@ +// +// MoreInfoData.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +struct MoreInfoData { + let month: MoreInfo + let year: MoreInfo + let twelveMonths: MoreInfo +} + +extension MoreInfoData: Decodable { + private enum CodingKeys: String, CodingKey { + case month + case year + case twelveMonths = "12months" + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + month = try container.decode(MoreInfo.self, forKey: .month) + year = try container.decode(MoreInfo.self, forKey: .year) + twelveMonths = try container.decode(MoreInfo.self, forKey: .twelveMonths) + } +} diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100755 index 00000000..8d8f4bb4 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "ItunesArtwork@2x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..6120803b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..15a86b00 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..3d4ecc89 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..b166735c Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..9553d814 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..fc89fb9c Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..15a86b00 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..382b185a Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..f3f00bbe Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..f3f00bbe Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..7b253000 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..7d8205d7 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..677267c7 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..95007bcc Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png new file mode 100644 index 00000000..d530bc1e Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/Contents.json new file mode 100644 index 00000000..660a5e19 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "checkboxEmpty.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "checkboxEmpty@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "checkboxEmpty@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty.png new file mode 100644 index 00000000..fa3f552b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@2x.png new file mode 100644 index 00000000..90acdb28 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@3x.png new file mode 100644 index 00000000..263484aa Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxEmpty.imageset/checkboxEmpty@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/Contents.json new file mode 100644 index 00000000..b14c979e --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "checkboxFilled.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "checkboxFilled@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "checkboxFilled@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled.png new file mode 100644 index 00000000..6488e68d Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@2x.png new file mode 100644 index 00000000..b7ea965b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@3x.png new file mode 100644 index 00000000..6ace6a7b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/checkboxFilled.imageset/checkboxFilled@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/Contents.json new file mode 100644 index 00000000..e3e7ef6c --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "download.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "download@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "download@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download.png new file mode 100644 index 00000000..4da26871 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@2x.png new file mode 100644 index 00000000..03332568 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@3x.png new file mode 100644 index 00000000..7e6c881a Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/download.imageset/download@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/Contents.json new file mode 100644 index 00000000..a689771e --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "indicator.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "indicator@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "indicator@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator.png new file mode 100644 index 00000000..1219c0fa Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@2x.png new file mode 100644 index 00000000..80187b04 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@3x.png new file mode 100644 index 00000000..98f57368 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/indicator.imageset/indicator@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/Contents.json new file mode 100644 index 00000000..d1c759f7 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "path2-6-2-path.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "path2-6-2-path@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "path2-6-2-path@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path.png new file mode 100644 index 00000000..05667bdc Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@2x.png new file mode 100644 index 00000000..fb77530e Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@3x.png new file mode 100644 index 00000000..b1ad623a Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/logo.imageset/path2-6-2-path@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/Contents.json new file mode 100644 index 00000000..2b9622b9 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "separator.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "separator@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "separator@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator.png new file mode 100644 index 00000000..42738412 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@2x.png new file mode 100644 index 00000000..7ded029d Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@3x.png new file mode 100644 index 00000000..d48143c7 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/separator.imageset/separator@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar.png new file mode 100644 index 00000000..91439b86 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@2x.png new file mode 100644 index 00000000..bda2532b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@3x.png new file mode 100644 index 00000000..27eb73c7 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Compartilhar@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Contents.json new file mode 100644 index 00000000..642fc812 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/share.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Compartilhar.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Compartilhar@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Compartilhar@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Contents.json new file mode 100644 index 00000000..598743e3 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Rectangle.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Rectangle@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Rectangle@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle.png new file mode 100644 index 00000000..6c54c5e3 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@2x.png new file mode 100644 index 00000000..1bd7c9d8 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@3x.png new file mode 100644 index 00000000..a87c4a2b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemNormal.imageset/Rectangle@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Contents.json b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Contents.json new file mode 100644 index 00000000..15f05dce --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Rectangle 3.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Rectangle 3@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Rectangle 3@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3.png new file mode 100644 index 00000000..5e31a34d Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@2x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@2x.png new file mode 100644 index 00000000..c08fc9ba Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@2x.png differ diff --git a/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@3x.png b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@3x.png new file mode 100644 index 00000000..c46e0c0c Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Assets.xcassets/tabBarItemSelected.imageset/Rectangle 3@3x.png differ diff --git a/TesteiOS/TesteiOS/Resources/ColorPalette.swift b/TesteiOS/TesteiOS/Resources/ColorPalette.swift new file mode 100644 index 00000000..45cf15b5 --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/ColorPalette.swift @@ -0,0 +1,29 @@ +// +// ColorPalette.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +enum ColorPalette { + static let jet = UIColor(hex: "333333") + + static let white = UIColor(hex: "FFFFFF") + + static let black = UIColor(hex: "333333") + + static let rossoCorsa = UIColor(hex: "DA0101") + + static let middleRedPurple = UIColor(hex: "EB7676") + + static let silverChalice = UIColor(hex: "ACACAC") + + static let green = UIColor(hex: "65BE30") + + static let red = UIColor(hex: "FF1F1F") + + static let isabelline = UIColor(hex: "EFEEED") +} diff --git a/TesteiOS/TesteiOS/Resources/FontNames.swift b/TesteiOS/TesteiOS/Resources/FontNames.swift new file mode 100644 index 00000000..60d21adc --- /dev/null +++ b/TesteiOS/TesteiOS/Resources/FontNames.swift @@ -0,0 +1,17 @@ +// +// FontNames.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +enum FontNames { + static let black = "DINPro-Black" + static let bold = "DINPro-Bold" + static let medium = "DINPro-Medium" + static let light = "DINPro-Light" + static let regular = "DINPro-Regular" +} diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINEngschriftStd.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINEngschriftStd.otf new file mode 100755 index 00000000..ae85f8ee Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINEngschriftStd.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINMittelschriftStd.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINMittelschriftStd.otf new file mode 100755 index 00000000..9a6e0d4f Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINMittelschriftStd.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-BdCond.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-BdCond.otf new file mode 100755 index 00000000..1da42b06 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-BdCond.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-Light.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-Light.otf new file mode 100755 index 00000000..0cda2e5b Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINNeuzeitGroteskStd-Light.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Black.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Black.otf new file mode 100755 index 00000000..2092a7bb Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Black.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Bold.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Bold.otf new file mode 100755 index 00000000..7c839536 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Bold.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Light.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Light.otf new file mode 100755 index 00000000..8a7f085a Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Light.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Medium.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Medium.otf new file mode 100755 index 00000000..b4608d06 Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Medium.otf differ diff --git a/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Regular.otf b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Regular.otf new file mode 100755 index 00000000..84d57abb Binary files /dev/null and b/TesteiOS/TesteiOS/Resources/Fonts/DINPro-Regular.otf differ diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactDataSource.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactDataSource.swift new file mode 100644 index 00000000..aa802334 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactDataSource.swift @@ -0,0 +1,81 @@ +// +// ContactDataSource.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +typealias Value = (message: String, data: Any) + +class ContactDataSource: NSObject, ItemsTableViewDataSource { + + var items: [Cell] = [] + var tableView: UITableView? + var delegate: UITableViewDelegate? + var values: [Value] = [] + var enableSendButton: ((Bool) -> ())? + var sendAction: (([Value]) -> ())? + + required init(tableView: UITableView, delegate: UITableViewDelegate) { + self.tableView = tableView + self.delegate = delegate + super.init() + setupTableView() + } + + func registerTableView() { + for item in items { + let type = CellType(rawValue: item.type)! + self.tableView?.register(type.getNib(), forCellReuseIdentifier: type.getIdentifier()) + } + } + + func update(with items: [Cell]) { + self.items = items.filter { !$0.hidden } + self.registerTableView() + self.tableView?.reloadData() + } + + func sendButtonPressed() { + sendAction?(values) + values = [] + } + + func validValue(_ value: Value) { + if values.contains(where: { $0.message == value.message }) { + for i in 0.. i else { return } + if values[i].message == value.message { + values[i].data = value.data + if let data = value.data as? String, data.isEmpty { + values.remove(at: i) + enableSendButton?(false) + } + } + } + } else { + values.append(value) + } + enableSendButton?(values.count == items.filter{ $0.required }.count) + } +} + +extension ContactDataSource: UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return items.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let item = items[indexPath.row] + let type = CellType(rawValue: item.type)! + let cell = tableView.dequeueReusableCell(withIdentifier: type.getIdentifier(), for: indexPath) as! ContactBaseTableViewCell + enableSendButton = cell.enableAction + cell.sendAction = sendButtonPressed + cell.callback = validValue + cell.setup(with: item) + return cell + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactDelegate.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactDelegate.swift new file mode 100644 index 00000000..ead6c56d --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactDelegate.swift @@ -0,0 +1,31 @@ +// +// ContactDelegate.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class ContactDelegate: NSObject, UITableViewDelegate { + + weak var tableView: ContactTableView? + + var items: [Cell] = [] + + init(tableView: ContactTableView) { + self.tableView = tableView + super.init() + self.tableView?.delegate = self + } + + func update(with items: [Cell]) { + self.items = items.filter { !$0.hidden } + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + let spacing = items[indexPath.row].topSpacing + return CGFloat(50 + spacing) + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactInteractor.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactInteractor.swift new file mode 100644 index 00000000..62d85835 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactInteractor.swift @@ -0,0 +1,53 @@ +// +// ContactInteractor.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol ContactBusinessLogic { + func fetchForm(request: Contact.Form.Request) + func sendFormData(request: Contact.Send.Request) +} + +protocol ContactDataStore { + //var name: String { get set } +} + +class ContactInteractor: ContactBusinessLogic, ContactDataStore { + var presenter: ContactPresentationLogic? + var worker: ContactWorker? + //var name: String = "" + + init(worker: ContactWorker? = ContactWorker()) { + self.worker = worker + } + + // MARK: Fetch Form + func fetchForm(request: Contact.Form.Request) { + worker?.fetchForm(request: request, completion: { result in + switch result { + case .success(let data): + let response = Contact.Form.Response(cells: data.cells) + self.presenter?.presentForm(response: response) + case .failure(let error): + let response = Contact.Form.Response(error: error) + self.presenter?.presentErrorMessage(response: response) + } + }) + } + + // MARK: Send form data + func sendFormData(request: Contact.Send.Request) { + let response = Contact.Send.Response() + presenter?.presentSuccesseMessage(response: response) + // TODO: Send form data + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactModels.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactModels.swift new file mode 100644 index 00000000..d729204f --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactModels.swift @@ -0,0 +1,48 @@ +// +// ContactModels.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +enum Contact { + // MARK: Use cases + enum Send { + struct Request{ + let values: [Value] + } + struct Response {} + struct ViewModel {} + } + + enum Form { + struct Request{} + + struct Response { + let cells: [Cell] + let error: Error? + + init(cells: [Cell] = [], error: Error? = .none) { + self.cells = cells + self.error = error + } + } + struct ViewModel { + let cells: [Cell] + let error: Error? + + init(cells: [Cell] = [], error: Error? = .none) { + self.cells = cells + self.error = error + } + } + } + +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactPresenter.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactPresenter.swift new file mode 100644 index 00000000..5834609f --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactPresenter.swift @@ -0,0 +1,41 @@ +// +// ContactPresenter.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol ContactPresentationLogic { + func presentForm(response: Contact.Form.Response) + func presentSuccesseMessage(response: Contact.Send.Response) + func presentErrorMessage(response: Contact.Form.Response) +} + +class ContactPresenter: ContactPresentationLogic { + weak var viewController: ContactDisplayLogic? + + // MARK: Present Form + func presentForm(response: Contact.Form.Response) { + let viewModel = Contact.Form.ViewModel(cells: response.cells) + viewController?.displayForm(viewModel: viewModel) + } + + // MARK: Present Success Message + func presentSuccesseMessage(response: Contact.Send.Response) { + let viewModel = Contact.Send.ViewModel() + viewController?.displaySuccessMessage(viewModel: viewModel) + } + + // MARK: Present Error Message + func presentErrorMessage(response: Contact.Form.Response) { + let viewModel = Contact.Form.ViewModel(error: response.error) + viewController?.displayErrorMessage(viewModel: viewModel) + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactRouter.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactRouter.swift new file mode 100644 index 00000000..59059a2f --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactRouter.swift @@ -0,0 +1,57 @@ +// +// ContactRouter.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +@objc protocol ContactRoutingLogic { + //func routeToSomewhere(segue: UIStoryboardSegue?) +} + +protocol ContactDataPassing { + var dataStore: ContactDataStore? { get } +} + +class ContactRouter: NSObject, ContactRoutingLogic, ContactDataPassing { + weak var viewController: ContactViewController? + var dataStore: ContactDataStore? + + // MARK: Routing + + //func routeToSomewhere(segue: UIStoryboardSegue?) + //{ + // if let segue = segue { + // let destinationVC = segue.destination as! SomewhereViewController + // var destinationDS = destinationVC.router!.dataStore! + // passDataToSomewhere(source: dataStore!, destination: &destinationDS) + // } else { + // let storyboard = UIStoryboard(name: "Main", bundle: nil) + // let destinationVC = storyboard.instantiateViewController(withIdentifier: "SomewhereViewController") as! SomewhereViewController + // var destinationDS = destinationVC.router!.dataStore! + // passDataToSomewhere(source: dataStore!, destination: &destinationDS) + // navigateToSomewhere(source: viewController!, destination: destinationVC) + // } + //} + + // MARK: Navigation + + //func navigateToSomewhere(source: ContactViewController, destination: SomewhereViewController) + //{ + // source.show(destination, sender: nil) + //} + + // MARK: Passing data + + //func passDataToSomewhere(source: ContactDataStore, destination: inout SomewhereDataStore) + //{ + // destination.name = source.name + //} +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactViewController.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactViewController.swift new file mode 100644 index 00000000..96359a74 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactViewController.swift @@ -0,0 +1,103 @@ +// +// ContactViewController.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol ContactDisplayLogic: class { + func displayForm(viewModel: Contact.Form.ViewModel) + func displayErrorMessage(viewModel: Contact.Form.ViewModel) + func displaySuccessMessage(viewModel: Contact.Send.ViewModel) +} + +class ContactViewController: UIViewController { + var interactor: ContactBusinessLogic? + var router: (NSObjectProtocol & ContactRoutingLogic & ContactDataPassing)? + + let contactView = ContactView() + + // MARK: Object lifecycle + init() { + super.init(nibName: .none, bundle: .none) + title = "Contato" + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + // MARK: Setup + private func setup() { + let viewController = self + let interactor = ContactInteractor() + let presenter = ContactPresenter() + let router = ContactRouter() + viewController.interactor = interactor + viewController.router = router + interactor.presenter = presenter + presenter.viewController = viewController + router.viewController = viewController + router.dataStore = interactor + } + + // MARK: View lifecycle + override func viewDidLoad() { + super.viewDidLoad() + setupView() + fetchForm() + } + + override func loadView() { + view = contactView + } + + func setupView() { + let tapGeture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard)) + view.addGestureRecognizer(tapGeture) + contactView.tableView.setSendHandler(sendButtonPressed) + } + + @objc func hideKeyboard() { + view.endEditing(true) + } + + func sendButtonPressed(_ values: [Value]) { + print(values) + let request = Contact.Send.Request(values: values) + interactor?.sendFormData(request: request) + } + + // MARK: Fetch Form + func fetchForm() { + let request = Contact.Form.Request() + interactor?.fetchForm(request: request) + contactView.activityIndicator.startAnimating() + } +} + +extension ContactViewController: ContactDisplayLogic { + func displayForm(viewModel: Contact.Form.ViewModel) { + contactView.activityIndicator.stopAnimating() + contactView.tableView.update(with: viewModel.cells) + } + + func displaySuccessMessage(viewModel: Contact.Send.ViewModel) { + contactView.showFeedbackView() + contactView.tableView.reloadData() + } + + func displayErrorMessage(viewModel: Contact.Form.ViewModel) { + + contactView.activityIndicator.stopAnimating() + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Contact/ContactWorker.swift b/TesteiOS/TesteiOS/Scenes/Contact/ContactWorker.swift new file mode 100644 index 00000000..a347ae96 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Contact/ContactWorker.swift @@ -0,0 +1,29 @@ +// +// ContactWorker.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit +import Alamofire + +class ContactWorker { + + private let networkManager: Networkable + + init(networkManager: Networkable = NetworkManager()) { + self.networkManager = networkManager + } + + func fetchForm(request: Contact.Form.Request, completion: @escaping (Result) -> ()) { + networkManager.fetchForm(request: request) { result in + completion(result) + } + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsDataSource.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsDataSource.swift new file mode 100644 index 00000000..c6245bc6 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsDataSource.swift @@ -0,0 +1,71 @@ +// +// FundsDataSource.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FundsDataSource: NSObject, ItemsTableViewDataSource { + + var items: [CellType] = [] + var fund: Fund? = .none + var tableView: UITableView? + var delegate: UITableViewDelegate? + var investAction: (() -> ())? + var downloadAction: ((String?) -> ())? + + required init(tableView: UITableView, delegate: UITableViewDelegate) { + self.tableView = tableView + self.delegate = delegate + super.init() + setupTableView() + } + + func registerTableView() { + for item in items { + self.tableView?.register(item.getNib(), forCellReuseIdentifier: item.getIdentifier()) + } + } + + func update(with fund: Fund) { + self.fund = fund + self.items = [.fundHeader, .moreInfo, .info, .downInfo, .invest] + self.registerTableView() + self.tableView?.reloadData() + } +} + +extension FundsDataSource: UITableViewDataSource { + + func numberOfSections(in tableView: UITableView) -> Int { + return items.count + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch section { + case 0, 1, 4 : + return 1 + case 2: + return fund!.info.count + case 3: + return fund!.downInfo.count + default: + return 0 + } + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let type = items[indexPath.section] + let cell = tableView.dequeueReusableCell(withIdentifier: type.getIdentifier(), for: indexPath) as! FundBaseTableViewCell + + cell.tag = indexPath.row + cell.investAction = investAction + cell.downloadAction = downloadAction + cell.setup(with: fund!) + + return cell + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsDelegate.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsDelegate.swift new file mode 100644 index 00000000..f4bf1042 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsDelegate.swift @@ -0,0 +1,26 @@ +// +// FundsDelegate.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FundsDelegate: NSObject, UITableViewDelegate { + + weak var tableView: UITableView? + + var items: [CellType] = [.fundHeader, .moreInfo, .info, .downInfo, .invest] + + init(tableView: UITableView) { + self.tableView = tableView + super.init() + self.tableView?.delegate = self + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return items[indexPath.section].getHeight() + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsInteractor.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsInteractor.swift new file mode 100644 index 00000000..bce0b29b --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsInteractor.swift @@ -0,0 +1,53 @@ +// +// FundsInteractor.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol FundsBusinessLogic { + func fetchFund(request: Funds.Get.Request) + func downloadData(request: Funds.Download.Request) +} + +protocol FundsDataStore { + var url: String { get set } +} + +class FundsInteractor: FundsBusinessLogic, FundsDataStore { + var presenter: FundsPresentationLogic? + var worker: FundsWorker? + var url: String = "" + + init(worker: FundsWorker? = FundsWorker()) { + self.worker = worker + } + + // MARK: Fetch fund + func fetchFund(request: Funds.Get.Request) { + worker?.fetchFund(request: request, completion: { result in + switch result { + case .success(let data): + let response = Funds.Get.Response(fund: data.fund) + self.presenter?.presentFund(response: response) + case .failure(let error): + let response = Funds.Get.Response(error: error) + self.presenter?.presentErrorMessage(response: response) + } + }) + } + + // MARK: Fetch data + func downloadData(request: Funds.Download.Request) { + url = request.url ?? "https://www.google.com/" + let response = Funds.Download.Response() + presenter?.presentDownloadedData(response: response) + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsModels.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsModels.swift new file mode 100644 index 00000000..55ce7ce2 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsModels.swift @@ -0,0 +1,46 @@ +// +// FundsModels.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +enum Funds { + // MARK: Use cases + enum Download { + struct Request { + let url: String? + } + struct Response {} + struct ViewModel {} + } + + enum Get { + struct Request {} + struct Response { + let fund: Fund? + let error: Error? + + init(fund: Fund? = .none, error: Error? = .none) { + self.fund = fund + self.error = error + } + } + struct ViewModel { + let fund: Fund? + let error: Error? + + init(fund: Fund? = .none, error: Error? = .none) { + self.fund = fund + self.error = error + } + } + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsPresenter.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsPresenter.swift new file mode 100644 index 00000000..ebf02d30 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsPresenter.swift @@ -0,0 +1,41 @@ +// +// FundsPresenter.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol FundsPresentationLogic { + func presentFund(response: Funds.Get.Response) + func presentDownloadedData(response: Funds.Download.Response) + func presentErrorMessage(response: Funds.Get.Response) +} + +class FundsPresenter: FundsPresentationLogic { + weak var viewController: FundsDisplayLogic? + + // MARK: Present Fund + func presentFund(response: Funds.Get.Response) { + let viewModel = Funds.Get.ViewModel(fund: response.fund) + viewController?.displayFund(viewModel: viewModel) + } + + // MARK: Present Data + func presentDownloadedData(response: Funds.Download.Response) { + let viewModel = Funds.Download.ViewModel() + viewController?.displayDownloadedData(viewModel: viewModel) + } + + // MARK: Present Error Message + func presentErrorMessage(response: Funds.Get.Response) { + let viewModel = Funds.Get.ViewModel(error: response.error) + viewController?.displayErrorMessage(viewModel: viewModel) + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsRouter.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsRouter.swift new file mode 100644 index 00000000..857ece3a --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsRouter.swift @@ -0,0 +1,44 @@ +// +// FundsRouter.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit +import SafariServices + +@objc protocol FundsRoutingLogic { + func routeToDownloadData() +} + +protocol FundsDataPassing { + var dataStore: FundsDataStore? { get } +} + +class FundsRouter: NSObject, FundsRoutingLogic, FundsDataPassing { + weak var viewController: FundsViewController? + var dataStore: FundsDataStore? + + // MARK: Routing + func routeToDownloadData() { + guard let string = dataStore?.url, let url = URL(string: string) else { return } + let safariViewController = SFSafariViewController(url: url) + navigateToDownloadData(source: viewController!, destination: safariViewController) + } + + // MARK: Navigation + func navigateToDownloadData(source: FundsViewController, destination: SFSafariViewController) { + source.present(destination, animated: true) + } + + // MARK: Passing data +// func passDataToSomewhere(source: FundsDataStore, destination: inout SomewhereDataStore) { +// destination.name = source.name +// } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsViewController.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsViewController.swift new file mode 100644 index 00000000..f35fdf64 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsViewController.swift @@ -0,0 +1,101 @@ +// +// FundsViewController.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit + +protocol FundsDisplayLogic: class { + func displayFund(viewModel: Funds.Get.ViewModel) + func displayDownloadedData(viewModel: Funds.Download.ViewModel) + func displayErrorMessage(viewModel: Funds.Get.ViewModel) +} + +class FundsViewController: UIViewController { + var interactor: FundsBusinessLogic? + var router: (NSObjectProtocol & FundsRoutingLogic & FundsDataPassing)? + + let fundsView = FundsView() + + // MARK: Object lifecycle + init() { + super.init(nibName: .none, bundle: .none) + title = "Investimento" + navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "share"), style: .plain, target: .none, action: .none) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + // MARK: Setup + private func setup() { + let viewController = self + let interactor = FundsInteractor() + let presenter = FundsPresenter() + let router = FundsRouter() + viewController.interactor = interactor + viewController.router = router + interactor.presenter = presenter + presenter.viewController = viewController + router.viewController = viewController + router.dataStore = interactor + } + + // MARK: View lifecycle + override func viewDidLoad() { + super.viewDidLoad() + setupView() + fetchFund() + } + + override func loadView() { + view = fundsView + } + + func setupView() { + fundsView.tableView.setInvestHandler(investButtonPressed) + fundsView.tableView.setDownloadHandler(downloadButtonPressed) + } + + func investButtonPressed() { + // TODO: Invest Button pressed action + print("Investir") + } + + func downloadButtonPressed(_ url: String?) { + let request = Funds.Download.Request(url: url) + interactor?.downloadData(request: request) + } + + // MARK: Fetch Fund + func fetchFund() { + let request = Funds.Get.Request() + interactor?.fetchFund(request: request) + fundsView.activityIndicator.startAnimating() + } +} + +extension FundsViewController: FundsDisplayLogic { + func displayFund(viewModel: Funds.Get.ViewModel) { + fundsView.tableView.update(with: viewModel.fund!) + fundsView.activityIndicator.stopAnimating() + } + + func displayDownloadedData(viewModel: Funds.Download.ViewModel) { + router?.routeToDownloadData() + } + + func displayErrorMessage(viewModel: Funds.Get.ViewModel) { + fundsView.activityIndicator.stopAnimating() + } +} diff --git a/TesteiOS/TesteiOS/Scenes/Funds/FundsWorker.swift b/TesteiOS/TesteiOS/Scenes/Funds/FundsWorker.swift new file mode 100644 index 00000000..5afed537 --- /dev/null +++ b/TesteiOS/TesteiOS/Scenes/Funds/FundsWorker.swift @@ -0,0 +1,29 @@ +// +// FundsWorker.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright (c) 2019 Brendoon Ryos. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +import UIKit +import Alamofire + +class FundsWorker { + + private let networkManager: Networkable + + init(networkManager: Networkable = NetworkManager()) { + self.networkManager = networkManager + } + + func fetchFund(request: Funds.Get.Request, completion: @escaping (Result) -> ()) { + networkManager.fetchFund(request: request) { result in + completion(result) + } + } +} diff --git a/TesteiOS/TesteiOS/Services/BankAPI+Testing.swift b/TesteiOS/TesteiOS/Services/BankAPI+Testing.swift new file mode 100644 index 00000000..25fc0495 --- /dev/null +++ b/TesteiOS/TesteiOS/Services/BankAPI+Testing.swift @@ -0,0 +1,25 @@ +// +// BankAPI+Testing.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +extension BankAPI { + var sampleData: Data { + switch self { + case .fetchForm: + return stubbedResponse("Form") + case .fetchFund: + return stubbedResponse("Fund") + } + } + + func stubbedResponse(_ filename: String, bundle: Bundle = .main) -> Data! { + let path = bundle.path(forResource: filename, ofType: "json") + return (try? Data(contentsOf: URL(fileURLWithPath: path!))) + } +} diff --git a/TesteiOS/TesteiOS/Services/BankAPI.swift b/TesteiOS/TesteiOS/Services/BankAPI.swift new file mode 100644 index 00000000..e8ece93b --- /dev/null +++ b/TesteiOS/TesteiOS/Services/BankAPI.swift @@ -0,0 +1,63 @@ +// +// BankAPI.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation +import Moya + +enum BankAPI { + case fetchForm + case fetchFund +} + +extension BankAPI: TargetType { + var environmentBaseURL: String { + switch NetworkManager.environment { + case .staging: + return "https://floating-mountain-50292.herokuapp.com" + case .qa: + return "" + case .production: + return "" + } + } + + var baseURL: URL { + guard let url = URL(string: environmentBaseURL) else { fatalError("baseURL could not be configured.") } + return url + } + + var path: String { + switch self { + case .fetchForm: + return "/cells.json" + case .fetchFund: + return "/fund.json" + } + } + + var method: Moya.Method { + switch self { + default: + return .get + } + } + + var task: Task { + switch self { + default: + return .requestPlain + } + } + + var headers: [String : String]? { + switch self { + default: + return ["Content-type":"application/json"] + } + } +} diff --git a/TesteiOS/TesteiOS/Services/DefaultAlamofireManager.swift b/TesteiOS/TesteiOS/Services/DefaultAlamofireManager.swift new file mode 100644 index 00000000..33c18054 --- /dev/null +++ b/TesteiOS/TesteiOS/Services/DefaultAlamofireManager.swift @@ -0,0 +1,20 @@ +// +// DefaultAlamofireManager.swift +// TesteiOS +// +// Created by Brendoon Ryos on 13/01/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Alamofire + +class DefaultAlamofireManager: Alamofire.SessionManager { + static let sharedManager: DefaultAlamofireManager = { + let configuration = URLSessionConfiguration.default + configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders + configuration.timeoutIntervalForRequest = 30 + configuration.timeoutIntervalForResource = 30 + configuration.requestCachePolicy = .useProtocolCachePolicy + return DefaultAlamofireManager(configuration: configuration) + }() +} diff --git a/TesteiOS/TesteiOS/Services/NetworkManager.swift b/TesteiOS/TesteiOS/Services/NetworkManager.swift new file mode 100644 index 00000000..7fe25bae --- /dev/null +++ b/TesteiOS/TesteiOS/Services/NetworkManager.swift @@ -0,0 +1,60 @@ +// +// NetworkManager.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation +import Moya +import Alamofire + +enum APIEnvironment { + case staging + case qa + case production +} + +protocol Networkable { + var provider: MoyaProvider { get } + func fetchForm(request: Contact.Form.Request, completion: @escaping (Result) -> ()) + func fetchFund(request: Funds.Get.Request, completion: @escaping (Result) -> ()) +} + +struct NetworkManager: Networkable { + let provider = MoyaProvider(manager: DefaultAlamofireManager.sharedManager, plugins: [NetworkLoggerPlugin(verbose: true)]) + static let environment: APIEnvironment = .staging + + func fetchForm(request: Contact.Form.Request, completion: @escaping (Result) -> ()) { + provider.request(.fetchForm) { result in + switch result { + case .success(let response): + do { + let formData = try JSONDecoder().decode(FormData.self, from: response.data) + completion(Result.success(formData)) + } catch let error { + fatalError("data could not be decoded: \(error)") + } + case .failure(let error): + completion(Result.failure(error)) + } + } + } + + func fetchFund(request: Funds.Get.Request, completion: @escaping (Result) -> ()) { + provider.request(.fetchFund) { result in + switch result { + case .success(let response): + do { + let fundsData = try JSONDecoder().decode(FundsData.self, from: response.data) + completion(Result.success(fundsData)) + } catch let error { + fatalError("data could not be decoded: \(error)") + } + case .failure(let error): + completion(Result.failure(error)) + } + } + } +} diff --git a/TesteiOS/TesteiOS/Services/StubbedResponses/Form.json b/TesteiOS/TesteiOS/Services/StubbedResponses/Form.json new file mode 100644 index 00000000..61588115 --- /dev/null +++ b/TesteiOS/TesteiOS/Services/StubbedResponses/Form.json @@ -0,0 +1,64 @@ +{ + "cells": [ + { + "id": 1, + "type": 2, + "message": "Olá, primeiro se apresente com o seu nome:", + "typefield": null, + "hidden": false, + "topSpacing": 60, + "show": null, + "required": false + }, + { + "id": 2, + "type": 1, + "message": "Nome completo", + "typefield": 1, + "hidden": false, + "topSpacing": 35, + "show": null, + "required": true + }, + { + "id": 4, + "type": 1, + "message": "Email", + "typefield": 3, + "hidden": true, + "topSpacing": 35, + "show": null, + "required": true + }, + { + "id": 6, + "type": 1, + "message": "Telefone", + "typefield": "telnumber", + "hidden": false, + "topSpacing": 10, + "show": null, + "required": true + }, + { + "id": 3, + "type": 4, + "message": "Gostaria de cadastrar meu email", + "typefield": null, + "hidden": false, + "topSpacing": 35, + "show": 4, + "required": false + }, + { + "id": 7, + "type": 5, + "message": "Enviar", + "typefield": null, + "hidden": false, + "topSpacing": 10, + "show": null, + "required": true + } + ] +} diff --git a/TesteiOS/TesteiOS/Services/StubbedResponses/Fund.json b/TesteiOS/TesteiOS/Services/StubbedResponses/Fund.json new file mode 100644 index 00000000..0a3bcdec --- /dev/null +++ b/TesteiOS/TesteiOS/Services/StubbedResponses/Fund.json @@ -0,0 +1,77 @@ +{ + "screen": { + "title": "Fundos de investimento", + "fundName": "Vinci Valorem FI Multimercado", + "whatIs": "O que é?", + "definition": "O Fundo tem por objetivo proporcionar aos seus cotistas rentabilidade no longo prazo através de investimentos.", + "riskTitle": "Grau de risco do investimento", + "risk": 4, + "infoTitle": "Mais informações sobre o investimento", + "moreInfo": { + "month": { + "fund": 0.3, + "CDI": 0.3 + }, + "year": { + "fund": 13.01, + "CDI": 12.08 + }, + "12months": { + "fund": 17.9, + "CDI": 17.6 + } + }, + "info": [ + { + "name": "Taxa de administração", + "data": "0,50%" + }, + { + "name": "Aplicação inicial", + "data": "R$ 10.000,00" + }, + { + "name": "Movimentação mínima", + "data": "R$ 1.000,00" + }, + { + "name": "Saldo mínimo", + "data": "R$ 5.000,00" + }, + { + "name": "Resgate (valor bruto)", + "data": "D+0" + }, + { + "name": "Cota (valor bruto)", + "data": "D+1" + }, + { + "name": "Pagamento (valor bruto)", + "data": "D+2" + } + ], + "downInfo": [ + { + "name": "Essenciais", + "data": null + }, + { + "name": "Desempenho", + "data": null + }, + { + "name": "Complementares", + "data": null + }, + { + "name": "Regulamento", + "data": null + }, + { + "name": "Adesão", + "data": null + } + ] + } +} diff --git a/TesteiOS/TesteiOS/Supporting Files/AppDelegate.swift b/TesteiOS/TesteiOS/Supporting Files/AppDelegate.swift new file mode 100644 index 00000000..8c6b1247 --- /dev/null +++ b/TesteiOS/TesteiOS/Supporting Files/AppDelegate.swift @@ -0,0 +1,40 @@ +// +// AppDelegate.swift +// TesteiOS +// +// Created by Brendoon Ryos on 19/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + self.window = UIWindow(frame: UIScreen.main.bounds) + self.window?.backgroundColor = UIColor.white + + let tabBarController = TabBarViewController() + let fundsVC = FundsViewController() + let contactVC = ContactViewController() + + let fundsNavigationController = UINavigationController(rootViewController: fundsVC) + let contactNavigationController = UINavigationController(rootViewController: contactVC) + + tabBarController.viewControllers = [fundsNavigationController, contactNavigationController] + + self.window?.rootViewController = tabBarController + self.window?.makeKeyAndVisible() + + AppearanceProxyHelper.customizeNavigationBar() + + return true + } + +} + diff --git a/TesteiOS/TesteiOS/Supporting Files/Base.lproj/LaunchScreen.storyboard b/TesteiOS/TesteiOS/Supporting Files/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..4c3e9800 --- /dev/null +++ b/TesteiOS/TesteiOS/Supporting Files/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/Supporting Files/Extensions/String+Validator.swift b/TesteiOS/TesteiOS/Supporting Files/Extensions/String+Validator.swift new file mode 100644 index 00000000..6bbacac5 --- /dev/null +++ b/TesteiOS/TesteiOS/Supporting Files/Extensions/String+Validator.swift @@ -0,0 +1,68 @@ +// +// String+Validator.swift +// TesteiOSv2 +// +// Created by Brendoon Ryos on 11/01/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +extension String { + var isValidCPF: Bool { + + let numbers = self.compactMap({Int(String($0))}) + guard numbers.count == 11 && Set(numbers).count != 1 else { return false } + let sum1 = 11 - ( numbers[0] * 10 + + numbers[1] * 9 + + numbers[2] * 8 + + numbers[3] * 7 + + numbers[4] * 6 + + numbers[5] * 5 + + numbers[6] * 4 + + numbers[7] * 3 + + numbers[8] * 2 ) % 11 + let dv1 = sum1 > 9 ? 0 : sum1 + let sum2 = 11 - ( numbers[0] * 11 + + numbers[1] * 10 + + numbers[2] * 9 + + numbers[3] * 8 + + numbers[4] * 7 + + numbers[5] * 6 + + numbers[6] * 5 + + numbers[7] * 4 + + numbers[8] * 3 + + numbers[9] * 2 ) % 11 + let dv2 = sum2 > 9 ? 0 : sum2 + return dv1 == numbers[9] && dv2 == numbers[10] + } + + var isValidEmail: Bool { + let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" + + let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) + return emailTest.evaluate(with: self) + } + + func isValidPassword() -> Bool { + let capitalLetterRegEx = ".*[A-Z]+.*" + let texttest = NSPredicate(format:"SELF MATCHES %@", capitalLetterRegEx) + if !texttest.evaluate(with: self) { + return false + } + + let specialCharacterRegEx = ".*[!@#$%&*():_+=/?´~;{}*ºª|\\,(){}^\\[\\]\"]+.*" + let texttest2 = NSPredicate(format:"SELF MATCHES %@", specialCharacterRegEx) + if !texttest2.evaluate(with: self) { + return false + } + + let alphanumericLetterRegEx = ".*[0-9]+.*" + let texttest3 = NSPredicate(format:"SELF MATCHES %@", alphanumericLetterRegEx) + if !texttest3.evaluate(with: self) { + return false + } + + return true + } +} diff --git a/TesteiOS/TesteiOS/Supporting Files/Extensions/UIColor+Hex.swift b/TesteiOS/TesteiOS/Supporting Files/Extensions/UIColor+Hex.swift new file mode 100644 index 00000000..27016718 --- /dev/null +++ b/TesteiOS/TesteiOS/Supporting Files/Extensions/UIColor+Hex.swift @@ -0,0 +1,35 @@ +// +// UIColor+Hex.swift +// Movs +// +// Created by Brendoon Ryos on 25/01/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +extension UIColor { + static func rgb(red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor { + return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: 1) + } + + public convenience init(hex: String, alpha: CGFloat = 1) { + let scanner = Scanner(string: hex) + scanner.scanLocation = 0 + + var rgbValue: UInt64 = 0 + + scanner.scanHexInt64(&rgbValue) + + let r = (rgbValue & 0xff0000) >> 16 + let g = (rgbValue & 0xff00) >> 8 + let b = rgbValue & 0xff + + self.init( + red: CGFloat(r) / 0xff, + green: CGFloat(g) / 0xff, + blue: CGFloat(b) / 0xff, + alpha: alpha + ) + } +} diff --git a/TesteiOS/TesteiOS/Supporting Files/Info.plist b/TesteiOS/TesteiOS/Supporting Files/Info.plist new file mode 100644 index 00000000..1f636854 --- /dev/null +++ b/TesteiOS/TesteiOS/Supporting Files/Info.plist @@ -0,0 +1,57 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + 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 + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleLightContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/TesteiOS/TesteiOS/UI/Appearance/AppearanceProxyHelper.swift b/TesteiOS/TesteiOS/UI/Appearance/AppearanceProxyHelper.swift new file mode 100644 index 00000000..78f1df6e --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Appearance/AppearanceProxyHelper.swift @@ -0,0 +1,24 @@ +// +// AppearanceProxyHelper.swift +// Movs +// +// Created by Brendoon Ryos on 24/01/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +struct AppearanceProxyHelper { + + private init() {} + + static func customizeNavigationBar(){ + let navBarAppearance = UINavigationBar.appearance() + navBarAppearance.isTranslucent = false + navBarAppearance.shadowImage = UIImage() + navBarAppearance.setBackgroundImage(UIImage(), for: .default) + navBarAppearance.barTintColor = ColorPalette.white + navBarAppearance.tintColor = ColorPalette.rossoCorsa + navBarAppearance.titleTextAttributes = [NSAttributedString.Key.font: UIFont(name: FontNames.medium, size: 16)!, NSAttributedString.Key.foregroundColor: ColorPalette.jet] + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.swift new file mode 100755 index 00000000..a89e40ca --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.swift @@ -0,0 +1,39 @@ +// +// CheckboxTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +final class CheckboxTableViewCell: ContactBaseTableViewCell { + + @IBOutlet weak var checkboxButton: UIButton! + + override func awakeFromNib() { + super.awakeFromNib() + checkboxButton.titleLabel?.adjustsFontSizeToFitWidth = true + checkboxButton.titleLabel?.minimumScaleFactor = 0.5 + } + + override func setup(with item: Cell) { + super.setup(with: item) + checkboxButton.isSelected = false + checkboxButton.setImage(UIImage(named: "checkboxEmpty"), for: .normal) + checkboxButton.setTitle(item.message, for: .normal) + callback?((item.message, false)) + } + + @IBAction func checkboxButtonPressed(_ sender: UIButton) { + if sender.isSelected { + sender.isSelected = false + sender.setImage(UIImage(named: "checkboxEmpty"), for: .normal) + } else { + sender.isSelected = true + sender.setImage(UIImage(named: "checkboxFilled"), for: .normal) + } + callback?((sender.title(for: .normal)!, sender.isSelected)) + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.xib new file mode 100755 index 00000000..872daa79 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.xib @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/ContactBaseTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Contact/ContactBaseTableViewCell.swift new file mode 100644 index 00000000..dcb684b5 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/ContactBaseTableViewCell.swift @@ -0,0 +1,29 @@ +// +// ContactBaseTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit +import Reusable + +class ContactBaseTableViewCell: UITableViewCell, NibReusable { + + @IBOutlet weak var topSpacingConstraint: NSLayoutConstraint! + + var callback: ((Value) -> ())? + var sendAction: (() -> ())? + + override func awakeFromNib() { + super.awakeFromNib() + } + + func setup(with item: Cell) { + topSpacingConstraint.constant = CGFloat(item.topSpacing) + self.layoutIfNeeded() + } + + func enableAction(_ value: Bool) {} +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.swift new file mode 100755 index 00000000..2fc29ef9 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.swift @@ -0,0 +1,42 @@ +// +// SendTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +final class SendTableViewCell: ContactBaseTableViewCell { + + @IBOutlet weak var sendButton: UIButton! + + override func awakeFromNib() { + super.awakeFromNib() + sendButton.layer.cornerRadius = sendButton.frame.height / 2 + } + + override func setup(with item: Cell) { + super.setup(with: item) + sendButton.isUserInteractionEnabled = false + sendButton.transform = CGAffineTransform.identity + sendButton.backgroundColor = ColorPalette.middleRedPurple + sendButton.setTitle(item.message, for: .normal) + sendButton.addTarget(self, action: #selector(sendButtonPressed(_:)), for: .touchUpInside) + } + + override func enableAction(_ value: Bool) { + sendButton.backgroundColor = value ? ColorPalette.rossoCorsa : ColorPalette.middleRedPurple + sendButton.isUserInteractionEnabled = value + } + + @objc func sendButtonPressed(_ sender: UIButton) { + UIView.animate(withDuration: 0.2, animations: { + sender.backgroundColor = ColorPalette.middleRedPurple + sender.transform = CGAffineTransform(scaleX: 0.90, y: 0.83) + }) { completed in + self.sendAction?() + } + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.xib new file mode 100755 index 00000000..eb22ca5a --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.xib @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + DINPro-Medium + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.swift new file mode 100755 index 00000000..f32dd96d --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.swift @@ -0,0 +1,107 @@ +// +// TextFieldTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit +import JMMaskTextField_Swift + +final class TextFieldTableViewCell: ContactBaseTableViewCell { + + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet var textField: UITextField! + @IBOutlet weak var lineView: UIView! + + var isTextValid: Bool = false { + didSet { + lineView.backgroundColor = isTextValid ? ColorPalette.green : ColorPalette.red + if isTextValid { + callback?((titleLabel.text!, textField.text!)) + } + } + } + + override func awakeFromNib() { + super.awakeFromNib() + textField.delegate = self + textField.addTarget(self, action: #selector(resizeTitleLabel), for: .editingDidBegin) + textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged) + } + + @objc func resizeTitleLabel() { + titleLabel.font = UIFont(name: FontNames.regular, size: 11) + if textField.text!.isEmpty { + lineView.backgroundColor = ColorPalette.silverChalice + } + } + + @objc func textFieldDidChange(_ textField: UITextField) { + checkTextField(textField) + } + + override func setup(with item: Cell) { + super.setup(with: item) + if item.message == "Telefone" { + textField.textContentType = UITextContentType.telephoneNumber + textField.keyboardType = .numberPad + } else { + let type = TypeField(rawValue: item.typefield ?? 0) + textField.textContentType = type?.contentType ?? .name + textField.keyboardType = type?.keyboardType ?? .default + } + titleLabel.text = item.message + textField.text = .none + lineView.backgroundColor = ColorPalette.isabelline + titleLabel.font = UIFont(name: FontNames.regular, size: 16) + } + + private func checkTextField(_ textField: UITextField) { + guard let text = textField.text else { return } + switch textField.textContentType! { + case .name: + isTextValid = text.count >= 5 + case .telephoneNumber: + isTextValid = text.count >= 10 + default: + let newText = text.replacingOccurrences(of: " ", with: "") + textField.text = newText + isTextValid = newText.isValidEmail + } + } +} + +extension TextFieldTableViewCell: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } + + func textFieldShouldClear(_ textField: UITextField) -> Bool { + callback?((self.titleLabel.text!, "")) + return true + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + if textField.textContentType == .telephoneNumber { + guard let text = textField.text as NSString? else { return true } + let newText = text.replacingCharacters(in: range, with: string) + + let maskTextField = textField as! JMMaskTextField + maskTextField.maskString = "(00) 00000-0000" + guard let unmaskedText = maskTextField.stringMask?.unmask(string: newText) else { return true } + maskTextField.text = unmaskedText + if unmaskedText.count >= 11 { + maskTextField.maskString = "(00) 00000-0000" + _ = textFieldShouldReturn(textField) + } else { + maskTextField.maskString = "(00) 0000-0000" + } + + textFieldDidChange(maskTextField) + } + return true + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.xib new file mode 100755 index 00000000..e8fe5b8c --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.xib @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + DINPro-Medium + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.swift new file mode 100755 index 00000000..149c2430 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.swift @@ -0,0 +1,23 @@ +// +// TextTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +final class TextTableViewCell: ContactBaseTableViewCell { + + @IBOutlet weak var messageLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + } + + override func setup(with item: Cell) { + super.setup(with: item) + messageLabel.text = item.message + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.xib new file mode 100755 index 00000000..8018043d --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.swift new file mode 100755 index 00000000..cb10ceb9 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.swift @@ -0,0 +1,26 @@ +// +// DownInfoTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class DownInfoTableViewCell: FundBaseTableViewCell { + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var downloadButton: UIButton! + + var data: String? = .none + + override func setup(with fund: Fund) { + nameLabel.text = fund.downInfo[tag].name + data = fund.downInfo[tag].data + } + + @IBAction func downloadData(_ sender: UIButton){ + self.downloadAction?(data) + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.xib new file mode 100755 index 00000000..684f5655 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.xib @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/FundBaseTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/FundBaseTableViewCell.swift new file mode 100644 index 00000000..88abc918 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/FundBaseTableViewCell.swift @@ -0,0 +1,16 @@ +// +// FundBaseTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit +import Reusable + +class FundBaseTableViewCell: UITableViewCell, NibReusable { + func setup(with fund: Fund) {} + var investAction: (() -> ())? + var downloadAction: ((String?) -> ())? +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.swift new file mode 100755 index 00000000..86aebbc8 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.swift @@ -0,0 +1,29 @@ +// +// FundHeaderTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FundHeaderTableViewCell: FundBaseTableViewCell { + + @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 riskView: RiskView! + + override func setup(with fund: Fund) { + titleLabel.text = fund.title + fundNameLabel.text = fund.fundName + whatIsLabel.text = fund.whatIs + definitionLabel.text = fund.definition + riskTitleLabel.text = fund.riskTitle + riskView.setRist(risk: fund.risk) + } + +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.xib new file mode 100755 index 00000000..c2c3b85a --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.xib @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + DINPro-Light + + + DINPro-Medium + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.swift new file mode 100755 index 00000000..8e441a32 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.swift @@ -0,0 +1,20 @@ +// +// InfoTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 22/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class InfoTableViewCell: FundBaseTableViewCell { + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var dataLabel: UILabel! + + override func setup(with fund: Fund) { + nameLabel.text = fund.info[tag].name + dataLabel.text = fund.info[tag].data + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.xib new file mode 100755 index 00000000..cc347e94 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.swift new file mode 100644 index 00000000..0fb97bec --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.swift @@ -0,0 +1,33 @@ +// +// InvestTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class InvestTableViewCell: FundBaseTableViewCell { + + @IBOutlet weak var investButton: UIButton! + + override func awakeFromNib() { + super.awakeFromNib() + investButton.layer.cornerRadius = investButton.frame.height / 2 + investButton.setTitle("Investir", for: .normal) + } + + @IBAction func investButtonPressed(_ sender: UIButton) { + UIView.animate(withDuration: 0.2, animations: { + sender.backgroundColor = ColorPalette.middleRedPurple + sender.transform = CGAffineTransform(scaleX: 0.90, y: 0.83) + }) { completed in + UIView.animate(withDuration: 0.2, animations: { + self.investAction?() + sender.backgroundColor = ColorPalette.rossoCorsa + sender.transform = CGAffineTransform.identity + }) + } + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.xib new file mode 100644 index 00000000..13694482 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.xib @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + DINPro-Medium + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.swift b/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.swift new file mode 100644 index 00000000..22c04ec4 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.swift @@ -0,0 +1,29 @@ +// +// MoreInfoTableViewCell.swift +// TesteiOS +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class MoreInfoTableViewCell: FundBaseTableViewCell { + @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 twelveMonthsFundLabel: UILabel! + @IBOutlet weak var twelveMonthsCdiLabel: UILabel! + + override func setup(with fund: Fund) { + infoTitleLabel.text = fund.infoTitle + monthFundLabel.text = String(format: "%.1f %%", fund.moreInfo.month.fund) + monthCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.month.cdi) + yearFundLabel.text = String(format: "%.1f %%", fund.moreInfo.year.fund) + yearCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.year.cdi) + twelveMonthsFundLabel.text = String(format: "%.1f %%", fund.moreInfo.twelveMonths.fund) + twelveMonthsCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.twelveMonths.cdi) + } +} diff --git a/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.xib b/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.xib new file mode 100644 index 00000000..613ba8a0 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.xib @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + DINPro-Medium + + + DINPro-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Views/Contact/ContactTableView.swift b/TesteiOS/TesteiOS/UI/Views/Contact/ContactTableView.swift new file mode 100644 index 00000000..72235cf0 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Contact/ContactTableView.swift @@ -0,0 +1,39 @@ +// +// ContactTableView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class ContactTableView: UITableView { + + fileprivate var customDataSource: ContactDataSource? + fileprivate var customDelegate: ContactDelegate? + convenience init() { + self.init(frame: .zero, style: .plain) + } + + override init(frame: CGRect, style: UITableView.Style) { + super.init(frame: frame, style: style) + customDelegate = ContactDelegate(tableView: self) + customDataSource = ContactDataSource(tableView: self, delegate: customDelegate!) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension ContactTableView { + func update(with items: [Cell]) { + customDelegate?.update(with: items) + customDataSource?.update(with: items) + } + + func setSendHandler(_ handler: @escaping ([Value]) -> ()) { + customDataSource?.sendAction = handler + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/Contact/ContactView.swift b/TesteiOS/TesteiOS/UI/Views/Contact/ContactView.swift new file mode 100644 index 00000000..d2c285b0 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Contact/ContactView.swift @@ -0,0 +1,76 @@ +// +// ContactView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class ContactView: UIView { + lazy var activityIndicator: UIActivityIndicatorView = { + let view = UIActivityIndicatorView(style: .whiteLarge) + view.color = ColorPalette.black + return view + }() + + lazy var tableView: ContactTableView = { + let view = ContactTableView() + view.separatorStyle = .none + view.alwaysBounceVertical = false + return view + }() + + private lazy var feedbackView: FeedbackView = { + let view = FeedbackView.loadFromNib() + view.alpha = 0 + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupViewCode() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func showFeedbackView() { + UIView.animate(withDuration: 0.2) { + self.feedbackView.alpha = 1 + } + } +} + +extension ContactView: ViewCode { + func buildViewHierarchy() { + addSubview(tableView) + addSubview(feedbackView) + addSubview(activityIndicator) + } + + func setupConstraints() { + tableView.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + make.bottom.equalTo(-55) + } + + feedbackView.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + make.bottom.equalTo(-55) + } + + activityIndicator.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + make.bottom.equalTo(-55) + } + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.swift b/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.swift new file mode 100644 index 00000000..3a4fe94a --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.swift @@ -0,0 +1,22 @@ +// +// FeedbackView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FeedbackView: UIView { + class func loadFromNib() -> FeedbackView { + let nib = UINib(nibName: String(describing: self), bundle: .main) + return nib.instantiate(withOwner: nil, options: nil).first as! FeedbackView + } + + @IBAction func sendButtonPressed(_ sender: UIButton) { + UIView.animate(withDuration: 0.2) { + self.alpha = 0 + } + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.xib b/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.xib new file mode 100644 index 00000000..911418ef --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.xib @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + DINPro-Medium + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/TesteiOS/UI/Views/Funds/FundsTableView.swift b/TesteiOS/TesteiOS/UI/Views/Funds/FundsTableView.swift new file mode 100644 index 00000000..d6df12ff --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Funds/FundsTableView.swift @@ -0,0 +1,42 @@ +// +// FundsTableView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FundsTableView: UITableView { + + fileprivate var customDataSource: FundsDataSource? + fileprivate var customDelegate: FundsDelegate? + convenience init() { + self.init(frame: .zero, style: .plain) + } + + override init(frame: CGRect, style: UITableView.Style) { + super.init(frame: frame, style: style) + customDelegate = FundsDelegate(tableView: self) + customDataSource = FundsDataSource(tableView: self, delegate: customDelegate!) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension FundsTableView { + func update(with fund: Fund) { + customDataSource?.update(with: fund) + } + + func setInvestHandler(_ handler: @escaping () -> ()) { + customDataSource?.investAction = handler + } + + func setDownloadHandler(_ handler: @escaping (String?) -> ()) { + customDataSource?.downloadAction = handler + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/Funds/FundsView.swift b/TesteiOS/TesteiOS/UI/Views/Funds/FundsView.swift new file mode 100644 index 00000000..c70eb3a8 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Funds/FundsView.swift @@ -0,0 +1,56 @@ +// +// FundsView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 23/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class FundsView: UIView { + lazy var activityIndicator: UIActivityIndicatorView = { + let view = UIActivityIndicatorView(style: .whiteLarge) + view.color = ColorPalette.black + return view + }() + + lazy var tableView: FundsTableView = { + let view = FundsTableView() + view.separatorStyle = .none + view.alwaysBounceVertical = false + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupViewCode() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension FundsView: ViewCode { + func buildViewHierarchy() { + addSubview(tableView) + addSubview(activityIndicator) + } + + func setupConstraints() { + tableView.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + make.bottom.equalTo(-55) + } + + activityIndicator.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + make.bottom.equalTo(-55) + } + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/Funds/RiskView.swift b/TesteiOS/TesteiOS/UI/Views/Funds/RiskView.swift new file mode 100644 index 00000000..743cab09 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/Funds/RiskView.swift @@ -0,0 +1,92 @@ +// +// RiskView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class RiskView: UIView { + + @IBOutlet weak var fisrtBar: UIView! + @IBOutlet weak var lastBar: UIView! + + @IBOutlet weak var fisrtBarHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var secondBarHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var thirdBarHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var fourthHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var lastBarHeightConstraint: NSLayoutConstraint! + + @IBOutlet weak var vImageViewLeadingConstraint: NSLayoutConstraint! + + private let defaultHeightConstraintValue: CGFloat = 6.0 + private let selectedHeightConstraintValue: CGFloat = 10.0 + + private var defaultVImageViewLeadingConstraintValue: CGFloat! + + func setRist(risk: Int) { + resetHeightConstraints() + + switch risk { + case 1: + fisrtBarHeightConstraint.constant = selectedHeightConstraintValue + configureFirstBar(factor: selectedHeightConstraintValue) + configureLastBar(factor: defaultHeightConstraintValue) + case 2: + secondBarHeightConstraint.constant = selectedHeightConstraintValue + case 3: + thirdBarHeightConstraint.constant = selectedHeightConstraintValue + case 4: + fourthHeightConstraint.constant = selectedHeightConstraintValue + case 5: + lastBarHeightConstraint.constant = selectedHeightConstraintValue + configureFirstBar(factor: defaultHeightConstraintValue) + configureLastBar(factor: selectedHeightConstraintValue) + default: + break + } + + configureVImageView(risk: risk) + + self.layoutIfNeeded() + } + + private func configureVImageView(risk: Int) { + let factor = (UIScreen.main.bounds.width - 70) / 5 + let value = defaultVImageViewLeadingConstraintValue + (CGFloat(risk - 1) * factor) + vImageViewLeadingConstraint.constant = value + } + + private func resetHeightConstraints() { + fisrtBarHeightConstraint.constant = defaultHeightConstraintValue + secondBarHeightConstraint.constant = defaultHeightConstraintValue + thirdBarHeightConstraint.constant = defaultHeightConstraintValue + fourthHeightConstraint.constant = defaultHeightConstraintValue + lastBarHeightConstraint.constant = defaultHeightConstraintValue + } + + private func configureFirstBar(factor: CGFloat) { + fisrtBar.layer.cornerRadius = factor / 2 + } + + private func configureLastBar(factor: CGFloat) { + lastBar.layer.cornerRadius = factor / 2 + } + + private func configure() { + fisrtBar.layer.cornerRadius = fisrtBar.frame.height / 2 + fisrtBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner] + + lastBar.layer.cornerRadius = lastBar.frame.height / 2 + lastBar.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner] + vImageViewLeadingConstraint.constant = ((UIScreen.main.bounds.width - 70) / 5) / 2 + defaultVImageViewLeadingConstraintValue = vImageViewLeadingConstraint.constant + } + + override func awakeFromNib() { + super.awakeFromNib() + configure() + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/TabBarButton.swift b/TesteiOS/TesteiOS/UI/Views/TabBarButton.swift new file mode 100644 index 00000000..78448b8b --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/TabBarButton.swift @@ -0,0 +1,32 @@ +// +// TabBarButton.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class TabBarButton: UIButton { + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup() { + contentMode = .scaleAspectFit + clipsToBounds = true + adjustsImageWhenHighlighted = false + adjustsImageWhenDisabled = false + setBackgroundImage(UIImage(named: "tabBarItemNormal"), for: .normal) + setBackgroundImage(UIImage(named: "tabBarItemSelected"), for: .selected) + tintColor = ColorPalette.white + titleLabel?.font = UIFont(name: FontNames.medium, size: 16) + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/TabBarView.swift b/TesteiOS/TesteiOS/UI/Views/TabBarView.swift new file mode 100644 index 00000000..0772c099 --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/TabBarView.swift @@ -0,0 +1,59 @@ +// +// TabBarView.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import UIKit + +class TabBarView: UIView { + + lazy var button1: TabBarButton = { + let button = TabBarButton(frame: .zero) + button.tag = 0 + button.setTitle("Investimento", for: .normal) + return button + }() + + lazy var button2: TabBarButton = { + let button = TabBarButton(frame: .zero) + button.tag = 1 + button.setTitle("Contato", for: .normal) + return button + }() + + lazy var containerView: UIStackView = { + let view = UIStackView(frame: .zero) + view.axis = .horizontal + view.distribution = .fillEqually + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupViewCode() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension TabBarView: ViewCode { + func buildViewHierarchy() { + addSubview(containerView) + } + + func setupConstraints() { + containerView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } + + func configureViews() { + containerView.addArrangedSubview(button1) + containerView.addArrangedSubview(button2) + } +} diff --git a/TesteiOS/TesteiOS/UI/Views/ViewCode.swift b/TesteiOS/TesteiOS/UI/Views/ViewCode.swift new file mode 100644 index 00000000..002f4b6d --- /dev/null +++ b/TesteiOS/TesteiOS/UI/Views/ViewCode.swift @@ -0,0 +1,26 @@ +// +// ViewCode.swift +// TesteiOS +// +// Created by Brendoon Ryos on 21/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Foundation + +protocol ViewCode: class { + func setupConstraints() + func buildViewHierarchy() + func setupViewCode() + func configureViews() +} + +extension ViewCode { + func setupViewCode() { + buildViewHierarchy() + setupConstraints() + configureViews() + } + + func configureViews() {} +} diff --git a/TesteiOS/TesteiOSTests/DataSources/ContactDataSourceSpec.swift b/TesteiOS/TesteiOSTests/DataSources/ContactDataSourceSpec.swift new file mode 100644 index 00000000..e4787311 --- /dev/null +++ b/TesteiOS/TesteiOSTests/DataSources/ContactDataSourceSpec.swift @@ -0,0 +1,77 @@ +// +// ContactDataSourceSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble + +@testable import TesteiOS + +class TableViewDelegateMock: NSObject, UITableViewDelegate { + +} + +class ContactDataSourceSpec: QuickSpec { + override func spec() { + describe("a ContactDataSource") { + var dataSource: ContactDataSource! + var cells: [Cell]! + var tableView: UITableView! + + beforeEach { + let sampleData = BankAPI.fetchForm.sampleData + let formData = try? JSONDecoder().decode(FormData.self, from: sampleData) + cells = formData?.cells + + tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 300, height: 500)) + dataSource = ContactDataSource(tableView: tableView, delegate: TableViewDelegateMock()) + dataSource.update(with: cells) + } + it("should have a valid dataSource") { + expect(dataSource).toNot(beNil()) + } + it("should have the expected number of items") { + let count = dataSource.tableView(tableView, numberOfRowsInSection: 0) + expect(count).to(equal(5)) + } + it("should show only the not hidden cells") { + let items = [cells[2], cells[0]] + dataSource.update(with: items) + let count = dataSource.tableView(tableView, numberOfRowsInSection: 0) + expect(cells[2].hidden).to(beTrue()) + expect(count).to(equal(1)) + } + it("should have be able to update items") { + let items = [cells[0], cells[0]] + dataSource.update(with: items) + let count = dataSource.tableView(tableView, numberOfRowsInSection: 0) + expect(count).to(equal(2)) + } + it("should return the expected cell") { + let cell = dataSource.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 0)) + expect(cell).to(beAKindOf(ContactBaseTableViewCell.self)) + } + it("should have be able to update values") { + dataSource.sendButtonPressed() + expect(dataSource.values).to(be([])) + } + it("should have the expected number of values") { + dataSource.validValue(("Email", "test@test.com")) + expect(dataSource.values.count).to(equal(1)) + } + it("should have upadeted the value data") { + dataSource.validValue(("Email", "test2@test.com")) + let data = dataSource.values[0].data as! String + expect(data).to(equal("test2@test.com")) + } + it("should remove the value") { + dataSource.validValue(("Email", "")) + expect(dataSource.values[0]).toNot(be(("Email", ""))) + } + } + } +} diff --git a/TesteiOS/TesteiOSTests/Extensions/StringValidatorSpec.swift b/TesteiOS/TesteiOSTests/Extensions/StringValidatorSpec.swift new file mode 100644 index 00000000..bce659f4 --- /dev/null +++ b/TesteiOS/TesteiOSTests/Extensions/StringValidatorSpec.swift @@ -0,0 +1,53 @@ +// +// StringValidatorSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 25/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble + +@testable import TesteiOS + +class StringValidatorSpec: QuickSpec { + override func spec() { + describe("the String Validator") { + it("should be able to check if it's an valid email") { + var email = "abc@test.com" + expect(email.isValidEmail).to(beTrue()) + email = "acv" + expect(email.isValidEmail).toNot(beTrue()) + email = "acc.com" + expect(email.isValidEmail).toNot(beTrue()) + email = "acc@" + expect(email.isValidEmail).toNot(beTrue()) + email = ".@" + expect(email.isValidEmail).toNot(beTrue()) + } + it("should be able to check if it's an valid CPF") { + var cpf = "06668090389" + expect(cpf.isValidCPF).to(beTrue()) + cpf = "06668090387" + expect(cpf.isValidCPF).toNot(beTrue()) + cpf = "0666809" + expect(cpf.isValidCPF).toNot(beTrue()) + cpf = "0666809ab" + expect(cpf.isValidCPF).toNot(beTrue()) + } + it("should be able to check if it's an valid password") { + var password = "Abc@10" + expect(password.isValidPassword()).to(beTrue()) + password = "abc" + expect(password.isValidPassword()).toNot(beTrue()) + password = "Abc" + expect(password.isValidPassword()).toNot(beTrue()) + password = "Abc@" + expect(password.isValidPassword()).toNot(beTrue()) + password = "0666809ab" + expect(password.isValidPassword()).toNot(beTrue()) + } + } + } +} diff --git a/TesteiOS/TesteiOSTests/Info.plist b/TesteiOS/TesteiOSTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/TesteiOS/TesteiOSTests/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/TesteiOS/TesteiOSTests/Models/FormDataSpec.swift b/TesteiOS/TesteiOSTests/Models/FormDataSpec.swift new file mode 100644 index 00000000..b16ff874 --- /dev/null +++ b/TesteiOS/TesteiOSTests/Models/FormDataSpec.swift @@ -0,0 +1,31 @@ +// +// FormDataSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 24/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble + +@testable import TesteiOS + +class FormDataSpec: QuickSpec { + override func spec() { + describe("a FormData") { + var formData: FormData! + + beforeEach { + let sampleData = BankAPI.fetchForm.sampleData + formData = try? JSONDecoder().decode(FormData.self, from: sampleData) + } + + it("should be able to create a formData from json") { + expect(formData).notTo(beNil()) + } + } + } +} + + diff --git a/TesteiOS/TesteiOSTests/Scenes/Contact/ContactInteractSpec.swift b/TesteiOS/TesteiOSTests/Scenes/Contact/ContactInteractSpec.swift new file mode 100644 index 00000000..d145990b --- /dev/null +++ b/TesteiOS/TesteiOSTests/Scenes/Contact/ContactInteractSpec.swift @@ -0,0 +1,32 @@ +// +// ContactInteractSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 25/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble + +@testable import TesteiOS + +class ContactInteractorSpec: QuickSpec { + override func spec() { + describe("a ContactInteractor") { + var interact: ContactInteractor! + + beforeEach { + let request = Contact.Form.Request() + let worker = ContactWorker(networkManager: NetworkManagerMock()) + interact = ContactInteractor(worker: worker) + interact.fetchForm(request: request) + interact.sendFormData(request: Contact.Send.Request(values: [])) + } + + it("should have a worker") { + expect(interact.worker).notTo(beNil()) + } + } + } +} diff --git a/TesteiOS/TesteiOSTests/Scenes/Contact/ContactWorkerSpec.swift b/TesteiOS/TesteiOSTests/Scenes/Contact/ContactWorkerSpec.swift new file mode 100644 index 00000000..af457ccf --- /dev/null +++ b/TesteiOS/TesteiOSTests/Scenes/Contact/ContactWorkerSpec.swift @@ -0,0 +1,63 @@ +// +// ContactWorkerSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 25/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble +import Moya +import Alamofire + +@testable import TesteiOS + +class NetworkManagerMock: Networkable { + var provider: MoyaProvider = MoyaProvider() + + func fetchForm(request: Contact.Form.Request, completion: @escaping (Result) -> ()) { + let sampleData = BankAPI.fetchForm.sampleData + let formData = try? JSONDecoder().decode(FormData.self, from: sampleData) + if let form = formData { + completion(Result.success(form)) + } else { + completion(Result.failure(NSError())) + } + } + + func fetchFund(request: Funds.Get.Request, completion: @escaping (Result) -> ()) { + let sampleData = BankAPI.fetchFund.sampleData + let fundsData = try? JSONDecoder().decode(FundsData.self, from: sampleData) + + if let funds = fundsData { + completion(Result.success(funds)) + } else { + completion(Result.failure(NSError())) + } + + } +} + +class ContactWorkerSpec: QuickSpec { + override func spec() { + describe("a ContactWorker") { + var worker: ContactWorker! + + beforeEach { + worker = ContactWorker(networkManager: NetworkManagerMock()) + } + + it("should have a result value") { + worker.fetchForm(request: Contact.Form.Request(), completion: { result in + expect(result.value).notTo(beNil()) + }) + } + it("should haven't a error ") { + worker.fetchForm(request: Contact.Form.Request(), completion: { result in + expect(result.error).to(beNil()) + }) + } + } + } +} diff --git a/TesteiOS/TesteiOSTests/Scenes/Funds/FundsInteractorSpec.swift b/TesteiOS/TesteiOSTests/Scenes/Funds/FundsInteractorSpec.swift new file mode 100644 index 00000000..f36b22fe --- /dev/null +++ b/TesteiOS/TesteiOSTests/Scenes/Funds/FundsInteractorSpec.swift @@ -0,0 +1,34 @@ +// +// FundsInteractorSpec.swift +// TesteiOSTests +// +// Created by Brendoon Ryos on 25/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import Quick +import Nimble + +@testable import TesteiOS + +class FundsInteractorSpec: QuickSpec { + override func spec() { + describe("a ContactInteractor") { + var interact: FundsInteractor! + + beforeEach { + let request = Funds.Download.Request(url: .none) + let worker = FundsWorker(networkManager: NetworkManagerMock()) + interact = FundsInteractor(worker: worker) + interact.downloadData(request: request) + } + + it("should have a worker") { + expect(interact.worker).notTo(beNil()) + } + it("should have an url") { + expect(interact.url).to(equal("https://www.google.com/")) + } + } + } +} diff --git a/TesteiOS/TesteiOSUITests/Info.plist b/TesteiOS/TesteiOSUITests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/TesteiOS/TesteiOSUITests/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/TesteiOS/TesteiOSUITests/TesteiOSUITests.swift b/TesteiOS/TesteiOSUITests/TesteiOSUITests.swift new file mode 100644 index 00000000..b32a69b9 --- /dev/null +++ b/TesteiOS/TesteiOSUITests/TesteiOSUITests.swift @@ -0,0 +1,34 @@ +// +// TesteiOSUITests.swift +// TesteiOSUITests +// +// Created by Brendoon Ryos on 19/02/19. +// Copyright © 2019 Brendoon Ryos. All rights reserved. +// + +import XCTest + +class TesteiOSUITests: 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. + } + +} diff --git a/TesteiOS/coverage/AppDelegate.swift.html b/TesteiOS/coverage/AppDelegate.swift.html new file mode 100644 index 00000000..0f7d2935 --- /dev/null +++ b/TesteiOS/coverage/AppDelegate.swift.html @@ -0,0 +1,222 @@ + + + +AppDelegate.swift - Slather + + + +
Slather logo
+

+Coverage for "AppDelegate.swift" : 100.00% +

+

(21 of 21 relevant lines covered)

+

TesteiOS/Supporting Files/AppDelegate.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  AppDelegate.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 19/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
@UIApplicationMain
12
class AppDelegate: UIResponder, UIApplicationDelegate {
13
14
  var window: UIWindow?
15
16
17
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2x
18
    
2x
19
    self.window = UIWindow(frame: UIScreen.main.bounds)
2x
20
    self.window?.backgroundColor = UIColor.white
2x
21
    
2x
22
    let tabBarController = TabBarViewController()
2x
23
    let fundsVC = FundsViewController()
2x
24
    let contactVC = ContactViewController()
2x
25
    
2x
26
    let fundsNavigationController = UINavigationController(rootViewController: fundsVC)
2x
27
    let contactNavigationController = UINavigationController(rootViewController: contactVC)
2x
28
    
2x
29
    tabBarController.viewControllers = [fundsNavigationController, contactNavigationController]
2x
30
    
2x
31
    self.window?.rootViewController = tabBarController
2x
32
    self.window?.makeKeyAndVisible()
2x
33
    
2x
34
    AppearanceProxyHelper.customizeNavigationBar()
2x
35
    
2x
36
    return true
2x
37
  }
2x
38
39
}
40
+
+ + + diff --git a/TesteiOS/coverage/AppearanceProxyHelper.swift.html b/TesteiOS/coverage/AppearanceProxyHelper.swift.html new file mode 100644 index 00000000..124f3746 --- /dev/null +++ b/TesteiOS/coverage/AppearanceProxyHelper.swift.html @@ -0,0 +1,142 @@ + + + +AppearanceProxyHelper.swift - Slather + + + +
Slather logo
+

+Coverage for "AppearanceProxyHelper.swift" : 90.00% +

+

(9 of 10 relevant lines covered)

+

TesteiOS/UI/Appearance/AppearanceProxyHelper.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  AppearanceProxyHelper.swift
3
//  Movs
4
//
5
//  Created by Brendoon Ryos on 24/01/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
struct AppearanceProxyHelper {
12
  
13
  private init() {}
!
14
  
15
  static func customizeNavigationBar(){
2x
16
    let navBarAppearance = UINavigationBar.appearance()
2x
17
    navBarAppearance.isTranslucent = false
2x
18
    navBarAppearance.shadowImage = UIImage()
2x
19
    navBarAppearance.setBackgroundImage(UIImage(), for: .default)
2x
20
    navBarAppearance.barTintColor = ColorPalette.white
2x
21
    navBarAppearance.tintColor = ColorPalette.rossoCorsa
2x
22
    navBarAppearance.titleTextAttributes = [NSAttributedString.Key.font: UIFont(name: FontNames.medium, size: 16)!, NSAttributedString.Key.foregroundColor: ColorPalette.jet]
2x
23
  }  
2x
24
}
+
+ + + diff --git a/TesteiOS/coverage/BankAPI+Testing.swift.html b/TesteiOS/coverage/BankAPI+Testing.swift.html new file mode 100644 index 00000000..ed1d52cc --- /dev/null +++ b/TesteiOS/coverage/BankAPI+Testing.swift.html @@ -0,0 +1,147 @@ + + + +BankAPI+Testing.swift - Slather + + + +
Slather logo
+

+Coverage for "BankAPI+Testing.swift" : 87.50% +

+

(7 of 8 relevant lines covered)

+

TesteiOS/Services/BankAPI+Testing.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  BankAPI+Testing.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
extension BankAPI {
12
  var sampleData: Data {
13x
13
    switch self {
13x
14
    case .fetchForm:
13x
15
      return stubbedResponse("Form")
13x
16
    case .fetchFund:
13x
17
      return stubbedResponse("Fund")
!
18
    }
13x
19
  }
13x
20
  
21
  func stubbedResponse(_ filename: String, bundle: Bundle = .main) -> Data! {
22
    let path = bundle.path(forResource: filename, ofType: "json")
23
    return (try? Data(contentsOf: URL(fileURLWithPath: path!)))
24
  }
25
}
+
+ + + diff --git a/TesteiOS/coverage/BankAPI.swift.html b/TesteiOS/coverage/BankAPI.swift.html new file mode 100644 index 00000000..2b414836 --- /dev/null +++ b/TesteiOS/coverage/BankAPI.swift.html @@ -0,0 +1,337 @@ + + + +BankAPI.swift - Slather + + + +
Slather logo
+

+Coverage for "BankAPI.swift" : 92.50% +

+

(37 of 40 relevant lines covered)

+

TesteiOS/Services/BankAPI.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  BankAPI.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
import Moya
11
12
enum BankAPI {
13
  case fetchForm
14
  case fetchFund
15
}
16
17
extension BankAPI: TargetType {
18
  var environmentBaseURL: String {
2x
19
    switch NetworkManager.environment {
2x
20
    case .staging:
2x
21
      return "https://floating-mountain-50292.herokuapp.com"
2x
22
    case .qa:
2x
23
      return ""
!
24
    case .production:
2x
25
      return ""
!
26
    }
2x
27
  }
2x
28
  
29
  var baseURL: URL {
2x
30
    guard let url = URL(string: environmentBaseURL) else { fatalError("baseURL could not be configured.") }
2x
31
    return url
2x
32
  }
2x
33
  
34
  var path: String {
4x
35
    switch self {
4x
36
    case .fetchForm:
4x
37
      return "/cells.json"
!
38
    case .fetchFund:
4x
39
      return "/fund.json"
4x
40
    }
4x
41
  }
4x
42
  
43
  var method: Moya.Method {
2x
44
    switch self {
2x
45
    default:
2x
46
      return .get
2x
47
    }
2x
48
  }
2x
49
  
50
  var task: Task {
2x
51
    switch self {
2x
52
    default:
2x
53
      return .requestPlain
2x
54
    }
2x
55
  }
2x
56
  
57
  var headers: [String : String]? {
2x
58
    switch self {
2x
59
    default:
2x
60
      return ["Content-type":"application/json"]
2x
61
    }
2x
62
  }
2x
63
}
+
+ + + diff --git a/TesteiOS/coverage/Cell.swift.html b/TesteiOS/coverage/Cell.swift.html new file mode 100644 index 00000000..694b83a3 --- /dev/null +++ b/TesteiOS/coverage/Cell.swift.html @@ -0,0 +1,872 @@ + + + +Cell.swift - Slather + + + +
Slather logo
+

+Coverage for "Cell.swift" : 60.91% +

+

(67 of 110 relevant lines covered)

+

TesteiOS/Models/Cell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  Cell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
import Reusable
11
12
enum CellType: Int {
13
  case field = 1
14
  case text
15
  case image
16
  case checkbox
17
  case send
18
  case fundHeader
19
  case moreInfo
20
  case info
21
  case downInfo
22
  case invest
23
  
24
  func getNib() -> UINib {
53x
25
    switch self {
53x
26
    case .field:
53x
27
      return TextFieldTableViewCell.nib
18x
28
    case .text:
53x
29
      return TextTableViewCell.nib
12x
30
    case .checkbox:
53x
31
      return CheckboxTableViewCell.nib
9x
32
    case .send:
53x
33
      return SendTableViewCell.nib
9x
34
    case .fundHeader:
53x
35
      return FundHeaderTableViewCell.nib
1x
36
    case .moreInfo:
53x
37
      return MoreInfoTableViewCell.nib
1x
38
    case .info:
53x
39
      return InfoTableViewCell.nib
1x
40
    case .downInfo:
53x
41
      return DownInfoTableViewCell.nib
1x
42
    default:
53x
43
      return InvestTableViewCell.nib
1x
44
    }
53x
45
  }
53x
46
  
47
  func getIdentifier() -> String {
65x
48
    switch self {
65x
49
    case .field:
65x
50
      return TextFieldTableViewCell.reuseIdentifier
18x
51
    case .text:
65x
52
      return TextTableViewCell.reuseIdentifier
13x
53
    case .checkbox:
65x
54
      return CheckboxTableViewCell.reuseIdentifier
9x
55
    case .send:
65x
56
      return SendTableViewCell.reuseIdentifier
9x
57
    case .fundHeader:
65x
58
      return FundHeaderTableViewCell.reuseIdentifier
2x
59
    case .moreInfo:
65x
60
      return MoreInfoTableViewCell.reuseIdentifier
2x
61
    case .info:
65x
62
      return InfoTableViewCell.reuseIdentifier
8x
63
    case .downInfo:
65x
64
      return DownInfoTableViewCell.reuseIdentifier
3x
65
    default:
65x
66
      return InvestTableViewCell.reuseIdentifier
1x
67
    }
65x
68
  }
65x
69
  
70
  func getClass() -> UITableViewCell.Type {
!
71
    switch self {
!
72
    case .field:
!
73
      return TextFieldTableViewCell.self
!
74
    case .text:
!
75
      return TextTableViewCell.self
!
76
    case .checkbox:
!
77
      return CheckboxTableViewCell.self
!
78
    case .send:
!
79
      return SendTableViewCell.self
!
80
    case .fundHeader:
!
81
      return FundHeaderTableViewCell.self
!
82
    case .moreInfo:
!
83
      return MoreInfoTableViewCell.self
!
84
    case .info:
!
85
      return InfoTableViewCell.self
!
86
    case .downInfo:
!
87
      return DownInfoTableViewCell.self
!
88
    default:
!
89
      return InvestTableViewCell.self
!
90
    }
!
91
  }
!
92
  
93
  func getHeight() -> CGFloat {
33x
94
    switch self {
33x
95
    case .fundHeader:
33x
96
      return 410
3x
97
    case .moreInfo:
33x
98
      return 200
3x
99
    case .info, .downInfo:
33x
100
      return 30
27x
101
    default:
33x
102
      return 80
!
103
    }
33x
104
  }
33x
105
}
106
107
enum TypeField: Int {
108
  case text = 1
109
  case telNumber
110
  case email
111
  
112
  var contentType: UITextContentType {
!
113
    switch self {
!
114
    case .telNumber:
!
115
      return .telephoneNumber
!
116
    case .email:
!
117
      return .emailAddress
!
118
    default:
!
119
      return .name
!
120
    }
!
121
  }
!
122
  
123
  var keyboardType: UIKeyboardType {
!
124
    switch self {
!
125
    case .telNumber:
!
126
      return .phonePad
!
127
    case .email:
!
128
      return .emailAddress
!
129
    default:
!
130
      return .default
!
131
    }
!
132
  }
!
133
}
134
135
struct Cell {
136
  let id: Int
137
  let type: Int
138
  let message: String
139
  let typefield: Int?
140
  let hidden: Bool
141
  let topSpacing: Int
142
  let show: Int?
143
  let required: Bool
144
}
145
146
extension Cell: Decodable {
147
  private enum CodingKeys: String, CodingKey {
148
    case id
149
    case type
150
    case message
151
    case typefield
152
    case hidden
153
    case topSpacing
154
    case show
155
    case required
156
  }
157
  
158
  init(from decoder: Decoder) throws {
78x
159
    let container = try decoder.container(keyedBy: CodingKeys.self)
78x
160
    
78x
161
    id = try container.decode(Int.self, forKey: .id)
78x
162
    type = try container.decode(Int.self, forKey: .type)
78x
163
    message = try container.decode(String.self, forKey: .message)
78x
164
    typefield = try? container.decode(Int.self, forKey: .typefield)
78x
165
    hidden = try container.decode(Bool.self, forKey: .hidden)
78x
166
    topSpacing = try container.decode(Int.self, forKey: .topSpacing)
78x
167
    show = try? container.decode(Int.self, forKey: .show)
78x
168
    required = try container.decode(Bool.self, forKey: .required)
78x
169
  }
78x
170
}
+
+ + + diff --git a/TesteiOS/coverage/CheckboxTableViewCell.swift.html b/TesteiOS/coverage/CheckboxTableViewCell.swift.html new file mode 100644 index 00000000..ad991388 --- /dev/null +++ b/TesteiOS/coverage/CheckboxTableViewCell.swift.html @@ -0,0 +1,217 @@ + + + +CheckboxTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "CheckboxTableViewCell.swift" : 0.00% +

+

(0 of 22 relevant lines covered)

+

TesteiOS/UI/Cells/Contact/CheckboxTableViewCell/CheckboxTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  CheckboxTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
final class CheckboxTableViewCell: ContactBaseTableViewCell {
12
13
  @IBOutlet weak var checkboxButton: UIButton!
14
  
15
  override func awakeFromNib() {
!
16
    super.awakeFromNib()
!
17
    checkboxButton.titleLabel?.adjustsFontSizeToFitWidth = true
!
18
    checkboxButton.titleLabel?.minimumScaleFactor = 0.5
!
19
  }
!
20
  
21
  override func setup(with item: Cell) {
!
22
    super.setup(with: item)
!
23
    checkboxButton.isSelected = false
!
24
    checkboxButton.setImage(UIImage(named: "checkboxEmpty"), for: .normal)
!
25
    checkboxButton.setTitle(item.message, for: .normal)
!
26
    callback?((item.message, false))
!
27
  }
!
28
    
29
  @IBAction func checkboxButtonPressed(_ sender: UIButton) {
!
30
    if sender.isSelected {
!
31
      sender.isSelected = false
!
32
      sender.setImage(UIImage(named: "checkboxEmpty"), for: .normal)
!
33
    } else {
!
34
      sender.isSelected = true
!
35
      sender.setImage(UIImage(named: "checkboxFilled"), for: .normal)
!
36
    }
!
37
    callback?((sender.title(for: .normal)!, sender.isSelected))
!
38
  }
!
39
}
+
+ + + diff --git a/TesteiOS/coverage/ContactBaseTableViewCell.swift.html b/TesteiOS/coverage/ContactBaseTableViewCell.swift.html new file mode 100644 index 00000000..7b7092a3 --- /dev/null +++ b/TesteiOS/coverage/ContactBaseTableViewCell.swift.html @@ -0,0 +1,167 @@ + + + +ContactBaseTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactBaseTableViewCell.swift" : 87.50% +

+

(7 of 8 relevant lines covered)

+

TesteiOS/UI/Cells/Contact/ContactBaseTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactBaseTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
import Reusable
11
12
class ContactBaseTableViewCell: UITableViewCell, NibReusable {
13
  
14
  @IBOutlet weak var topSpacingConstraint: NSLayoutConstraint!
15
  
16
  var callback: ((Value) -> ())?
17
  var sendAction: (() -> ())?
18
  
19
  override func awakeFromNib() {
1x
20
    super.awakeFromNib()
1x
21
  }
1x
22
  
23
  func setup(with item: Cell) {
1x
24
    topSpacingConstraint.constant = CGFloat(item.topSpacing)
1x
25
    self.layoutIfNeeded()
1x
26
  }
1x
27
  
28
  func enableAction(_ value: Bool) {}
!
29
}
+
+ + + diff --git a/TesteiOS/coverage/ContactDataSource.swift.html b/TesteiOS/coverage/ContactDataSource.swift.html new file mode 100644 index 00000000..65bacaba --- /dev/null +++ b/TesteiOS/coverage/ContactDataSource.swift.html @@ -0,0 +1,427 @@ + + + +ContactDataSource.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactDataSource.swift" : 80.39% +

+

(41 of 51 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactDataSource.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactDataSource.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
typealias Value = (message: String, data: Any)
12
13
class ContactDataSource: NSObject, ItemsTableViewDataSource {
14
  
15
  var items: [Cell] = []
16
  var tableView: UITableView?
17
  var delegate: UITableViewDelegate?
18
  var values: [Value] = []
19
  var enableSendButton: ((Bool) -> ())?
20
  var sendAction: (([Value]) -> ())?
21
  
22
  required init(tableView: UITableView, delegate: UITableViewDelegate) {
11x
23
    self.tableView = tableView
11x
24
    self.delegate = delegate
11x
25
    super.init()
11x
26
    setupTableView()
11x
27
  }
11x
28
  
29
  func registerTableView() {
22x
30
    for item in items {
48x
31
      let type = CellType(rawValue: item.type)!
48x
32
      self.tableView?.register(type.getNib(), forCellReuseIdentifier: type.getIdentifier())
48x
33
    }
48x
34
  }
22x
35
  
36
  func update(with items: [Cell]) {
11x
37
    self.items = items.filter { !$0.hidden }
58x
38
    self.registerTableView()
11x
39
    self.tableView?.reloadData()
11x
40
  }
11x
41
  
42
  func sendButtonPressed() {
1x
43
    sendAction?(values)
1x
44
    values = []
1x
45
  }
1x
46
  
47
  func validValue(_ value: Value) {
3x
48
    if values.contains(where: { $0.message == value.message }) {
3x
49
      for i in 0..<values.count {
!
50
        guard values.count > i else { return }
!
51
        if values[i].message == value.message {
!
52
          values[i].data = value.data
!
53
          if let data = value.data as? String, data.isEmpty {
!
54
            values.remove(at: i)
!
55
            enableSendButton?(false)
!
56
          }
!
57
        }
!
58
      }
!
59
    } else {
3x
60
      values.append(value)
3x
61
    }
3x
62
    enableSendButton?(values.count == items.count - 2)
3x
63
  }
3x
64
}
65
66
extension ContactDataSource: UITableViewDataSource {
67
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
25x
68
    return items.count
25x
69
  }
25x
70
  
71
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
1x
72
    let item = items[indexPath.row]
1x
73
    let type = CellType(rawValue: item.type)!
1x
74
    let cell = tableView.dequeueReusableCell(withIdentifier: type.getIdentifier(), for: indexPath) as! ContactBaseTableViewCell
1x
75
    enableSendButton = cell.enableAction
1x
76
    cell.sendAction = sendButtonPressed
1x
77
    cell.callback = validValue
1x
78
    cell.setup(with: item)
1x
79
    return cell
1x
80
  }
1x
81
}
+
+ + + diff --git a/TesteiOS/coverage/ContactDelegate.swift.html b/TesteiOS/coverage/ContactDelegate.swift.html new file mode 100644 index 00000000..9c3e1d46 --- /dev/null +++ b/TesteiOS/coverage/ContactDelegate.swift.html @@ -0,0 +1,177 @@ + + + +ContactDelegate.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactDelegate.swift" : 41.67% +

+

(5 of 12 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactDelegate.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactDelegate.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class ContactDelegate: NSObject, UITableViewDelegate {
12
  
13
  weak var tableView: ContactTableView?
14
  
15
  var items: [Cell] = []
16
  
17
  init(tableView: ContactTableView) {
2x
18
    self.tableView = tableView
2x
19
    super.init()
2x
20
    self.tableView?.delegate = self
2x
21
  }
2x
22
  
23
  func update(with items: [Cell]) {
!
24
    self.items = items.filter { !$0.hidden }
!
25
  }
!
26
  
27
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
!
28
    let spacing = items[indexPath.row].topSpacing
!
29
    return CGFloat(50 + spacing)
!
30
  }
!
31
}
+
+ + + diff --git a/TesteiOS/coverage/ContactInteractor.swift.html b/TesteiOS/coverage/ContactInteractor.swift.html new file mode 100644 index 00000000..4180829c --- /dev/null +++ b/TesteiOS/coverage/ContactInteractor.swift.html @@ -0,0 +1,287 @@ + + + +ContactInteractor.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactInteractor.swift" : 90.00% +

+

(18 of 20 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactInteractor.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactInteractor.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol ContactBusinessLogic {
16
  func fetchForm(request: Contact.Form.Request)
17
  func sendFormData(request: Contact.Send.Request)
18
}
19
20
protocol ContactDataStore {
21
  //var name: String { get set }
22
}
23
24
class ContactInteractor: ContactBusinessLogic, ContactDataStore {
25
  var presenter: ContactPresentationLogic?
26
  var worker: ContactWorker?
27
  //var name: String = ""
28
  
29
  init(worker: ContactWorker? = ContactWorker()) {
3x
30
    self.worker = worker
3x
31
  }
3x
32
  
33
  // MARK: Fetch Form
34
  func fetchForm(request: Contact.Form.Request) {
1x
35
    worker?.fetchForm(request: request, completion: { result in
1x
36
      switch result {
1x
37
      case .success(let data):
1x
38
        let response = Contact.Form.Response(cells: data.cells)
1x
39
        self.presenter?.presentForm(response: response)
1x
40
      case .failure(let error):
1x
41
        let response = Contact.Form.Response(error: error)
!
42
        self.presenter?.presentErrorMessage(response: response)
!
43
      }
1x
44
    })
1x
45
  }
1x
46
  
47
  // MARK: Send form data
48
  func sendFormData(request: Contact.Send.Request) {
1x
49
    let response = Contact.Send.Response()
1x
50
    presenter?.presentSuccesseMessage(response: response)
1x
51
    // TODO: Send form data
1x
52
  }
1x
53
}
+
+ + + diff --git a/TesteiOS/coverage/ContactModels.swift.html b/TesteiOS/coverage/ContactModels.swift.html new file mode 100644 index 00000000..7fc04ac0 --- /dev/null +++ b/TesteiOS/coverage/ContactModels.swift.html @@ -0,0 +1,262 @@ + + + +ContactModels.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactModels.swift" : 50.00% +

+

(4 of 8 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactModels.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactModels.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
enum Contact {
16
  // MARK: Use cases
17
  enum Send {
18
    struct Request{
19
      let values: [Value]
20
    }
21
    struct Response {}
22
    struct ViewModel {}
23
  }
24
  
25
  enum Form {
26
    struct Request{}
27
    
28
    struct Response {
29
      let cells: [Cell]
30
      let error: Error?
31
      
32
      init(cells: [Cell] = [], error: Error? = .none) {
1x
33
        self.cells = cells
1x
34
        self.error = error
1x
35
      }
1x
36
    }
37
    struct ViewModel {
38
      let cells: [Cell]
39
      let error: Error?
40
      
41
      init(cells: [Cell] = [], error: Error? = .none) {
!
42
        self.cells = cells
!
43
        self.error = error
!
44
      }
!
45
    }
46
  }
47
  
48
}
+
+ + + diff --git a/TesteiOS/coverage/ContactPresenter.swift.html b/TesteiOS/coverage/ContactPresenter.swift.html new file mode 100644 index 00000000..c96662b4 --- /dev/null +++ b/TesteiOS/coverage/ContactPresenter.swift.html @@ -0,0 +1,227 @@ + + + +ContactPresenter.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactPresenter.swift" : 0.00% +

+

(0 of 12 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactPresenter.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactPresenter.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol ContactPresentationLogic {
16
  func presentForm(response: Contact.Form.Response)
17
  func presentSuccesseMessage(response: Contact.Send.Response)
18
  func presentErrorMessage(response: Contact.Form.Response)
19
}
20
21
class ContactPresenter: ContactPresentationLogic {
22
  weak var viewController: ContactDisplayLogic?
23
  
24
  // MARK: Present Form
25
  func presentForm(response: Contact.Form.Response) {
!
26
    let viewModel = Contact.Form.ViewModel(cells: response.cells)
!
27
    viewController?.displayForm(viewModel: viewModel)
!
28
  }
!
29
  
30
  // MARK: Present Success Message
31
  func presentSuccesseMessage(response: Contact.Send.Response) {
!
32
    let viewModel = Contact.Send.ViewModel()
!
33
    viewController?.displaySuccessMessage(viewModel: viewModel)
!
34
  }
!
35
  
36
  // MARK: Present Error Message
37
  func presentErrorMessage(response: Contact.Form.Response) {
!
38
    let viewModel = Contact.Form.ViewModel(error: response.error)
!
39
    viewController?.displayErrorMessage(viewModel: viewModel)
!
40
  }
!
41
}
+
+ + + diff --git a/TesteiOS/coverage/ContactTableView.swift.html b/TesteiOS/coverage/ContactTableView.swift.html new file mode 100644 index 00000000..c1f4621b --- /dev/null +++ b/TesteiOS/coverage/ContactTableView.swift.html @@ -0,0 +1,217 @@ + + + +ContactTableView.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactTableView.swift" : 44.44% +

+

(8 of 18 relevant lines covered)

+

TesteiOS/UI/Views/Contact/ContactTableView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactTableView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class ContactTableView: UITableView {
12
13
  fileprivate var customDataSource: ContactDataSource?
14
  fileprivate var customDelegate: ContactDelegate?
15
  convenience init() {
2x
16
    self.init(frame: .zero, style: .plain)
2x
17
  }
2x
18
  
19
  override init(frame: CGRect, style: UITableView.Style) {
2x
20
    super.init(frame: frame, style: style)
2x
21
    customDelegate = ContactDelegate(tableView: self)
2x
22
    customDataSource = ContactDataSource(tableView: self, delegate: customDelegate!)
2x
23
  }
2x
24
  
25
  required init?(coder aDecoder: NSCoder) {
!
26
    fatalError("init(coder:) has not been implemented")
!
27
  }
!
28
}
29
30
extension ContactTableView {
31
  func update(with items: [Cell]) {
!
32
    customDelegate?.update(with: items)
!
33
    customDataSource?.update(with: items)
!
34
  }
!
35
  
36
  func setSendHandler(_ handler: @escaping ([Value]) -> ()) {
!
37
    customDataSource?.sendAction = handler
!
38
  }
!
39
}
+
+ + + diff --git a/TesteiOS/coverage/ContactView.swift.html b/TesteiOS/coverage/ContactView.swift.html new file mode 100644 index 00000000..03f61c98 --- /dev/null +++ b/TesteiOS/coverage/ContactView.swift.html @@ -0,0 +1,402 @@ + + + +ContactView.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactView.swift" : 85.45% +

+

(47 of 55 relevant lines covered)

+

TesteiOS/UI/Views/Contact/ContactView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class ContactView: UIView {
12
  lazy var activityIndicator: UIActivityIndicatorView = {
2x
13
    let view = UIActivityIndicatorView(style: .whiteLarge)
2x
14
    view.color = ColorPalette.black
2x
15
    return view
2x
16
  }()
2x
17
  
18
  lazy var tableView: ContactTableView = {
2x
19
    let view = ContactTableView()
2x
20
    view.separatorStyle = .none
2x
21
    view.alwaysBounceVertical = false
2x
22
    return view
2x
23
  }()
2x
24
  
25
  private lazy var feedbackView: FeedbackView = {
2x
26
    let view = FeedbackView.loadFromNib()
2x
27
    view.alpha = 0
2x
28
    return view
2x
29
  }()
2x
30
31
  override init(frame: CGRect) {
2x
32
    super.init(frame: frame)
2x
33
    setupViewCode()
2x
34
  }
2x
35
  
36
  required init?(coder aDecoder: NSCoder) {
!
37
    fatalError("init(coder:) has not been implemented")
!
38
  }
!
39
  
40
  func showFeedbackView() {
!
41
    UIView.animate(withDuration: 0.2) {
!
42
      self.feedbackView.alpha = 1
!
43
    }
!
44
  }
!
45
}
46
47
extension ContactView: ViewCode {
48
  func buildViewHierarchy() {
2x
49
    addSubview(tableView)
2x
50
    addSubview(feedbackView)
2x
51
    addSubview(activityIndicator)
2x
52
  }
2x
53
  
54
  func setupConstraints() {
2x
55
    tableView.snp.makeConstraints { make in
2x
56
      make.top.equalToSuperview()
2x
57
      make.leading.equalToSuperview()
2x
58
      make.trailing.equalToSuperview()
2x
59
      make.bottom.equalTo(-55)
2x
60
    }
2x
61
    
2x
62
    feedbackView.snp.makeConstraints { make in
2x
63
      make.top.equalToSuperview()
2x
64
      make.leading.equalToSuperview()
2x
65
      make.trailing.equalToSuperview()
2x
66
      make.bottom.equalTo(-55)
2x
67
    }
2x
68
    
2x
69
    activityIndicator.snp.makeConstraints { make in
2x
70
      make.top.equalToSuperview()
2x
71
      make.leading.equalToSuperview()
2x
72
      make.trailing.equalToSuperview()
2x
73
      make.bottom.equalTo(-55)
2x
74
    }
2x
75
  }
2x
76
}
+
+ + + diff --git a/TesteiOS/coverage/ContactViewController.swift.html b/TesteiOS/coverage/ContactViewController.swift.html new file mode 100644 index 00000000..477e22c3 --- /dev/null +++ b/TesteiOS/coverage/ContactViewController.swift.html @@ -0,0 +1,537 @@ + + + +ContactViewController.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactViewController.swift" : 28.81% +

+

(17 of 59 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactViewController.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactViewController.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol ContactDisplayLogic: class {
16
  func displayForm(viewModel: Contact.Form.ViewModel)
17
  func displayErrorMessage(viewModel: Contact.Form.ViewModel)
18
  func displaySuccessMessage(viewModel: Contact.Send.ViewModel)
19
}
20
21
class ContactViewController: UIViewController {
22
  var interactor: ContactBusinessLogic?
23
  var router: (NSObjectProtocol & ContactRoutingLogic & ContactDataPassing)?
24
  
25
  let contactView = ContactView()
26
27
  // MARK: Object lifecycle
28
  init() {
2x
29
    super.init(nibName: .none, bundle: .none)
2x
30
    title = "Contato"
2x
31
    setup()
2x
32
  }
2x
33
  
34
  required init?(coder aDecoder: NSCoder) {
!
35
    super.init(coder: aDecoder)
!
36
    setup()
!
37
  }
!
38
  
39
  // MARK: Setup
40
  private func setup() {
2x
41
    let viewController = self
2x
42
    let interactor = ContactInteractor()
2x
43
    let presenter = ContactPresenter()
2x
44
    let router = ContactRouter()
2x
45
    viewController.interactor = interactor
2x
46
    viewController.router = router
2x
47
    interactor.presenter = presenter
2x
48
    presenter.viewController = viewController
2x
49
    router.viewController = viewController
2x
50
    router.dataStore = interactor
2x
51
  }
2x
52
  
53
  // MARK: View lifecycle
54
  override func viewDidLoad() {
!
55
    super.viewDidLoad()
!
56
    setupView()
!
57
    fetchForm()
!
58
  }
!
59
  
60
  override func loadView() {
!
61
    view = contactView
!
62
  }
!
63
  
64
  func setupView() {
!
65
    let tapGeture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
!
66
    view.addGestureRecognizer(tapGeture)
!
67
    contactView.tableView.setSendHandler(sendButtonPressed)
!
68
  }
!
69
  
70
  @objc func hideKeyboard() {
!
71
    view.endEditing(true)
!
72
  }
!
73
  
74
  func sendButtonPressed(_ values: [Value]) {
!
75
    print(values)
!
76
    let request = Contact.Send.Request(values: values)
!
77
    interactor?.sendFormData(request: request)
!
78
  }
!
79
  
80
  // MARK: Fetch Form
81
  func fetchForm() {
!
82
    let request = Contact.Form.Request()
!
83
    interactor?.fetchForm(request: request)
!
84
    contactView.activityIndicator.startAnimating()
!
85
  }
!
86
}
87
88
extension ContactViewController: ContactDisplayLogic {
89
  func displayForm(viewModel: Contact.Form.ViewModel) {
!
90
    contactView.activityIndicator.stopAnimating()
!
91
    contactView.tableView.update(with: viewModel.cells)
!
92
  }
!
93
  
94
  func displaySuccessMessage(viewModel: Contact.Send.ViewModel) {
!
95
    contactView.showFeedbackView()
!
96
    contactView.tableView.reloadData()
!
97
  }
!
98
  
99
  func displayErrorMessage(viewModel: Contact.Form.ViewModel) {
!
100
    
!
101
    contactView.activityIndicator.stopAnimating()
!
102
  }
!
103
}
+
+ + + diff --git a/TesteiOS/coverage/ContactWorker.swift.html b/TesteiOS/coverage/ContactWorker.swift.html new file mode 100644 index 00000000..a561771d --- /dev/null +++ b/TesteiOS/coverage/ContactWorker.swift.html @@ -0,0 +1,167 @@ + + + +ContactWorker.swift - Slather + + + +
Slather logo
+

+Coverage for "ContactWorker.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/Scenes/Contact/ContactWorker.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ContactWorker.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
import Alamofire
15
16
class ContactWorker {
17
  
18
  private let networkManager: Networkable
19
  
20
  init(networkManager: Networkable = NetworkManager()) {
5x
21
    self.networkManager = networkManager
5x
22
  }
5x
23
  
24
  func fetchForm(request: Contact.Form.Request, completion: @escaping (Result<FormData>) -> ()) {
3x
25
    networkManager.fetchForm(request: request) { result in
3x
26
      completion(result)
3x
27
    }
3x
28
  }
3x
29
}
+
+ + + diff --git a/TesteiOS/coverage/DefaultAlamofireManager.swift.html b/TesteiOS/coverage/DefaultAlamofireManager.swift.html new file mode 100644 index 00000000..98975e89 --- /dev/null +++ b/TesteiOS/coverage/DefaultAlamofireManager.swift.html @@ -0,0 +1,122 @@ + + + +DefaultAlamofireManager.swift - Slather + + + +
Slather logo
+

+Coverage for "DefaultAlamofireManager.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/Services/DefaultAlamofireManager.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  DefaultAlamofireManager.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 13/01/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Alamofire
10
11
class DefaultAlamofireManager: Alamofire.SessionManager {
12
  static let sharedManager: DefaultAlamofireManager = {
2x
13
    let configuration = URLSessionConfiguration.default
2x
14
    configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
2x
15
    configuration.timeoutIntervalForRequest = 30
2x
16
    configuration.timeoutIntervalForResource = 30
2x
17
    configuration.requestCachePolicy = .useProtocolCachePolicy
2x
18
    return DefaultAlamofireManager(configuration: configuration)
2x
19
  }()
2x
20
}
+
+ + + diff --git a/TesteiOS/coverage/DownInfoTableViewCell.swift.html b/TesteiOS/coverage/DownInfoTableViewCell.swift.html new file mode 100644 index 00000000..3ec66a72 --- /dev/null +++ b/TesteiOS/coverage/DownInfoTableViewCell.swift.html @@ -0,0 +1,152 @@ + + + +DownInfoTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "DownInfoTableViewCell.swift" : 57.14% +

+

(4 of 7 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/DownInfoTableViewCell/DownInfoTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  DownInfoTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class DownInfoTableViewCell: FundBaseTableViewCell {
12
    
13
  @IBOutlet weak var nameLabel: UILabel!
14
  @IBOutlet weak var downloadButton: UIButton!
15
  
16
  var data: String? = .none
17
  
18
  override func setup(with fund: Fund) {
2x
19
    nameLabel.text = fund.downInfo[tag].name
2x
20
    data = fund.downInfo[tag].data
2x
21
  }
2x
22
    
23
  @IBAction func downloadData(_ sender: UIButton){
!
24
    self.downloadAction?(data)
!
25
  }
!
26
}
+
+ + + diff --git a/TesteiOS/coverage/FeedbackView.swift.html b/TesteiOS/coverage/FeedbackView.swift.html new file mode 100644 index 00000000..bc874866 --- /dev/null +++ b/TesteiOS/coverage/FeedbackView.swift.html @@ -0,0 +1,132 @@ + + + +FeedbackView.swift - Slather + + + +
Slather logo
+

+Coverage for "FeedbackView.swift" : 44.44% +

+

(4 of 9 relevant lines covered)

+

TesteiOS/UI/Views/Contact/FeedbackView/FeedbackView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FeedbackView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FeedbackView: UIView {
12
  class func loadFromNib() -> FeedbackView {
2x
13
    let nib = UINib(nibName: String(describing: self), bundle: .main)
2x
14
    return nib.instantiate(withOwner: nil, options: nil).first as! FeedbackView
2x
15
  }
2x
16
  
17
  @IBAction func sendButtonPressed(_ sender: UIButton) {
!
18
    UIView.animate(withDuration: 0.2) {
!
19
      self.alpha = 0
!
20
    }
!
21
  }
!
22
}
+
+ + + diff --git a/TesteiOS/coverage/FormData.swift.html b/TesteiOS/coverage/FormData.swift.html new file mode 100644 index 00000000..d12ce008 --- /dev/null +++ b/TesteiOS/coverage/FormData.swift.html @@ -0,0 +1,147 @@ + + + +FormData.swift - Slather + + + +
Slather logo
+

+Coverage for "FormData.swift" : 100.00% +

+

(5 of 5 relevant lines covered)

+

TesteiOS/Models/FormData.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FormData.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct FormData {
12
  let cells: [Cell]
13
}
14
15
extension FormData: Decodable {
16
  private enum CodingKeys: String, CodingKey {
17
    case cells
18
  }
19
  
20
  init(from decoder: Decoder) throws {
13x
21
    let container = try decoder.container(keyedBy: CodingKeys.self)
13x
22
    
13x
23
    cells = try container.decode([Cell].self, forKey: .cells)
13x
24
  }
13x
25
}
+
+ + + diff --git a/TesteiOS/coverage/Fund.swift.html b/TesteiOS/coverage/Fund.swift.html new file mode 100644 index 00000000..c3cbb031 --- /dev/null +++ b/TesteiOS/coverage/Fund.swift.html @@ -0,0 +1,277 @@ + + + +Fund.swift - Slather + + + +
Slather logo
+

+Coverage for "Fund.swift" : 100.00% +

+

(13 of 13 relevant lines covered)

+

TesteiOS/Models/Fund.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  Fund.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct Fund {
12
  let title: String
13
  let fundName: String
14
  let whatIs: String
15
  let definition: String
16
  let riskTitle: String
17
  let risk: Int
18
  let infoTitle: String
19
  let moreInfo: MoreInfoData
20
  let info: [Info]
21
  let downInfo: [Info]
22
}
23
24
extension Fund: Decodable {
25
  private enum CodingKeys: String, CodingKey {
26
    case title
27
    case fundName
28
    case whatIs
29
    case definition
30
    case riskTitle
31
    case risk
32
    case infoTitle
33
    case moreInfo
34
    case info
35
    case downInfo
36
  }
37
  
38
  init(from decoder: Decoder) throws {
1x
39
    let container = try decoder.container(keyedBy: CodingKeys.self)
1x
40
    title = try container.decode(String.self, forKey: .title)
1x
41
    fundName = try container.decode(String.self, forKey: .fundName)
1x
42
    whatIs = try container.decode(String.self, forKey: .whatIs)
1x
43
    definition = try container.decode(String.self, forKey: .definition)
1x
44
    riskTitle = try container.decode(String.self, forKey: .riskTitle)
1x
45
    risk = try container.decode(Int.self, forKey: .risk)
1x
46
    infoTitle = try container.decode(String.self, forKey: .infoTitle)
1x
47
    moreInfo = try container.decode(MoreInfoData.self, forKey: .moreInfo)
1x
48
    info = try container.decode([Info].self, forKey: .info)
1x
49
    downInfo = try container.decode([Info].self, forKey: .downInfo)
1x
50
  }
1x
51
}
+
+ + + diff --git a/TesteiOS/coverage/FundBaseTableViewCell.swift.html b/TesteiOS/coverage/FundBaseTableViewCell.swift.html new file mode 100644 index 00000000..ab7195fc --- /dev/null +++ b/TesteiOS/coverage/FundBaseTableViewCell.swift.html @@ -0,0 +1,102 @@ + + + +FundBaseTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "FundBaseTableViewCell.swift" : 0.00% +

+

(0 of 1 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/FundBaseTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundBaseTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 24/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
import Reusable
11
12
class FundBaseTableViewCell: UITableViewCell, NibReusable {
13
  func setup(with fund: Fund) {}
!
14
  var investAction: (() -> ())?
15
  var downloadAction: ((String?) -> ())?
16
}
+
+ + + diff --git a/TesteiOS/coverage/FundHeaderTableViewCell.swift.html b/TesteiOS/coverage/FundHeaderTableViewCell.swift.html new file mode 100644 index 00000000..b45d211d --- /dev/null +++ b/TesteiOS/coverage/FundHeaderTableViewCell.swift.html @@ -0,0 +1,167 @@ + + + +FundHeaderTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "FundHeaderTableViewCell.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/FundHeaderTableViewCell/FundHeaderTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundHeaderTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FundHeaderTableViewCell: FundBaseTableViewCell {
12
13
  @IBOutlet weak var titleLabel: UILabel!
14
  @IBOutlet weak var fundNameLabel: UILabel!
15
  @IBOutlet weak var whatIsLabel: UILabel!
16
  @IBOutlet weak var definitionLabel: UILabel!
17
  @IBOutlet weak var riskTitleLabel: UILabel!
18
  @IBOutlet weak var riskView: RiskView!
19
  
20
  override func setup(with fund: Fund) {
1x
21
    titleLabel.text = fund.title
1x
22
    fundNameLabel.text = fund.fundName
1x
23
    whatIsLabel.text = fund.whatIs
1x
24
    definitionLabel.text = fund.definition
1x
25
    riskTitleLabel.text = fund.riskTitle
1x
26
    riskView.setRist(risk: fund.risk)
1x
27
  }
1x
28
29
}
+
+ + + diff --git a/TesteiOS/coverage/FundsData.swift.html b/TesteiOS/coverage/FundsData.swift.html new file mode 100644 index 00000000..3fd9b82a --- /dev/null +++ b/TesteiOS/coverage/FundsData.swift.html @@ -0,0 +1,142 @@ + + + +FundsData.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsData.swift" : 100.00% +

+

(4 of 4 relevant lines covered)

+

TesteiOS/Models/FundsData.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsData.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct FundsData {
12
  let fund: Fund
13
}
14
15
extension FundsData: Decodable {
16
  private enum CodingKeys: String, CodingKey {
17
    case fund = "screen"
18
  }
19
  
20
  init(from decoder: Decoder) throws {
1x
21
    let container = try decoder.container(keyedBy: CodingKeys.self)
1x
22
    fund = try container.decode(Fund.self, forKey: .fund)
1x
23
  }
1x
24
}
+
+ + + diff --git a/TesteiOS/coverage/FundsDataSource.swift.html b/TesteiOS/coverage/FundsDataSource.swift.html new file mode 100644 index 00000000..4f0c7f4b --- /dev/null +++ b/TesteiOS/coverage/FundsDataSource.swift.html @@ -0,0 +1,377 @@ + + + +FundsDataSource.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsDataSource.swift" : 97.67% +

+

(42 of 43 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsDataSource.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsDataSource.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FundsDataSource: NSObject, ItemsTableViewDataSource {
12
  
13
  var items: [CellType] = []
14
  var fund: Fund? = .none
15
  var tableView: UITableView?
16
  var delegate: UITableViewDelegate?
17
  var investAction: (() -> ())?
18
  var downloadAction: ((String?) -> ())?
19
  
20
  required init(tableView: UITableView, delegate: UITableViewDelegate) {
2x
21
    self.tableView = tableView
2x
22
    self.delegate = delegate
2x
23
    super.init()
2x
24
    setupTableView()
2x
25
  }
2x
26
  
27
  func registerTableView() {
3x
28
    for item in items {
5x
29
      self.tableView?.register(item.getNib(), forCellReuseIdentifier: item.getIdentifier())
5x
30
    }
5x
31
  }
3x
32
  
33
  func update(with fund: Fund) {
1x
34
    self.fund = fund
1x
35
    self.items = [.fundHeader, .moreInfo, .info, .downInfo, .invest]
1x
36
    self.registerTableView()
1x
37
    self.tableView?.reloadData()
1x
38
  }
1x
39
}
40
41
extension FundsDataSource: UITableViewDataSource {
42
  
43
  func numberOfSections(in tableView: UITableView) -> Int {
9x
44
    return items.count
9x
45
  }
9x
46
  
47
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
5x
48
    switch section {
5x
49
    case 0, 1, 4 :
5x
50
      return 1
3x
51
    case 2:
5x
52
      return fund!.info.count
1x
53
    case 3:
5x
54
      return fund!.downInfo.count
1x
55
    default:
5x
56
      return 0
!
57
    }
5x
58
  }
5x
59
  
60
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
11x
61
    let type = items[indexPath.section]
11x
62
    let cell = tableView.dequeueReusableCell(withIdentifier: type.getIdentifier(), for: indexPath) as! FundBaseTableViewCell
11x
63
    
11x
64
    cell.tag = indexPath.row
11x
65
    cell.investAction = investAction
11x
66
    cell.downloadAction = downloadAction
11x
67
    cell.setup(with: fund!)
11x
68
    
11x
69
    return cell
11x
70
  }
11x
71
}
+
+ + + diff --git a/TesteiOS/coverage/FundsDelegate.swift.html b/TesteiOS/coverage/FundsDelegate.swift.html new file mode 100644 index 00000000..26872c8b --- /dev/null +++ b/TesteiOS/coverage/FundsDelegate.swift.html @@ -0,0 +1,152 @@ + + + +FundsDelegate.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsDelegate.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsDelegate.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsDelegate.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FundsDelegate: NSObject, UITableViewDelegate {
12
  
13
  weak var tableView: UITableView?
14
  
15
  var items: [CellType] = [.fundHeader, .moreInfo, .info, .downInfo, .invest]
16
  
17
  init(tableView: UITableView) {
2x
18
    self.tableView = tableView
2x
19
    super.init()
2x
20
    self.tableView?.delegate = self
2x
21
  }
2x
22
  
23
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
33x
24
    return items[indexPath.section].getHeight()
33x
25
  }
33x
26
}
+
+ + + diff --git a/TesteiOS/coverage/FundsInteractor.swift.html b/TesteiOS/coverage/FundsInteractor.swift.html new file mode 100644 index 00000000..b4a14d82 --- /dev/null +++ b/TesteiOS/coverage/FundsInteractor.swift.html @@ -0,0 +1,287 @@ + + + +FundsInteractor.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsInteractor.swift" : 90.00% +

+

(18 of 20 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsInteractor.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsInteractor.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol FundsBusinessLogic {
16
  func fetchFund(request: Funds.Get.Request)
17
  func downloadData(request: Funds.Download.Request)
18
}
19
20
protocol FundsDataStore {
21
  var url: String { get set }
22
}
23
24
class FundsInteractor: FundsBusinessLogic, FundsDataStore {
25
  var presenter: FundsPresentationLogic?
26
  var worker: FundsWorker?
27
  var url: String = ""
28
  
29
  init(worker: FundsWorker? = FundsWorker()) {
4x
30
    self.worker = worker
4x
31
  }
4x
32
  
33
  // MARK: Fetch fund
34
  func fetchFund(request: Funds.Get.Request) {
2x
35
    worker?.fetchFund(request: request, completion: { result in
2x
36
      switch result {
1x
37
      case .success(let data):
1x
38
        let response = Funds.Get.Response(fund: data.fund)
1x
39
        self.presenter?.presentFund(response: response)
1x
40
      case .failure(let error):
1x
41
        let response = Funds.Get.Response(error: error)
!
42
        self.presenter?.presentErrorMessage(response: response)
!
43
      }
1x
44
    })
1x
45
  }
2x
46
  
47
  // MARK: Fetch data
48
  func downloadData(request: Funds.Download.Request) {
2x
49
    url = request.url ?? "https://www.google.com/"
2x
50
    let response = Funds.Download.Response()
2x
51
    presenter?.presentDownloadedData(response: response)
2x
52
  }
2x
53
}
+
+ + + diff --git a/TesteiOS/coverage/FundsModels.swift.html b/TesteiOS/coverage/FundsModels.swift.html new file mode 100644 index 00000000..41c86bff --- /dev/null +++ b/TesteiOS/coverage/FundsModels.swift.html @@ -0,0 +1,252 @@ + + + +FundsModels.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsModels.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsModels.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsModels.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
enum Funds {
16
  // MARK: Use cases
17
  enum Download {
18
    struct Request {
19
      let url: String?
20
    }
21
    struct Response {}
22
    struct ViewModel {}
23
  }
24
  
25
  enum Get {
26
    struct Request {}
27
    struct Response {
28
      let fund: Fund?
29
      let error: Error?
30
      
31
      init(fund: Fund? = .none, error: Error? = .none) {
1x
32
        self.fund = fund
1x
33
        self.error = error
1x
34
      }
1x
35
    }
36
    struct ViewModel {
37
      let fund: Fund?
38
      let error: Error?
39
      
40
      init(fund: Fund? = .none, error: Error? = .none) {
1x
41
        self.fund = fund
1x
42
        self.error = error
1x
43
      }
1x
44
    }
45
  }
46
}
+
+ + + diff --git a/TesteiOS/coverage/FundsPresenter.swift.html b/TesteiOS/coverage/FundsPresenter.swift.html new file mode 100644 index 00000000..5d801dea --- /dev/null +++ b/TesteiOS/coverage/FundsPresenter.swift.html @@ -0,0 +1,227 @@ + + + +FundsPresenter.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsPresenter.swift" : 33.33% +

+

(4 of 12 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsPresenter.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsPresenter.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol FundsPresentationLogic {
16
  func presentFund(response: Funds.Get.Response)
17
  func presentDownloadedData(response: Funds.Download.Response)
18
  func presentErrorMessage(response: Funds.Get.Response)
19
}
20
21
class FundsPresenter: FundsPresentationLogic {
22
  weak var viewController: FundsDisplayLogic?
23
  
24
  // MARK: Present Fund
25
  func presentFund(response: Funds.Get.Response) {
1x
26
    let viewModel = Funds.Get.ViewModel(fund: response.fund)
1x
27
    viewController?.displayFund(viewModel: viewModel)
1x
28
  }
1x
29
  
30
  // MARK: Present Data
31
  func presentDownloadedData(response: Funds.Download.Response) {
!
32
    let viewModel = Funds.Download.ViewModel()
!
33
    viewController?.displayDownloadedData(viewModel: viewModel)
!
34
  }
!
35
  
36
  // MARK: Present Error Message
37
  func presentErrorMessage(response: Funds.Get.Response) {
!
38
    let viewModel = Funds.Get.ViewModel(error: response.error)
!
39
    viewController?.displayErrorMessage(viewModel: viewModel)
!
40
  }
!
41
}
+
+ + + diff --git a/TesteiOS/coverage/FundsRouter.swift.html b/TesteiOS/coverage/FundsRouter.swift.html new file mode 100644 index 00000000..b77bf2e2 --- /dev/null +++ b/TesteiOS/coverage/FundsRouter.swift.html @@ -0,0 +1,242 @@ + + + +FundsRouter.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsRouter.swift" : 0.00% +

+

(0 of 8 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsRouter.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsRouter.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
import SafariServices
15
16
@objc protocol FundsRoutingLogic {
17
  func routeToDownloadData()
18
}
19
20
protocol FundsDataPassing {
21
  var dataStore: FundsDataStore? { get }
22
}
23
24
class FundsRouter: NSObject, FundsRoutingLogic, FundsDataPassing {
25
  weak var viewController: FundsViewController?
26
  var dataStore: FundsDataStore?
27
  
28
  // MARK: Routing
29
  func routeToDownloadData() {
!
30
    guard let string = dataStore?.url, let url = URL(string: string) else { return }
!
31
    let safariViewController = SFSafariViewController(url: url)
!
32
    navigateToDownloadData(source: viewController!, destination: safariViewController)
!
33
  }
!
34
35
  // MARK: Navigation
36
  func navigateToDownloadData(source: FundsViewController, destination: SFSafariViewController) {
!
37
    source.present(destination, animated: true)
!
38
  }
!
39
  
40
  // MARK: Passing data
41
//  func passDataToSomewhere(source: FundsDataStore, destination: inout SomewhereDataStore) {
42
//    destination.name = source.name
43
//  }
44
}
+
+ + + diff --git a/TesteiOS/coverage/FundsTableView.swift.html b/TesteiOS/coverage/FundsTableView.swift.html new file mode 100644 index 00000000..a44b8b12 --- /dev/null +++ b/TesteiOS/coverage/FundsTableView.swift.html @@ -0,0 +1,232 @@ + + + +FundsTableView.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsTableView.swift" : 85.00% +

+

(17 of 20 relevant lines covered)

+

TesteiOS/UI/Views/Funds/FundsTableView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsTableView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 24/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FundsTableView: UITableView {
12
13
  fileprivate var customDataSource: FundsDataSource?
14
  fileprivate var customDelegate: FundsDelegate?
15
  convenience init() {
2x
16
    self.init(frame: .zero, style: .plain)
2x
17
  }
2x
18
  
19
  override init(frame: CGRect, style: UITableView.Style) {
2x
20
    super.init(frame: frame, style: style)
2x
21
    customDelegate = FundsDelegate(tableView: self)
2x
22
    customDataSource = FundsDataSource(tableView: self, delegate: customDelegate!)
2x
23
  }
2x
24
  
25
  required init?(coder aDecoder: NSCoder) {
!
26
    fatalError("init(coder:) has not been implemented")
!
27
  }
!
28
}
29
30
extension FundsTableView {
31
  func update(with fund: Fund) {
1x
32
    customDataSource?.update(with: fund)
1x
33
  }
1x
34
  
35
  func setInvestHandler(_ handler: @escaping () -> ()) {
2x
36
    customDataSource?.investAction = handler
2x
37
  }
2x
38
  
39
  func setDownloadHandler(_ handler: @escaping (String?) -> ()) {
2x
40
    customDataSource?.downloadAction = handler
2x
41
  }
2x
42
}
+
+ + + diff --git a/TesteiOS/coverage/FundsView.swift.html b/TesteiOS/coverage/FundsView.swift.html new file mode 100644 index 00000000..982cf093 --- /dev/null +++ b/TesteiOS/coverage/FundsView.swift.html @@ -0,0 +1,302 @@ + + + +FundsView.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsView.swift" : 91.89% +

+

(34 of 37 relevant lines covered)

+

TesteiOS/UI/Views/Funds/FundsView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class FundsView: UIView {
12
  lazy var activityIndicator: UIActivityIndicatorView = {
2x
13
    let view = UIActivityIndicatorView(style: .whiteLarge)
2x
14
    view.color = ColorPalette.black
2x
15
    return view
2x
16
  }()
2x
17
  
18
  lazy var tableView: FundsTableView = {
2x
19
    let view = FundsTableView()
2x
20
    view.separatorStyle = .none
2x
21
    view.alwaysBounceVertical = false
2x
22
    return view
2x
23
  }()
2x
24
25
  override init(frame: CGRect) {
2x
26
    super.init(frame: frame)
2x
27
    setupViewCode()
2x
28
  }
2x
29
  
30
  required init?(coder aDecoder: NSCoder) {
!
31
    fatalError("init(coder:) has not been implemented")
!
32
  }
!
33
}
34
35
extension FundsView: ViewCode {
36
  func buildViewHierarchy() {
2x
37
    addSubview(tableView)
2x
38
    addSubview(activityIndicator)
2x
39
  }
2x
40
  
41
  func setupConstraints() {
2x
42
    tableView.snp.makeConstraints { make in
2x
43
      make.top.equalToSuperview()
2x
44
      make.leading.equalToSuperview()
2x
45
      make.trailing.equalToSuperview()
2x
46
      make.bottom.equalTo(-55)
2x
47
    }
2x
48
    
2x
49
    activityIndicator.snp.makeConstraints { make in
2x
50
      make.top.equalToSuperview()
2x
51
      make.leading.equalToSuperview()
2x
52
      make.trailing.equalToSuperview()
2x
53
      make.bottom.equalTo(-55)
2x
54
    }
2x
55
  }
2x
56
}
+
+ + + diff --git a/TesteiOS/coverage/FundsViewController.swift.html b/TesteiOS/coverage/FundsViewController.swift.html new file mode 100644 index 00000000..d66c1f25 --- /dev/null +++ b/TesteiOS/coverage/FundsViewController.swift.html @@ -0,0 +1,527 @@ + + + +FundsViewController.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsViewController.swift" : 68.42% +

+

(39 of 57 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsViewController.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsViewController.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
15
protocol FundsDisplayLogic: class {
16
  func displayFund(viewModel: Funds.Get.ViewModel)
17
  func displayDownloadedData(viewModel: Funds.Download.ViewModel)
18
  func displayErrorMessage(viewModel: Funds.Get.ViewModel)
19
}
20
21
class FundsViewController: UIViewController {
22
  var interactor: FundsBusinessLogic?
23
  var router: (NSObjectProtocol & FundsRoutingLogic & FundsDataPassing)?
24
  
25
  let fundsView = FundsView()
26
27
  // MARK: Object lifecycle
28
  init() {
2x
29
    super.init(nibName: .none, bundle: .none)
2x
30
    title = "Investimento"
2x
31
    navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "share"), style: .plain, target: .none, action: .none)
2x
32
    setup()
2x
33
  }
2x
34
  
35
  required init?(coder aDecoder: NSCoder) {
!
36
    super.init(coder: aDecoder)
!
37
    setup()
!
38
  }
!
39
  
40
  // MARK: Setup
41
  private func setup() {
2x
42
    let viewController = self
2x
43
    let interactor = FundsInteractor()
2x
44
    let presenter = FundsPresenter()
2x
45
    let router = FundsRouter()
2x
46
    viewController.interactor = interactor
2x
47
    viewController.router = router
2x
48
    interactor.presenter = presenter
2x
49
    presenter.viewController = viewController
2x
50
    router.viewController = viewController
2x
51
    router.dataStore = interactor
2x
52
  }
2x
53
  
54
  // MARK: View lifecycle
55
  override func viewDidLoad() {
2x
56
    super.viewDidLoad()
2x
57
    setupView()
2x
58
    fetchFund()
2x
59
  }
2x
60
  
61
  override func loadView() {
2x
62
    view = fundsView
2x
63
  }
2x
64
  
65
  func setupView() {
2x
66
    fundsView.tableView.setInvestHandler(investButtonPressed)
2x
67
    fundsView.tableView.setDownloadHandler(downloadButtonPressed)
2x
68
  }
2x
69
  
70
  func investButtonPressed() {
!
71
    // TODO: Invest Button pressed action
!
72
    print("Investir")
!
73
  }
!
74
  
75
  func downloadButtonPressed(_ url: String?) {
!
76
    let request = Funds.Download.Request(url: url)
!
77
    interactor?.downloadData(request: request)
!
78
  }
!
79
  
80
  // MARK: Fetch Fund
81
  func fetchFund() {
2x
82
    let request = Funds.Get.Request()
2x
83
    interactor?.fetchFund(request: request)
2x
84
    fundsView.activityIndicator.startAnimating()
2x
85
  }
2x
86
}
87
88
extension FundsViewController: FundsDisplayLogic {
89
  func displayFund(viewModel: Funds.Get.ViewModel) {
1x
90
    fundsView.tableView.update(with: viewModel.fund!)
1x
91
    fundsView.activityIndicator.stopAnimating()
1x
92
  }
1x
93
  
94
  func displayDownloadedData(viewModel: Funds.Download.ViewModel) {
!
95
    router?.routeToDownloadData()
!
96
  }
!
97
  
98
  func displayErrorMessage(viewModel: Funds.Get.ViewModel) {
!
99
    fundsView.activityIndicator.stopAnimating()
!
100
  }
!
101
}
+
+ + + diff --git a/TesteiOS/coverage/FundsWorker.swift.html b/TesteiOS/coverage/FundsWorker.swift.html new file mode 100644 index 00000000..709be292 --- /dev/null +++ b/TesteiOS/coverage/FundsWorker.swift.html @@ -0,0 +1,167 @@ + + + +FundsWorker.swift - Slather + + + +
Slather logo
+

+Coverage for "FundsWorker.swift" : 100.00% +

+

(8 of 8 relevant lines covered)

+

TesteiOS/Scenes/Funds/FundsWorker.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  FundsWorker.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright (c) 2019 Brendoon Ryos. All rights reserved.
7
//
8
//  This file was generated by the Clean Swift Xcode Templates so
9
//  you can apply clean architecture to your iOS and Mac projects,
10
//  see http://clean-swift.com
11
//
12
13
import UIKit
14
import Alamofire
15
16
class FundsWorker {
17
  
18
  private let networkManager: Networkable
19
  
20
  init(networkManager: Networkable = NetworkManager()) {
4x
21
    self.networkManager = networkManager
4x
22
  }
4x
23
  
24
  func fetchFund(request: Funds.Get.Request, completion: @escaping (Result<FundsData>) -> ()) {
2x
25
    networkManager.fetchFund(request: request) { result in
2x
26
      completion(result)
1x
27
    }
1x
28
  }
2x
29
}
+
+ + + diff --git a/TesteiOS/coverage/Info.swift.html b/TesteiOS/coverage/Info.swift.html new file mode 100644 index 00000000..44cb35a7 --- /dev/null +++ b/TesteiOS/coverage/Info.swift.html @@ -0,0 +1,167 @@ + + + +Info.swift - Slather + + + +
Slather logo
+

+Coverage for "Info.swift" : 100.00% +

+

(5 of 5 relevant lines covered)

+

TesteiOS/Models/Info.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  Info.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct Info {
12
  let name: String
13
  let data: String?
14
}
15
16
extension Info: Decodable {
17
  private enum CodingKeys: String, CodingKey {
18
    case name
19
    case data
20
  }
21
  
22
  init(from decoder: Decoder) throws {
12x
23
    let container = try decoder.container(keyedBy: CodingKeys.self)
12x
24
    name = try container.decode(String.self, forKey: .name)
12x
25
    data = try? container.decode(String.self, forKey: .data)
12x
26
  }
12x
27
}
28
29
+
+ + + diff --git a/TesteiOS/coverage/InfoTableViewCell.swift.html b/TesteiOS/coverage/InfoTableViewCell.swift.html new file mode 100644 index 00000000..4e644051 --- /dev/null +++ b/TesteiOS/coverage/InfoTableViewCell.swift.html @@ -0,0 +1,122 @@ + + + +InfoTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "InfoTableViewCell.swift" : 100.00% +

+

(4 of 4 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/InfoTableViewCell/InfoTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  InfoTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class InfoTableViewCell: FundBaseTableViewCell {
12
13
  @IBOutlet weak var nameLabel: UILabel!
14
  @IBOutlet weak var dataLabel: UILabel!
15
  
16
  override func setup(with fund: Fund) {
7x
17
    nameLabel.text = fund.info[tag].name
7x
18
    dataLabel.text = fund.info[tag].data
7x
19
  }
7x
20
}
+
+ + + diff --git a/TesteiOS/coverage/InvestTableViewCell.swift.html b/TesteiOS/coverage/InvestTableViewCell.swift.html new file mode 100644 index 00000000..5a3bfbfb --- /dev/null +++ b/TesteiOS/coverage/InvestTableViewCell.swift.html @@ -0,0 +1,187 @@ + + + +InvestTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "InvestTableViewCell.swift" : 0.00% +

+

(0 of 17 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/InvestTableViewCell/InvestTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  InvestTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 24/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class InvestTableViewCell: FundBaseTableViewCell {
12
  
13
  @IBOutlet weak var investButton: UIButton!
14
  
15
  override func awakeFromNib() {
!
16
    super.awakeFromNib()
!
17
    investButton.layer.cornerRadius = investButton.frame.height / 2
!
18
    investButton.setTitle("Investir", for: .normal)
!
19
  }
!
20
    
21
  @IBAction func investButtonPressed(_ sender: UIButton) {
!
22
    UIView.animate(withDuration: 0.2, animations: {
!
23
      sender.backgroundColor = ColorPalette.middleRedPurple
!
24
      sender.transform = CGAffineTransform(scaleX: 0.90, y: 0.83)
!
25
    }) { completed in
!
26
      UIView.animate(withDuration: 0.2, animations: {
!
27
        self.investAction?()
!
28
        sender.backgroundColor = ColorPalette.rossoCorsa
!
29
        sender.transform = CGAffineTransform.identity
!
30
      })
!
31
    }
!
32
  }
!
33
}
+
+ + + diff --git a/TesteiOS/coverage/ItemsTableViewDataSource.swift.html b/TesteiOS/coverage/ItemsTableViewDataSource.swift.html new file mode 100644 index 00000000..b1fd866e --- /dev/null +++ b/TesteiOS/coverage/ItemsTableViewDataSource.swift.html @@ -0,0 +1,182 @@ + + + +ItemsTableViewDataSource.swift - Slather + + + +
Slather logo
+

+Coverage for "ItemsTableViewDataSource.swift" : 85.71% +

+

(6 of 7 relevant lines covered)

+

TesteiOS/Commons/ItemsTableViewDataSource.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ItemsTableViewDataSource.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 04/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
protocol ItemsTableViewDataSource: UITableViewDataSource {
12
  associatedtype T
13
  var items:[T] { get }
14
  var tableView: UITableView? { get }
15
  var delegate: UITableViewDelegate? { get }
16
  
17
  init(tableView: UITableView, delegate: UITableViewDelegate)
18
  
19
  func setupTableView()
20
  func registerTableView()
21
}
22
23
extension ItemsTableViewDataSource {
24
  func setupTableView() {
13x
25
    registerTableView()
13x
26
    self.tableView?.dataSource = self
13x
27
    self.tableView?.delegate = self.delegate
13x
28
    self.tableView?.reloadData()
13x
29
  }
13x
30
  
31
  func registerTableView() {}
!
32
}
+
+ + + diff --git a/TesteiOS/coverage/MoreInfo.swift.html b/TesteiOS/coverage/MoreInfo.swift.html new file mode 100644 index 00000000..97c592d1 --- /dev/null +++ b/TesteiOS/coverage/MoreInfo.swift.html @@ -0,0 +1,157 @@ + + + +MoreInfo.swift - Slather + + + +
Slather logo
+

+Coverage for "MoreInfo.swift" : 100.00% +

+

(5 of 5 relevant lines covered)

+

TesteiOS/Models/MoreInfo.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  MoreInfo.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct MoreInfo {
12
  let fund: Double
13
  let cdi: Double
14
}
15
16
extension MoreInfo: Decodable {
17
  private enum CodingKeys: String, CodingKey {
18
    case fund
19
    case cdi = "CDI"
20
  }
21
  
22
  init(from decoder: Decoder) throws {
3x
23
    let container = try decoder.container(keyedBy: CodingKeys.self)
3x
24
    fund = try container.decode(Double.self, forKey: .fund)
3x
25
    cdi = try container.decode(Double.self, forKey: .cdi)
3x
26
  }
3x
27
}
+
+ + + diff --git a/TesteiOS/coverage/MoreInfoData.swift.html b/TesteiOS/coverage/MoreInfoData.swift.html new file mode 100644 index 00000000..b7f0b983 --- /dev/null +++ b/TesteiOS/coverage/MoreInfoData.swift.html @@ -0,0 +1,172 @@ + + + +MoreInfoData.swift - Slather + + + +
Slather logo
+

+Coverage for "MoreInfoData.swift" : 100.00% +

+

(6 of 6 relevant lines covered)

+

TesteiOS/Models/MoreInfoData.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  MoreInfoData.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 23/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
struct MoreInfoData {
12
  let month: MoreInfo
13
  let year: MoreInfo
14
  let twelveMonths: MoreInfo
15
}
16
17
extension MoreInfoData: Decodable {
18
  private enum CodingKeys: String, CodingKey {
19
    case month
20
    case year
21
    case twelveMonths = "12months"
22
  }
23
  
24
  init(from decoder: Decoder) throws {
1x
25
    let container = try decoder.container(keyedBy: CodingKeys.self)
1x
26
    month = try container.decode(MoreInfo.self, forKey: .month)
1x
27
    year = try container.decode(MoreInfo.self, forKey: .year)
1x
28
    twelveMonths = try container.decode(MoreInfo.self, forKey: .twelveMonths)
1x
29
  }
1x
30
}
+
+ + + diff --git a/TesteiOS/coverage/MoreInfoTableViewCell.swift.html b/TesteiOS/coverage/MoreInfoTableViewCell.swift.html new file mode 100644 index 00000000..d4c15bbc --- /dev/null +++ b/TesteiOS/coverage/MoreInfoTableViewCell.swift.html @@ -0,0 +1,167 @@ + + + +MoreInfoTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "MoreInfoTableViewCell.swift" : 100.00% +

+

(9 of 9 relevant lines covered)

+

TesteiOS/UI/Cells/Fund/MoreInfoTableViewCell/MoreInfoTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  MoreInfoTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 24/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class MoreInfoTableViewCell: FundBaseTableViewCell {
12
  @IBOutlet weak var infoTitleLabel: UILabel!
13
  @IBOutlet weak var monthFundLabel: UILabel!
14
  @IBOutlet weak var monthCdiLabel: UILabel!
15
  @IBOutlet weak var yearFundLabel: UILabel!
16
  @IBOutlet weak var yearCdiLabel: UILabel!
17
  @IBOutlet weak var twelveMonthsFundLabel: UILabel!
18
  @IBOutlet weak var twelveMonthsCdiLabel: UILabel!
19
  
20
  override func setup(with fund: Fund) {
1x
21
    infoTitleLabel.text = fund.infoTitle
1x
22
    monthFundLabel.text = String(format: "%.1f %%", fund.moreInfo.month.fund)
1x
23
    monthCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.month.cdi)
1x
24
    yearFundLabel.text = String(format: "%.1f %%", fund.moreInfo.year.fund)
1x
25
    yearCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.year.cdi)
1x
26
    twelveMonthsFundLabel.text = String(format: "%.1f %%", fund.moreInfo.twelveMonths.fund)
1x
27
    twelveMonthsCdiLabel.text = String(format: "%.1f %%", fund.moreInfo.twelveMonths.cdi)
1x
28
  }
1x
29
}
+
+ + + diff --git a/TesteiOS/coverage/NetworkManager.swift.html b/TesteiOS/coverage/NetworkManager.swift.html new file mode 100644 index 00000000..7478d873 --- /dev/null +++ b/TesteiOS/coverage/NetworkManager.swift.html @@ -0,0 +1,322 @@ + + + +NetworkManager.swift - Slather + + + +
Slather logo
+

+Coverage for "NetworkManager.swift" : 43.33% +

+

(13 of 30 relevant lines covered)

+

TesteiOS/Services/NetworkManager.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  NetworkManager.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
import Moya
11
import Alamofire
12
13
enum APIEnvironment {
14
  case staging
15
  case qa
16
  case production
17
}
18
19
protocol Networkable {
20
  var provider: MoyaProvider<BankAPI> { get }
21
  func fetchForm(request: Contact.Form.Request, completion: @escaping (Result<FormData>) -> ())
22
  func fetchFund(request: Funds.Get.Request, completion: @escaping (Result<FundsData>) -> ())
23
}
24
25
struct NetworkManager: Networkable {
26
  let provider = MoyaProvider<BankAPI>(manager: DefaultAlamofireManager.sharedManager, plugins: [NetworkLoggerPlugin(verbose: true)])
27
  static let environment: APIEnvironment = .staging
28
  
29
  func fetchForm(request: Contact.Form.Request, completion: @escaping (Result<FormData>) -> ()) {
!
30
    provider.request(.fetchForm) { result in
!
31
      switch result {
!
32
      case .success(let response):
!
33
        do {
!
34
          let formData = try JSONDecoder().decode(FormData.self, from: response.data)
!
35
          completion(Result.success(formData))
!
36
        } catch let error {
!
37
          fatalError("data could not be decoded: \(error)")
!
38
        }
!
39
      case .failure(let error):
!
40
        completion(Result.failure(error))
!
41
      }
!
42
    }
!
43
  }
!
44
  
45
  func fetchFund(request: Funds.Get.Request, completion: @escaping (Result<FundsData>) -> ()) {
2x
46
    provider.request(.fetchFund) { result in
2x
47
      switch result {
1x
48
      case .success(let response):
1x
49
        do {
1x
50
          let fundsData = try JSONDecoder().decode(FundsData.self, from: response.data)
1x
51
          completion(Result.success(fundsData))
1x
52
        } catch let error {
1x
53
          fatalError("data could not be decoded: \(error)")
!
54
        }
1x
55
      case .failure(let error):
1x
56
        completion(Result.failure(error))
!
57
      }
1x
58
    }
1x
59
  }
2x
60
}
+
+ + + diff --git a/TesteiOS/coverage/RiskView.swift.html b/TesteiOS/coverage/RiskView.swift.html new file mode 100644 index 00000000..0e4cd6c7 --- /dev/null +++ b/TesteiOS/coverage/RiskView.swift.html @@ -0,0 +1,482 @@ + + + +RiskView.swift - Slather + + + +
Slather logo
+

+Coverage for "RiskView.swift" : 73.68% +

+

(42 of 57 relevant lines covered)

+

TesteiOS/UI/Views/Funds/RiskView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  RiskView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 24/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class RiskView: UIView {
12
  
13
  @IBOutlet weak var fisrtBar: UIView!
14
  @IBOutlet weak var lastBar: UIView!
15
  
16
  @IBOutlet weak var fisrtBarHeightConstraint: NSLayoutConstraint!
17
  @IBOutlet weak var secondBarHeightConstraint: NSLayoutConstraint!
18
  @IBOutlet weak var thirdBarHeightConstraint: NSLayoutConstraint!
19
  @IBOutlet weak var fourthHeightConstraint: NSLayoutConstraint!
20
  @IBOutlet weak var lastBarHeightConstraint: NSLayoutConstraint!
21
  
22
  @IBOutlet weak var vImageViewLeadingConstraint: NSLayoutConstraint!
23
  
24
  private let defaultHeightConstraintValue: CGFloat = 6.0
25
  private let selectedHeightConstraintValue: CGFloat = 10.0
26
  
27
  private var defaultVImageViewLeadingConstraintValue: CGFloat!
28
  
29
  func setRist(risk: Int) {
1x
30
    resetHeightConstraints()
1x
31
    
1x
32
    switch risk {
1x
33
    case 1:
1x
34
      fisrtBarHeightConstraint.constant = selectedHeightConstraintValue
!
35
      configureFirstBar(factor: selectedHeightConstraintValue)
!
36
      configureLastBar(factor: defaultHeightConstraintValue)
!
37
    case 2:
1x
38
      secondBarHeightConstraint.constant = selectedHeightConstraintValue
!
39
    case 3:
1x
40
      thirdBarHeightConstraint.constant = selectedHeightConstraintValue
!
41
    case 4:
1x
42
      fourthHeightConstraint.constant = selectedHeightConstraintValue
1x
43
    case 5:
1x
44
      lastBarHeightConstraint.constant = selectedHeightConstraintValue
!
45
      configureFirstBar(factor: defaultHeightConstraintValue)
!
46
      configureLastBar(factor: selectedHeightConstraintValue)
!
47
    default:
1x
48
      break
!
49
    }
1x
50
    
1x
51
    configureVImageView(risk: risk)
1x
52
    
1x
53
    self.layoutIfNeeded()
1x
54
  }
1x
55
  
56
  private func configureVImageView(risk: Int) {
1x
57
    let factor = (UIScreen.main.bounds.width - 70) / 5
1x
58
    let value = defaultVImageViewLeadingConstraintValue + (CGFloat(risk - 1) * factor)
1x
59
    vImageViewLeadingConstraint.constant = value
1x
60
  }
1x
61
  
62
  private func resetHeightConstraints() {
1x
63
    fisrtBarHeightConstraint.constant = defaultHeightConstraintValue
1x
64
    secondBarHeightConstraint.constant = defaultHeightConstraintValue
1x
65
    thirdBarHeightConstraint.constant = defaultHeightConstraintValue
1x
66
    fourthHeightConstraint.constant = defaultHeightConstraintValue
1x
67
    lastBarHeightConstraint.constant = defaultHeightConstraintValue
1x
68
  }
1x
69
  
70
  private func configureFirstBar(factor: CGFloat) {
!
71
    fisrtBar.layer.cornerRadius = factor / 2
!
72
  }
!
73
  
74
  private func configureLastBar(factor: CGFloat) {
!
75
    lastBar.layer.cornerRadius = factor / 2
!
76
  }
!
77
  
78
  private func configure() {
1x
79
    fisrtBar.layer.cornerRadius = fisrtBar.frame.height / 2
1x
80
    fisrtBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
1x
81
    
1x
82
    lastBar.layer.cornerRadius = lastBar.frame.height / 2
1x
83
    lastBar.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
1x
84
    vImageViewLeadingConstraint.constant = ((UIScreen.main.bounds.width - 70) / 5) / 2
1x
85
    defaultVImageViewLeadingConstraintValue = vImageViewLeadingConstraint.constant
1x
86
  }
1x
87
  
88
  override func awakeFromNib() {
1x
89
    super.awakeFromNib()
1x
90
    configure()
1x
91
  }
1x
92
}
+
+ + + diff --git a/TesteiOS/coverage/SendTableViewCell.swift.html b/TesteiOS/coverage/SendTableViewCell.swift.html new file mode 100644 index 00000000..b3a5d1de --- /dev/null +++ b/TesteiOS/coverage/SendTableViewCell.swift.html @@ -0,0 +1,232 @@ + + + +SendTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "SendTableViewCell.swift" : 0.00% +

+

(0 of 24 relevant lines covered)

+

TesteiOS/UI/Cells/Contact/SendTableViewCell/SendTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  SendTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
final class SendTableViewCell: ContactBaseTableViewCell {
12
13
  @IBOutlet weak var sendButton: UIButton!
14
  
15
  override func awakeFromNib() {
!
16
    super.awakeFromNib()
!
17
    sendButton.layer.cornerRadius = sendButton.frame.height / 2
!
18
  }
!
19
  
20
  override func setup(with item: Cell) {
!
21
    super.setup(with: item)
!
22
    sendButton.isUserInteractionEnabled = false
!
23
    sendButton.transform = CGAffineTransform.identity
!
24
    sendButton.backgroundColor = ColorPalette.middleRedPurple
!
25
    sendButton.setTitle(item.message, for: .normal)
!
26
    sendButton.addTarget(self, action: #selector(sendButtonPressed(_:)), for: .touchUpInside)
!
27
  }
!
28
  
29
  override func enableAction(_ value: Bool) {
!
30
    sendButton.backgroundColor = value ? ColorPalette.rossoCorsa : ColorPalette.middleRedPurple
!
31
    sendButton.isUserInteractionEnabled = value
!
32
  }
!
33
  
34
  @objc func sendButtonPressed(_ sender: UIButton) {
!
35
    UIView.animate(withDuration: 0.2, animations: {
!
36
      sender.backgroundColor = ColorPalette.middleRedPurple
!
37
      sender.transform = CGAffineTransform(scaleX: 0.90, y: 0.83)
!
38
    }) { completed in
!
39
      self.sendAction?()
!
40
    }
!
41
  }
!
42
}
+
+ + + diff --git a/TesteiOS/coverage/String+Validator.swift.html b/TesteiOS/coverage/String+Validator.swift.html new file mode 100644 index 00000000..a697cdde --- /dev/null +++ b/TesteiOS/coverage/String+Validator.swift.html @@ -0,0 +1,362 @@ + + + +String+Validator.swift - Slather + + + +
Slather logo
+

+Coverage for "String+Validator.swift" : 100.00% +

+

(54 of 54 relevant lines covered)

+

TesteiOS/Supporting Files/Extensions/String+Validator.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  String+Validator.swift
3
//  TesteiOSv2
4
//
5
//  Created by Brendoon Ryos on 11/01/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
extension String {
12
  var isValidCPF: Bool {
4x
13
    
4x
14
    let numbers = self.compactMap({Int(String($0))})
38x
15
    guard numbers.count == 11 && Set(numbers).count != 1 else { return false }
4x
16
    let sum1 = 11 - ( numbers[0] * 10 +
2x
17
      numbers[1] * 9 +
2x
18
      numbers[2] * 8 +
2x
19
      numbers[3] * 7 +
2x
20
      numbers[4] * 6 +
2x
21
      numbers[5] * 5 +
2x
22
      numbers[6] * 4 +
2x
23
      numbers[7] * 3 +
2x
24
      numbers[8] * 2 ) % 11
2x
25
    let dv1 = sum1 > 9 ? 0 : sum1
2x
26
    let sum2 = 11 - ( numbers[0] * 11 +
2x
27
      numbers[1] * 10 +
2x
28
      numbers[2] * 9 +
2x
29
      numbers[3] * 8 +
2x
30
      numbers[4] * 7 +
2x
31
      numbers[5] * 6 +
2x
32
      numbers[6] * 5 +
2x
33
      numbers[7] * 4 +
2x
34
      numbers[8] * 3 +
2x
35
      numbers[9] * 2 ) % 11
2x
36
    let dv2 = sum2 > 9 ? 0 : sum2
2x
37
    return dv1 == numbers[9] && dv2 == numbers[10]
2x
38
  }
4x
39
  
40
  var isValidEmail: Bool {
5x
41
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
5x
42
    
5x
43
    let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
5x
44
    return emailTest.evaluate(with: self)
5x
45
  }
5x
46
  
47
  func isValidPassword() -> Bool {
5x
48
    let capitalLetterRegEx  = ".*[A-Z]+.*"
5x
49
    let texttest = NSPredicate(format:"SELF MATCHES %@", capitalLetterRegEx)
5x
50
    if !texttest.evaluate(with: self) {
5x
51
      return false
2x
52
    }
3x
53
  
3x
54
    let specialCharacterRegEx  = ".*[!@#$%&*():_+=/?´~;{}*ºª|\\,(){}^\\[\\]\"]+.*"
3x
55
    let texttest2 = NSPredicate(format:"SELF MATCHES %@", specialCharacterRegEx)
3x
56
    if !texttest2.evaluate(with: self) {
3x
57
      return false
1x
58
    }
2x
59
    
2x
60
    let alphanumericLetterRegEx  = ".*[0-9]+.*"
2x
61
    let texttest3 = NSPredicate(format:"SELF MATCHES %@", alphanumericLetterRegEx)
2x
62
    if !texttest3.evaluate(with: self) {
2x
63
      return false
1x
64
    }
1x
65
    
1x
66
    return true
1x
67
  }
2x
68
}
+
+ + + diff --git a/TesteiOS/coverage/TabBarButton.swift.html b/TesteiOS/coverage/TabBarButton.swift.html new file mode 100644 index 00000000..c81dcb38 --- /dev/null +++ b/TesteiOS/coverage/TabBarButton.swift.html @@ -0,0 +1,182 @@ + + + +TabBarButton.swift - Slather + + + +
Slather logo
+

+Coverage for "TabBarButton.swift" : 82.35% +

+

(14 of 17 relevant lines covered)

+

TesteiOS/UI/Views/TabBarButton.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  TabBarButton.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class TabBarButton: UIButton {
12
13
  override init(frame: CGRect) {
4x
14
    super.init(frame: frame)
4x
15
    setup()
4x
16
  }
4x
17
  
18
  required init?(coder aDecoder: NSCoder) {
!
19
    fatalError("init(coder:) has not been implemented")
!
20
  }
!
21
  
22
  private func setup() {
4x
23
    contentMode = .scaleAspectFit
4x
24
    clipsToBounds = true
4x
25
    adjustsImageWhenHighlighted = false
4x
26
    adjustsImageWhenDisabled = false
4x
27
    setBackgroundImage(UIImage(named: "tabBarItemNormal"), for: .normal)
4x
28
    setBackgroundImage(UIImage(named: "tabBarItemSelected"), for: .selected)
4x
29
    tintColor = ColorPalette.white
4x
30
    titleLabel?.font = UIFont(name: FontNames.medium, size: 16)
4x
31
  }
4x
32
}
+
+ + + diff --git a/TesteiOS/coverage/TabBarView.swift.html b/TesteiOS/coverage/TabBarView.swift.html new file mode 100644 index 00000000..794c29ef --- /dev/null +++ b/TesteiOS/coverage/TabBarView.swift.html @@ -0,0 +1,317 @@ + + + +TabBarView.swift - Slather + + + +
Slather logo
+

+Coverage for "TabBarView.swift" : 91.89% +

+

(34 of 37 relevant lines covered)

+

TesteiOS/UI/Views/TabBarView.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  TabBarView.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
class TabBarView: UIView {
12
  
13
  lazy var button1: TabBarButton = {
2x
14
    let button = TabBarButton(frame: .zero)
2x
15
    button.tag = 0
2x
16
    button.setTitle("Investimento", for: .normal)
2x
17
    return button
2x
18
  }()
2x
19
  
20
  lazy var button2: TabBarButton = {
2x
21
    let button = TabBarButton(frame: .zero)
2x
22
    button.tag = 1
2x
23
    button.setTitle("Contato", for: .normal)
2x
24
    return button
2x
25
  }()
2x
26
  
27
  lazy var containerView: UIStackView = {
2x
28
    let view = UIStackView(frame: .zero)
2x
29
    view.axis = .horizontal
2x
30
    view.distribution = .fillEqually
2x
31
    return view
2x
32
  }()
2x
33
34
  override init(frame: CGRect) {
2x
35
    super.init(frame: frame)
2x
36
    setupViewCode()
2x
37
  }
2x
38
  
39
  required init?(coder aDecoder: NSCoder) {
!
40
    fatalError("init(coder:) has not been implemented")
!
41
  }
!
42
}
43
44
extension TabBarView: ViewCode {
45
  func buildViewHierarchy() {
2x
46
    addSubview(containerView)
2x
47
  }
2x
48
  
49
  func setupConstraints() {
2x
50
    containerView.snp.makeConstraints { make in
2x
51
      make.edges.equalToSuperview()
2x
52
    }
2x
53
  }
2x
54
  
55
  func configureViews() {
2x
56
    containerView.addArrangedSubview(button1)
2x
57
    containerView.addArrangedSubview(button2)
2x
58
  }
2x
59
}
+
+ + + diff --git a/TesteiOS/coverage/TabBarViewController.swift.html b/TesteiOS/coverage/TabBarViewController.swift.html new file mode 100644 index 00000000..d98b57ac --- /dev/null +++ b/TesteiOS/coverage/TabBarViewController.swift.html @@ -0,0 +1,262 @@ + + + +TabBarViewController.swift - Slather + + + +
Slather logo
+

+Coverage for "TabBarViewController.swift" : 72.41% +

+

(21 of 29 relevant lines covered)

+

TesteiOS/Commons/TabBarViewController.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  TabBarViewController.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
import SnapKit
11
12
class TabBarViewController: UITabBarController {
13
  
14
  let tabBarView = TabBarView()
15
16
  override func viewDidLoad() {
2x
17
    super.viewDidLoad()
2x
18
    setup()
2x
19
  }
2x
20
21
  private func setup() {
2x
22
    self.tabBar.isHidden = true
2x
23
    view.addSubview(tabBarView)
2x
24
    setupConstraints()
2x
25
    selectedIndex = tabBarView.button1.tag
2x
26
    tabBarView.button1.isSelected = true
2x
27
    tabBarView.button1.addTarget(self, action: #selector(tabbarItemPressed(_:)), for: .touchUpInside)
2x
28
    tabBarView.button2.addTarget(self, action: #selector(tabbarItemPressed(_:)), for: .touchUpInside)
2x
29
  }
2x
30
  
31
  func setupConstraints() {
2x
32
    tabBarView.snp.makeConstraints { make in
2x
33
      make.bottom.equalToSuperview()
2x
34
      make.height.equalTo(57)
2x
35
      make.leading.equalToSuperview()
2x
36
      make.trailing.equalToSuperview()
2x
37
    }
2x
38
  }
2x
39
  
40
  @objc func tabbarItemPressed(_ sender: UIButton) {
!
41
    selectedIndex = sender.tag
!
42
    tabBarView.button1.isSelected = tabBarView.button1.tag == sender.tag
!
43
    tabBarView.button2.isSelected = tabBarView.button2.tag == sender.tag
!
44
    
!
45
    tabBarView.button1.isUserInteractionEnabled = !tabBarView.button1.isSelected
!
46
    tabBarView.button2.isUserInteractionEnabled = !tabBarView.button2.isSelected
!
47
  }
!
48
}
+
+ + + diff --git a/TesteiOS/coverage/TextFieldTableViewCell.swift.html b/TesteiOS/coverage/TextFieldTableViewCell.swift.html new file mode 100644 index 00000000..43c3b35a --- /dev/null +++ b/TesteiOS/coverage/TextFieldTableViewCell.swift.html @@ -0,0 +1,577 @@ + + + +TextFieldTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "TextFieldTableViewCell.swift" : 0.00% +

+

(0 of 64 relevant lines covered)

+

TesteiOS/UI/Cells/Contact/TextFieldTableViewCell/TextFieldTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  TextFieldTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
import JMMaskTextField_Swift
11
12
final class TextFieldTableViewCell: ContactBaseTableViewCell {
13
    
14
  @IBOutlet weak var titleLabel: UILabel!
15
  @IBOutlet var textField: UITextField!
16
  @IBOutlet weak var lineView: UIView!
17
  
18
  var isTextValid: Bool = false {
19
    didSet {
!
20
      lineView.backgroundColor = isTextValid ? ColorPalette.green : ColorPalette.red
!
21
      if isTextValid {
!
22
        callback?((titleLabel.text!, textField.text!))
!
23
      }
!
24
    }
!
25
  }
26
  
27
  override func awakeFromNib() {
!
28
    super.awakeFromNib()
!
29
    textField.delegate = self
!
30
    textField.addTarget(self, action: #selector(resizeTitleLabel), for: .editingDidBegin)
!
31
    textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
!
32
  }
!
33
  
34
  @objc func resizeTitleLabel() {
!
35
    titleLabel.font = UIFont(name: FontNames.regular, size: 11)
!
36
    if textField.text!.isEmpty {
!
37
      lineView.backgroundColor = ColorPalette.silverChalice
!
38
    }
!
39
  }
!
40
  
41
  @objc func textFieldDidChange(_ textField: UITextField) {
!
42
    checkTextField(textField)
!
43
  }
!
44
  
45
  override func setup(with item: Cell) {
!
46
    super.setup(with: item)
!
47
    if item.message == "Telefone" {
!
48
      textField.textContentType = UITextContentType.telephoneNumber
!
49
      textField.keyboardType = .numberPad
!
50
    } else {
!
51
      let type = TypeField(rawValue: item.typefield ?? 0)
!
52
      textField.textContentType = type?.contentType ?? .name
!
53
      textField.keyboardType = type?.keyboardType ?? .default
!
54
    }
!
55
    titleLabel.text = item.message
!
56
    textField.text = .none
!
57
    lineView.backgroundColor = ColorPalette.isabelline
!
58
    titleLabel.font = UIFont(name: FontNames.regular, size: 16)
!
59
  }
!
60
  
61
  private func checkTextField(_ textField: UITextField) {
62
    guard var text = textField.text else { return }
63
    switch textField.textContentType! {
64
    case .name:
65
      if text.last == " " {
66
        text.removeLast()
67
        textField.text = text
68
      }
69
      isTextValid = text.count >= 5
70
    case .telephoneNumber:
71
      isTextValid = text.count >= 10
72
    default:
73
      let newText = text.replacingOccurrences(of: " ", with: "")
74
      textField.text = newText
75
      isTextValid = newText.isValidEmail
76
    }
77
  }
78
}
79
80
extension TextFieldTableViewCell: UITextFieldDelegate {
81
  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
!
82
    textField.resignFirstResponder()
!
83
    return true
!
84
  }
!
85
  
86
  func textFieldShouldClear(_ textField: UITextField) -> Bool {
!
87
    callback?((self.titleLabel.text!, ""))
!
88
    return true
!
89
  }
!
90
  
91
  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
!
92
    if textField.textContentType == .telephoneNumber {
!
93
      guard let text = textField.text as NSString? else { return true }
!
94
      let newText = text.replacingCharacters(in: range, with: string)
!
95
      
!
96
      let maskTextField = textField as! JMMaskTextField
!
97
      maskTextField.maskString = "(00) 00000-0000"
!
98
      guard let unmaskedText = maskTextField.stringMask?.unmask(string: newText) else { return true }
!
99
      maskTextField.text = unmaskedText
!
100
      if unmaskedText.count >= 11 {
!
101
        maskTextField.maskString = "(00) 00000-0000"
!
102
        _ = textFieldShouldReturn(textField)
!
103
      } else {
!
104
        maskTextField.maskString = "(00) 0000-0000"
!
105
      }
!
106
      
!
107
      textFieldDidChange(maskTextField)
!
108
    }
!
109
    return true
!
110
  }
!
111
}
+
+ + + diff --git a/TesteiOS/coverage/TextTableViewCell.swift.html b/TesteiOS/coverage/TextTableViewCell.swift.html new file mode 100644 index 00000000..630eb93a --- /dev/null +++ b/TesteiOS/coverage/TextTableViewCell.swift.html @@ -0,0 +1,137 @@ + + + +TextTableViewCell.swift - Slather + + + +
Slather logo
+

+Coverage for "TextTableViewCell.swift" : 100.00% +

+

(7 of 7 relevant lines covered)

+

TesteiOS/UI/Cells/Contact/TextTableViewCell/TextTableViewCell.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  TextTableViewCell.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 22/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
final class TextTableViewCell: ContactBaseTableViewCell {
12
13
  @IBOutlet weak var messageLabel: UILabel!
14
15
  override func awakeFromNib() {
1x
16
      super.awakeFromNib()
1x
17
  }
1x
18
  
19
  override func setup(with item: Cell) {
1x
20
    super.setup(with: item)
1x
21
    messageLabel.text = item.message
1x
22
  }
1x
23
}
+
+ + + diff --git a/TesteiOS/coverage/UIColor+Hex.swift.html b/TesteiOS/coverage/UIColor+Hex.swift.html new file mode 100644 index 00000000..623bbf73 --- /dev/null +++ b/TesteiOS/coverage/UIColor+Hex.swift.html @@ -0,0 +1,197 @@ + + + +UIColor+Hex.swift - Slather + + + +
Slather logo
+

+Coverage for "UIColor+Hex.swift" : 86.36% +

+

(19 of 22 relevant lines covered)

+

TesteiOS/Supporting Files/Extensions/UIColor+Hex.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  UIColor+Hex.swift
3
//  Movs
4
//
5
//  Created by Brendoon Ryos on 25/01/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import UIKit
10
11
extension UIColor {
12
  static func rgb(red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor {
!
13
    return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: 1)
!
14
  }
!
15
  
16
  public convenience init(hex: String, alpha: CGFloat = 1) {
8x
17
    let scanner = Scanner(string: hex)
8x
18
    scanner.scanLocation = 0
8x
19
    
8x
20
    var rgbValue: UInt64 = 0
8x
21
    
8x
22
    scanner.scanHexInt64(&rgbValue)
8x
23
    
8x
24
    let r = (rgbValue & 0xff0000) >> 16
8x
25
    let g = (rgbValue & 0xff00) >> 8
8x
26
    let b = rgbValue & 0xff
8x
27
    
8x
28
    self.init(
8x
29
      red: CGFloat(r) / 0xff,
8x
30
      green: CGFloat(g) / 0xff,
8x
31
      blue: CGFloat(b) / 0xff,
8x
32
      alpha: alpha
8x
33
    )
8x
34
  }
8x
35
}
+
+ + + diff --git a/TesteiOS/coverage/ViewCode.swift.html b/TesteiOS/coverage/ViewCode.swift.html new file mode 100644 index 00000000..61c857bf --- /dev/null +++ b/TesteiOS/coverage/ViewCode.swift.html @@ -0,0 +1,152 @@ + + + +ViewCode.swift - Slather + + + +
Slather logo
+

+Coverage for "ViewCode.swift" : 100.00% +

+

(6 of 6 relevant lines covered)

+

TesteiOS/UI/Views/ViewCode.swift

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1
//
2
//  ViewCode.swift
3
//  TesteiOS
4
//
5
//  Created by Brendoon Ryos on 21/02/19.
6
//  Copyright © 2019 Brendoon Ryos. All rights reserved.
7
//
8
9
import Foundation
10
11
protocol ViewCode: class {
12
  func setupConstraints()
13
  func buildViewHierarchy()
14
  func setupViewCode()
15
  func configureViews()
16
}
17
18
extension ViewCode {
19
  func setupViewCode() {
6x
20
    buildViewHierarchy()
6x
21
    setupConstraints()
6x
22
    configureViews()
6x
23
  }
6x
24
  
25
  func configureViews() {}
4x
26
}
+
+ + + diff --git a/TesteiOS/coverage/highlight.pack.js b/TesteiOS/coverage/highlight.pack.js new file mode 100644 index 00000000..1fbbace2 --- /dev/null +++ b/TesteiOS/coverage/highlight.pack.js @@ -0,0 +1 @@ +!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/no-?highlight|plain|text/.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){f+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(B);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(B);r;){e+=n(B.substr(t,r.index-t));var a=g(L,r);a?(y+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(B)}return e+n(B.substr(t))}function d(){if(L.sL&&!x[L.sL])return n(B);var e=L.sL?f(L.sL,B,!0,M[L.sL]):l(B);return L.r>0&&(y+=e.r),"continuous"==L.subLanguageMode&&(M[L.sL]=e.top),h(e.language,e.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,B=""):e.eB?(k+=n(t)+r,B=""):(k+=r,B=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(B+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(B+=t),k+=b();do L.cN&&(k+=""),y+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),B="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"")+'"');return B+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,L=i||N,M={},k="";for(R=L;R!=N;R=R.parent)R.cN&&(k=h(R.cN,"",!0)+k);var B="",y=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+="");return{r:y,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||w.languages||Object.keys(x);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,w.tabReplace)})),w.useBR&&(e=e.replace(/\n/g,"
")),e}function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;w.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){w=o(w,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(x)}function E(e){return x[e]||x[R[e]]}var w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},x={},R={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="\\b(0[xX][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",bK:"TODO FIXME NOTE BUG XXX",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:i,l:o,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"[a-z\\d_]*_t"},r={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","cc","h","c++","h++","hpp"],k:r,i:""]',k:"include",i:"\\n"},t.CLCM]},{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:r,c:["self",e]},{b:t.IR+"::",k:r},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"\\s+)+"+t.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:t.IR+"\\s*\\(",rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[t.CBCM]},t.CLCM,t.CBCM]}]}}); \ No newline at end of file diff --git a/TesteiOS/coverage/index.html b/TesteiOS/coverage/index.html new file mode 100644 index 00000000..d7650040 --- /dev/null +++ b/TesteiOS/coverage/index.html @@ -0,0 +1,447 @@ + + + +TesteiOS.xcodeproj - Slather + + + +
Slather logo
+

Files for "TesteiOS.xcodeproj"

+

+Total Coverage : 67.22% +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
%FileLinesRelevantCoveredMissed
85.71ItemsTableViewDataSource.swift32761
72.41TabBarViewController.swift4829218
60.91Cell.swift1701106743
100.00FormData.swift25550
100.00Fund.swift5113130
100.00FundsData.swift24440
100.00Info.swift29550
100.00MoreInfo.swift27550
100.00MoreInfoData.swift30660
80.39ContactDataSource.swift81514110
41.67ContactDelegate.swift311257
90.00ContactInteractor.swift5320182
50.00ContactModels.swift48844
0.00ContactPresenter.swift4112012
28.81ContactViewController.swift103591742
100.00ContactWorker.swift29880
97.67FundsDataSource.swift7143421
100.00FundsDelegate.swift26880
90.00FundsInteractor.swift5320182
100.00FundsModels.swift46880
33.33FundsPresenter.swift411248
0.00FundsRouter.swift44808
68.42FundsViewController.swift101573918
100.00FundsWorker.swift29880
87.50BankAPI+Testing.swift25871
92.50BankAPI.swift6340373
100.00DefaultAlamofireManager.swift20880
43.33NetworkManager.swift60301317
100.00AppDelegate.swift4021210
100.00String+Validator.swift6854540
86.36UIColor+Hex.swift3522193
90.00AppearanceProxyHelper.swift241091
0.00CheckboxTableViewCell.swift3922022
87.50ContactBaseTableViewCell.swift29871
0.00SendTableViewCell.swift4224024
0.00TextFieldTableViewCell.swift11164064
100.00TextTableViewCell.swift23770
57.14DownInfoTableViewCell.swift26743
0.00FundBaseTableViewCell.swift16101
100.00FundHeaderTableViewCell.swift29880
100.00InfoTableViewCell.swift20440
0.00InvestTableViewCell.swift3317017
100.00MoreInfoTableViewCell.swift29990
44.44ContactTableView.swift3918810
85.45ContactView.swift7655478
44.44FeedbackView.swift22945
85.00FundsTableView.swift4220173
91.89FundsView.swift5637343
73.68RiskView.swift92574215
82.35TabBarButton.swift3217143
91.89TabBarView.swift5937343
100.00ViewCode.swift26660
+
+ + + diff --git a/TesteiOS/coverage/list.min.js b/TesteiOS/coverage/list.min.js new file mode 100644 index 00000000..8327aaf1 --- /dev/null +++ b/TesteiOS/coverage/list.min.js @@ -0,0 +1 @@ +var List=function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var r={};return e.m=t,e.c=r,e.i=function(t){return t},e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=11)}([function(t,e,r){function n(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}var i=r(4),s=/\s+/;Object.prototype.toString;t.exports=function(t){return new n(t)},n.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array(),r=i(e,t);return~r||e.push(t),this.el.className=e.join(" "),this},n.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=i(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},n.prototype.toggle=function(t,e){return this.list?("undefined"!=typeof e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):("undefined"!=typeof e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},n.prototype.array=function(){var t=this.el.getAttribute("class")||"",e=t.replace(/^\s+|\s+$/g,""),r=e.split(s);return""===r[0]&&r.shift(),r},n.prototype.has=n.prototype.contains=function(t){return this.list?this.list.contains(t):!!~i(this.array(),t)}},function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",i=window.removeEventListener?"removeEventListener":"detachEvent",s="addEventListener"!==n?"on":"",a=r(5);e.bind=function(t,e,r,i){t=a(t);for(var o=0;o0?setTimeout(function(){e(r,n,i)},1):(t.update(),n(i))};return e}},function(t,e){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,i=r.length;nv.page,a=new m(t[i],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,i=0,s=v.items.length;i-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r=v.i&&v.visibleItems.lengthe},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,i,s,a){return this.dottedLeft(t,e,r,n,i,s)||this.dottedRight(t,e,r,n,i,s,a)},dottedLeft:function(t,e,r,n,i,s){return e==r+1&&!this.innerWindow(e,i,s)&&!this.right(e,n)},dottedRight:function(t,e,r,n,i,s,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,i,s)&&!this.right(e,n))}},a=function(e,r,n){i.bind(e,"click",function(){t.show((r-1)*n+1,n)})};return function(r){var n=new s(t.listContainer.id,{listClass:r.paginationClass||"pagination",item:"
  • ",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});t.on("updated",function(){e(n,r)}),e(n,r)}}},function(t,e,r){t.exports=function(t){var e=r(2)(t),n=function(t){for(var e=t.childNodes,r=[],n=0,i=e.length;n0?setTimeout(function(){s(e,r)},1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=n(t.list),r=t.valueNames;t.indexAsync?s(e,r):i(e,r)}}},function(t,e){t.exports=function(t){var e,r,n,i,s={resetList:function(){t.i=1,t.templater.clear(),i=void 0},setOptions:function(t){2==t.length&&t[1]instanceof Array?r=t[1]:2==t.length&&"function"==typeof t[1]?(r=void 0,i=t[1]):3==t.length?(r=t[1],i=t[2]):r=void 0},setColumns:function(){0!==t.items.length&&void 0===r&&(r=void 0===t.searchColumns?s.toArray(t.items[0].values()):t.searchColumns)},setSearchString:function(e){e=t.utils.toString(e).toLowerCase(),e=e.replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"),n=e},toArray:function(t){var e=[];for(var r in t)e.push(r);return e}},a={list:function(){for(var e=0,r=t.items.length;e-1))},reset:function(){t.reset.search(),t.searched=!1}},o=function(e){return t.trigger("searchStart"),s.resetList(),s.setSearchString(e),s.setOptions(arguments),s.setColumns(),""===n?a.reset():(t.searched=!0,i?i(n,r):a.list()),t.update(),t.trigger("searchComplete"),t.visibleItems};return t.handlers.searchStart=t.handlers.searchStart||[],t.handlers.searchComplete=t.handlers.searchComplete||[],t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"keyup",function(e){var r=e.target||e.srcElement,n=""===r.value&&!t.searched;n||o(r.value)}),t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"input",function(t){var e=t.target||t.srcElement;""===e.value&&o("")}),o}},function(t,e){t.exports=function(t){var e={els:void 0,clear:function(){for(var r=0,n=e.els.length;r]/g.exec(e)){var s=document.createElement("tbody");return s.innerHTML=e,s.firstChild}if(e.indexOf("<")!==-1){var a=document.createElement("div");return a.innerHTML=e,a.firstChild}var o=document.getElementById(t.item);if(o)return o}},this.get=function(e,n){r.create(e);for(var i={},s=0,a=n.length;s=1;)t.list.removeChild(t.list.firstChild)},n()};t.exports=function(t){return new r(t)}},function(t,e){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,i=n.length,s=0;s=48&&t<=57}function i(t,e){for(var r=(t+="").length,i=(e+="").length,s=0,l=0;s32)return!1;var o=i,l=function(){var t,r={};for(t=0;t=p;b--){var w=l[t.charAt(b-1)];if(0===g?y[b]=(y[b+1]<<1|1)&w:y[b]=(y[b+1]<<1|1)&w|((v[b+1]|v[b])<<1|1)|v[b+1],y[b]&f){var x=n(g,b-1);if(x<=u){if(u=x,c=b-1,!(c>o))break;p=Math.max(1,2*o-c)}}}if(n(g+1,o)>u)break;v=y}return!(c<0)}}]); \ No newline at end of file diff --git a/TesteiOS/coverage/logo.jpg b/TesteiOS/coverage/logo.jpg new file mode 100644 index 00000000..74466044 Binary files /dev/null and b/TesteiOS/coverage/logo.jpg differ diff --git a/TesteiOS/coverage/slather.css b/TesteiOS/coverage/slather.css new file mode 100644 index 00000000..d09c0086 --- /dev/null +++ b/TesteiOS/coverage/slather.css @@ -0,0 +1,316 @@ +/* -------------------------------------------------------- +Slather stylesheet + +version: 0.1 +author: Ikhsan Assaat (@ixnixnixn) +----------------------------------------------------------*/ + +/* General */ +html { + position: relative; + min-height: 100%; +} +body { + font: 16px "Helvetica", sans-serif; + margin: 0 0 120px; + color: #333; +} +.row { margin: 0 2em; } + +/* Header */ +header { margin-top: 1em; } +header img { width: auto; height: 120px; } + +/* Coverage */ +#reports > h2 { margin-bottom: 0; } +#reports > h4 { margin-top: 5px; } +.percentage { + padding: 4px ; + font-weight: bold; +} +.cov_high { color: #67CF7C; } +.cov_medium { color: #F89404; } +.cov_low { color: #F86769; } +.cov_title { margin-bottom: 0; } +.cov_subtitle { margin-top: 0.2em; } +.cov_filepath { font-style: italic; } + +/* Index Table */ +table.coverage_list { + width: 90%; + min-width: 400px; +} +table.coverage_list th, +table.coverage_list td { + padding: .6em .5em; + text-align: left; +} +table.coverage_list th.col_num { width: 70px; } +table.coverage_list th.col_percent { width: 75px; } +table.coverage_list thead, tfoot { background: #FDCD9B; } +table.coverage_list tbody tr:hover { background: #FCF2E6; } +table.coverage_list tbody td { border-bottom: 1px solid #CCC; } +table.coverage_list td a { + color: #333; + text-decoration: none; + border-bottom: 1px dotted; +} +table.coverage_list td a:hover { + border-bottom: none; +} + +/* Source Code */ +table.source_code { + width: 100%; + max-width: 1200px; + min-width: 400px; + font-size: 13px; + border-spacing: 0; + background: #FCF2E6; + padding: 1.2em 1em; + margin-bottom: 2em; +} + +table.source_code td { + padding-bottom: 0.3em; +} +table.source_code tr.missed td { background-color: rgba(248, 103, 105, 0.2); } +table.source_code tr.covered td { background-color: rgba(103, 207, 124, 0.2); } +table.source_code td.num { + border-right: 1px rgba(0,0,0,0.1) solid; + text-align: right; + padding-right: 1em; + width: 30px; +} +table.source_code td.src { + border-left: 1px rgba(255,255,255,0.7) solid; + padding-left: 1em; +} +table.source_code td.src pre { + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + margin: 0; +} +table.source_code td.src pre code { font: 13px "Menlo", "Courier New"; } + +table.source_code td.coverage { + text-align: right; + padding-right: 0.5em; +} + +/* Footer */ +footer { + background-color: #67CDCF; + height: 80px; + + position: absolute; + left: 0; + bottom: 0; + width: 100%; + overflow:hidden; +} + +footer p, footer a { + color: #ffffff; + font-weight: bold; + text-align: center; +} + + +/* ---------------------------------------------------------- +Syntax Highlighting using highlight.js (https://highlightjs.org) +------------------------------------------------------------- */ +.hljs { + display: block; + overflow-x: auto; + -webkit-text-size-adjust: none; +} + +.hljs, +.hljs-subst, +.hljs-tag .hljs-title, +.nginx .hljs-title { + color: #333; +} + +.hljs-string, +.hljs-title, +.hljs-constant, +.hljs-parent, +.hljs-tag .hljs-value, +.hljs-rule .hljs-value, +.hljs-preprocessor, +.hljs-pragma, +.hljs-name, +.haml .hljs-symbol, +.ruby .hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.hljs-template_tag, +.django .hljs-variable, +.smalltalk .hljs-class, +.hljs-addition, +.hljs-flow, +.hljs-stream, +.bash .hljs-variable, +.pf .hljs-variable, +.apache .hljs-tag, +.apache .hljs-cbracket, +.tex .hljs-command, +.tex .hljs-special, +.erlang_repl .hljs-function_or_atom, +.asciidoc .hljs-header, +.markdown .hljs-header, +.coffeescript .hljs-attribute, +.tp .hljs-variable { + color: #D14F4F; +} + +.smartquote, +.hljs-comment, +.hljs-annotation, +.diff .hljs-header, +.hljs-chunk, +.asciidoc .hljs-blockquote, +.markdown .hljs-blockquote { + color: #888; +} + +.hljs-number, +.hljs-date, +.hljs-regexp, +.hljs-literal, +.hljs-hexcolor, +.smalltalk .hljs-symbol, +.smalltalk .hljs-char, +.go .hljs-constant, +.hljs-change, +.lasso .hljs-variable, +.makefile .hljs-variable, +.asciidoc .hljs-bullet, +.markdown .hljs-bullet, +.asciidoc .hljs-link_url, +.markdown .hljs-link_url { + color: #05A5A8; +} + +.hljs-label, +.ruby .hljs-string, +.hljs-decorator, +.hljs-filter .hljs-argument, +.hljs-localvars, +.hljs-array, +.hljs-attr_selector, +.hljs-important, +.hljs-pseudo, +.hljs-pi, +.haml .hljs-bullet, +.hljs-doctype, +.hljs-deletion, +.hljs-envvar, +.hljs-shebang, +.apache .hljs-sqbracket, +.nginx .hljs-built_in, +.tex .hljs-formula, +.erlang_repl .hljs-reserved, +.hljs-prompt, +.asciidoc .hljs-link_label, +.markdown .hljs-link_label, +.vhdl .hljs-attribute, +.clojure .hljs-attribute, +.asciidoc .hljs-attribute, +.lasso .hljs-attribute, +.coffeescript .hljs-property, +.hljs-phony { + color: #087599; +} + +.hljs-keyword, +.hljs-id, +.hljs-title, +.hljs-built_in, +.css .hljs-tag, +.hljs-doctag, +.smalltalk .hljs-class, +.hljs-winutils, +.bash .hljs-variable, +.pf .hljs-variable, +.apache .hljs-tag, +.hljs-type, +.hljs-typename, +.tex .hljs-command, +.asciidoc .hljs-strong, +.markdown .hljs-strong, +.hljs-request, +.hljs-status, +.tp .hljs-data, +.tp .hljs-io { + font-weight: bold; +} + +.asciidoc .hljs-emphasis, +.markdown .hljs-emphasis, +.tp .hljs-units { + font-style: italic; +} + +.nginx .hljs-built_in { + font-weight: normal; +} + +.coffeescript .javascript, +.javascript .xml, +.lasso .markup, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +} + +/* ------------------------------------------------------- +Sorting & Filtering with List.js (http://www.listjs.com/) +------------------------------------------------------- */ + +input.search { + border:solid 1px #ccc; + border-radius: 4px; + padding:7px; + margin-bottom:10px; + font-size: 12px; +} +input.search:focus { + outline:none; + border-color:#aaa; +} + +th.sort::-moz-selection { background:transparent; } +th.sort::selection { background:transparent; } +th.sort { cursor:pointer; } +th.sort:after { + content:''; + display:inline-block; + width: 0; + height: 0; + position: relative; + top: -3px; + right: -6px; + border-width:0 4px 4px; + border-style:solid; + border-color:#404040 transparent; + visibility:hidden; +} + th.sort:hover:after { visibility:visible; } + th.sort.desc:after, + th.sort.asc:after, + th.sort.asc:hover:after { + visibility:visible; + opacity:0.6; +} + th.sort.desc:after { + border-bottom:none; + border-width:4px 4px 0; +} diff --git a/TesteiOS/fastlane/Appfile b/TesteiOS/fastlane/Appfile new file mode 100644 index 00000000..18030630 --- /dev/null +++ b/TesteiOS/fastlane/Appfile @@ -0,0 +1,6 @@ +# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app +# apple_id("[[APPLE_ID]]") # Your Apple email address + + +# For more information about the Appfile, see: +# https://docs.fastlane.tools/advanced/#appfile diff --git a/TesteiOS/fastlane/Fastfile b/TesteiOS/fastlane/Fastfile new file mode 100644 index 00000000..a01e497a --- /dev/null +++ b/TesteiOS/fastlane/Fastfile @@ -0,0 +1,50 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +update_fastlane + +default_platform(:ios) + +platform :ios do + before_all do + # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..." + cocoapods + end + + desc "Push a new beta build to TestFlight" + lane :beta do + gym(scheme: "TesteiOS") # Build your app - more options available + pilot + end + + desc "Deploy a new version to the App Store" + lane :release do + # match(type: "appstore") + # snapshot + gym(scheme: "TesteiOS") # Build your app - more options available + deliver(force: true) + # frameit + end + + desc "Runs all the tests" + lane :test do + scan(scheme: "TesteiOS") + slather( + output_directory: "coverage", + workspace: "TesteiOS.xcworkspace", + scheme: "TesteiOS", + proj: "TesteiOS.xcodeproj", + html: true + ) + end +end diff --git a/TesteiOS/fastlane/README.md b/TesteiOS/fastlane/README.md new file mode 100644 index 00000000..20932363 --- /dev/null +++ b/TesteiOS/fastlane/README.md @@ -0,0 +1,39 @@ +fastlane documentation +================ +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +``` +xcode-select --install +``` + +Install _fastlane_ using +``` +[sudo] gem install fastlane -NV +``` +or alternatively using `brew cask install fastlane` + +# Available Actions +## iOS +### ios beta +``` +fastlane ios beta +``` +Push a new beta build to TestFlight +### ios release +``` +fastlane ios release +``` +Deploy a new version to the App Store +### ios test +``` +fastlane ios test +``` +Runs all the tests + +---- + +This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. +More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). diff --git a/TesteiOS/fastlane/report.xml b/TesteiOS/fastlane/report.xml new file mode 100644 index 00000000..45e739f4 --- /dev/null +++ b/TesteiOS/fastlane/report.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS/fastlane/test_output/report.html b/TesteiOS/fastlane/test_output/report.html new file mode 100644 index 00000000..0263fb56 --- /dev/null +++ b/TesteiOS/fastlane/test_output/report.html @@ -0,0 +1,419 @@ + + + + + Test Results | xcpretty + + + + +
    +
    +

    Test Results

    +
    +
    +
    +

    19 tests

    + +
    +
    + AllFailingPassing +
    +
    +
    +
    + + +
    +
    +

    TesteiOSTests.ContactDataSourceSpec

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +

    0.067s

    + +

    a_ContactDataSource__should_have_a_valid_dataSource

    + +

    0.014s

    + +

    a_ContactDataSource__should_have_the_expected_number_of_items

    + +

    0.002s

    + +

    a_ContactDataSource__should_show_only_the_not_hidden_cells

    + +

    0.002s

    + +

    a_ContactDataSource__should_have_be_able_to_update_items

    + +

    0.021s

    + +

    a_ContactDataSource__should_return_the_expected_cell

    + +

    0.003s

    + +

    a_ContactDataSource__should_have_be_able_to_update_values

    + +

    0.002s

    + +

    a_ContactDataSource__should_have_the_expected_number_of_values

    + +

    0.002s

    + +

    a_ContactDataSource__should_have_upadeted_the_value_data

    + +

    0.002s

    + +

    a_ContactDataSource__should_remove_the_value

    +
    +
    + + +
    +
    +

    TesteiOSTests.ContactInteractorSpec

    +
    +
    + + + + + + + + + +
    + +

    0.001s

    + +

    a_ContactInteractor__should_have_a_worker

    +
    +
    + + +
    +
    +

    TesteiOSTests.ContactWorkerSpec

    +
    +
    + + + + + + + + + + + + + + + + +
    + +

    0.004s

    + +

    a_ContactWorker__should_have_a_result_value

    + +

    0.001s

    + +

    a_ContactWorker__should_haven_t_a_error_

    +
    +
    + + +
    +
    +

    TesteiOSTests.FormDataSpec

    +
    +
    + + + + + + + + + +
    + +

    0.001s

    + +

    a_FormData__should_be_able_to_create_a_formData_from_json

    +
    +
    + + +
    +
    +

    TesteiOSTests.FundsInteractorSpec

    +
    +
    + + + + + + + + + + + + + + + + +
    + +

    0.001s

    + +

    a_ContactInteractor__should_have_a_worker

    + +

    0.001s

    + +

    a_ContactInteractor__should_have_an_url

    +
    +
    + + +
    +
    +

    TesteiOSTests.StringValidatorSpec

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + +

    0.008s

    + +

    the_String_Validator__should_be_able_to_check_if_it_s_an_valid_email

    + +

    0.003s

    + +

    the_String_Validator__should_be_able_to_check_if_it_s_an_valid_CPF

    + +

    0.003s

    + +

    the_String_Validator__should_be_able_to_check_if_it_s_an_valid_password

    +
    +
    + + +
    +
    +

    TesteiOSUITests.TesteiOSUITests

    +
    +
    + + + + + + + + + +
    + +

    5.570s

    + +

    testExample

    +
    +
    + +
    + + + diff --git a/TesteiOS/fastlane/test_output/report.junit b/TesteiOS/fastlane/test_output/report.junit new file mode 100644 index 00000000..b60485b0 --- /dev/null +++ b/TesteiOS/fastlane/test_output/report.junit @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file