diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bb2e7a9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +pods/ +*.xcworkspace +Podfile.lock diff --git a/Domain/Domain.h b/Domain/Domain.h new file mode 100644 index 00000000..e8317928 --- /dev/null +++ b/Domain/Domain.h @@ -0,0 +1,19 @@ +// +// Model.h +// Model +// +// Created by Erika de Almeida Segatto on 06/09/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +#import + +//! Project version number for Model. +FOUNDATION_EXPORT double ModelVersionNumber; + +//! Project version string for Model. +FOUNDATION_EXPORT const unsigned char ModelVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Domain/Info.plist b/Domain/Info.plist new file mode 100644 index 00000000..1007fd9d --- /dev/null +++ b/Domain/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Domain/Model/CellType.swift b/Domain/Model/CellType.swift new file mode 100644 index 00000000..75ed7a46 --- /dev/null +++ b/Domain/Model/CellType.swift @@ -0,0 +1,17 @@ +// +// CellType.swift +// Domain +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +public enum CellType: Int { + case field = 1 + case text = 2 + case image = 3 + case checkbox = 4 + case send = 5 +} diff --git a/Domain/Model/FieldType.swift b/Domain/Model/FieldType.swift new file mode 100644 index 00000000..87cf2326 --- /dev/null +++ b/Domain/Model/FieldType.swift @@ -0,0 +1,40 @@ +// +// FieldType.swift +// Domain +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +public enum FieldType: Int { + case text = 1 + case telNumber = 2 + case email = 3 + + static func get(_ type: String) -> FieldType? { + if let intType = type.asInt() { + return FieldType(rawValue: intType) + } + if type.uppercased() == "TEXT" { + return .text + } + if type.uppercased() == "TELNUMBER" { + return .telNumber + } + if type.uppercased() == "EMAIL" { + return .email + } + return .text + } + + public func isValid(_ text: String) -> Bool { + switch self { + case .email: return text.isValidEmail() + case .telNumber: return text.isValidPhone() + case .text: return (text.count >= 1) + } + } +} + diff --git a/Domain/Model/FormCell.swift b/Domain/Model/FormCell.swift new file mode 100644 index 00000000..8abf7246 --- /dev/null +++ b/Domain/Model/FormCell.swift @@ -0,0 +1,37 @@ +// +// FormCell.swift +// Domain +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + + +public class FormCell { + public let id: Int + public let cellType: CellType + public let fieldType: FieldType + public let message: String + public let topSpacing: Double + public let show: Int? + public let hidden: Bool + public let required: Bool + + public var input: Any? = nil + + public init(id: Int, cellType: Int, fieldType: String, message: String, topSpacing: Double, show: Int?, hidden: Bool, required: Bool) throws { + + guard let cellType = CellType(rawValue: cellType) else { throw DomainError.invalidCellType } + guard let fieldType = FieldType.get(fieldType) else { throw DomainError.invalidFieldType } + self.id = id + self.cellType = cellType + self.fieldType = fieldType + self.message = message + self.topSpacing = topSpacing + self.show = show + self.hidden = hidden + self.required = required + } +} diff --git a/Domain/Model/Fund.swift b/Domain/Model/Fund.swift new file mode 100644 index 00000000..2673a84e --- /dev/null +++ b/Domain/Model/Fund.swift @@ -0,0 +1,60 @@ +// +// Fund.swift +// Domain +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +public struct FundValueInfo { + public let month: (fund: Double, cdi: Double) + public let year: (fund: Double, cdi: Double) + public let twelveMonths: (fund: Double, cdi: Double) + + public init(monthFund: Double, monthCdi: Double, yearFund: Double, yearCdi: Double, twelveMonthsFund: Double, twelveMonthsCdi: Double) { + self.month = (monthFund, monthCdi) + self.year = (yearFund, yearCdi) + self.twelveMonths = (twelveMonthsFund, twelveMonthsCdi) + } +} + +public struct FundInfo { + public var name: String + public var data: String + + public init(name: String, data: String) { + self.name = name + self.data = data + } +} + + +public class Fund { + public let id: String + public let title: String + public let fundName: String + public let whatIs: String + public let definition: String + public let riskTitle: String + public let risk: Int + public let infoTitle: String + public let moreInfo: FundValueInfo + public let info: [FundInfo] + public let downInfo: [FundInfo] + + public init(id: String, title: String, fundName: String, whatIs: String, definition: String, riskTitle: String, risk: Int, infoTitle: String, monthFund: Double, monthCdi: Double, yearFund: Double, yearCdi: Double, twelveMonthsFund: Double, twelveMonthsCdi: Double, info: [FundInfo], downInfo: [FundInfo]) { + self.id = id + self.title = title + self.fundName = fundName + self.whatIs = whatIs + self.definition = definition + self.riskTitle = riskTitle + self.risk = risk + self.infoTitle = infoTitle + self.moreInfo = FundValueInfo(monthFund: monthFund, monthCdi: monthCdi, yearFund: yearFund, yearCdi: yearCdi, twelveMonthsFund: twelveMonthsFund, twelveMonthsCdi: twelveMonthsCdi) + self.info = info + self.downInfo = downInfo + } +} diff --git a/Domain/Number+ext.swift b/Domain/Number+ext.swift new file mode 100644 index 00000000..75e93077 --- /dev/null +++ b/Domain/Number+ext.swift @@ -0,0 +1,19 @@ +// +// Number+ext.swift +// Domain +// +// Created by Erika de Almeida Segatto on 26/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + + +extension Double { + public func formatAsPercentage() -> String { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + return (formatter.string(from: self as NSNumber) ?? String(format: "%.2f", self)) + "%" + } +} diff --git a/Domain/String+ext.swift b/Domain/String+ext.swift new file mode 100644 index 00000000..53f7f133 --- /dev/null +++ b/Domain/String+ext.swift @@ -0,0 +1,85 @@ +// +// String+ext.swift +// Platform +// +// Created by Erika Segatto on 19/03/18. +// Copyright © 2018 evologica. All rights reserved. +// + +import Foundation + +extension String { + + + func asInt() -> Int? { + if let number = self.asNumber() { + return Int(exactly: number) + } + return nil + } + + func asNumber() -> NSNumber? { + let numFormatter = NumberFormatter() + numFormatter.decimalSeparator = "." + if let number = numFormatter.number(from: self){ + return number + } + numFormatter.decimalSeparator = "," + return numFormatter.number(from: self) + } + + + // MARK: String Format + public func formatAsPhone() -> String { + let cleanString = String(self.formatAsNumeric().prefix(11)) + + switch cleanString.count { + case 11: return cleanString.applyMask(mask: "(**) *****-****") + default: return cleanString.applyMask(mask: "(**) ****-****") + } + } + + func formatAsNumeric() -> String { + return self.replacingOccurrences(of:"[^0-9]", with: "", options: .regularExpression) + } + + + private func applyMask(mask: String) -> String { + var result = "" + + var maskIndex = mask.startIndex + var selfIndex = self.startIndex + + while selfIndex.encodedOffset != self.endIndex.encodedOffset { + if mask[maskIndex] == "*" { + result.append(self[selfIndex]) + selfIndex = self.index(after: selfIndex) + } else { + result.append(mask[maskIndex]) + } + maskIndex = mask.index(after: maskIndex) + if maskIndex.encodedOffset == mask.endIndex.encodedOffset { + result.append(String(self.suffix(from: selfIndex))) + return result + } + } + + return result + } + + // MARK: is Valid + + func isValidEmail() -> Bool { + let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" + let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailFormat) + return emailPredicate.evaluate(with: self) + } + + func isValidPhone() -> Bool { + let formatedPhoneFormat = "\\([0-9]{2}\\) ?[0-9]{4,5}-[0-9]{4}" + let unformatedPhoneFormat = "[0-9]{10,11}" + let predicate = NSPredicate(format: "SELF MATCHES %@ OR SELF MATCHES %@", formatedPhoneFormat, unformatedPhoneFormat) + return predicate.evaluate(with: self) + } + +} diff --git a/Domain/UseCases/ApiUseCase.swift b/Domain/UseCases/ApiUseCase.swift new file mode 100644 index 00000000..32d76d53 --- /dev/null +++ b/Domain/UseCases/ApiUseCase.swift @@ -0,0 +1,17 @@ +// +// ApiUseCase.swift +// Domain +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import RxSwift + + +public protocol ApiUseCase { + func getFormFields() -> Observable<[FormCell]> + func getFundInfo() -> Observable + func sendForm(_ form: [FormCell]) -> Observable +} diff --git a/Domain/UseCases/DomainError.swift b/Domain/UseCases/DomainError.swift new file mode 100644 index 00000000..eba5b689 --- /dev/null +++ b/Domain/UseCases/DomainError.swift @@ -0,0 +1,26 @@ +// +// DomainError.swift +// Domain +// +// Created by Erika de Almeida Segatto on 10/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +public enum DomainError: Error { + case invalidCellType + case invalidFieldType +} + + +extension DomainError: LocalizedError { + public var errorDescription: String? { + switch self { + case .invalidCellType: + return "Cell Type not identified" + case .invalidFieldType: + return "Field Type not identified" + } + } +} diff --git a/Platform/Entities/RMUser.swift b/Platform/Entities/RMUser.swift new file mode 100644 index 00000000..5eb88b11 --- /dev/null +++ b/Platform/Entities/RMUser.swift @@ -0,0 +1,46 @@ +// +// RMUser.swift +// Platform +// +// Created by Erika de Almeida Segatto on 06/09/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import RealmSwift +import Realm +import Domain + +//final class RMUser: Object { +// @objc dynamic var id: String = "" +// @objc dynamic var name: String = "" +// @objc dynamic var dateOfBirth: Date? +// @objc dynamic var gender: String? +// +// // @objc dynamic var category: RMCategory? +// +// override static func primaryKey() -> String? { +// return "id" +// } +//} +// +//extension RMUser: DomainConvertibleType { +// func asDomain() -> User { +// return User(id: id, name: name, dateOfBirth: dateOfBirth, gender: gender) +// } +//} +// +//extension User: RealmRepresentable { +// internal var uid: String { +// return self.id +// } +// +// func asRealm() -> RMUser { +// return RMUser.build { object in +// object.id = id +// object.name = name +// object.dateOfBirth = dateOfBirth +// object.gender = gender +// } +// } +//} diff --git a/Platform/Info.plist b/Platform/Info.plist new file mode 100644 index 00000000..1007fd9d --- /dev/null +++ b/Platform/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Platform/Platform.h b/Platform/Platform.h new file mode 100644 index 00000000..194ef9f5 --- /dev/null +++ b/Platform/Platform.h @@ -0,0 +1,19 @@ +// +// Platform.h +// Platform +// +// Created by Erika de Almeida Segatto on 06/09/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +#import + +//! Project version number for Platform. +FOUNDATION_EXPORT double PlatformVersionNumber; + +//! Project version string for Platform. +FOUNDATION_EXPORT const unsigned char PlatformVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Platform/Repository/DomainConvertibleType.swift b/Platform/Repository/DomainConvertibleType.swift new file mode 100644 index 00000000..627103a3 --- /dev/null +++ b/Platform/Repository/DomainConvertibleType.swift @@ -0,0 +1,15 @@ +// +// DomainConvertibleType.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +protocol DomainConvertibleType { + associatedtype DomainType + + func asDomain() -> DomainType +} diff --git a/Platform/Repository/Observable+ext.swift b/Platform/Repository/Observable+ext.swift new file mode 100644 index 00000000..816e56e5 --- /dev/null +++ b/Platform/Repository/Observable+ext.swift @@ -0,0 +1,29 @@ +// +// Observable+ext.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import RxSwift + +extension Observable where Element: Sequence, Element.Iterator.Element: DomainConvertibleType { + typealias DomainType = Element.Iterator.Element.DomainType + + func mapToDomain() -> Observable<[DomainType]> { + return map { sequence -> [DomainType] in + return sequence.mapToDomain() + } + } +} + +extension Sequence where Iterator.Element: DomainConvertibleType { + typealias Element = Iterator.Element + func mapToDomain() -> [Element.DomainType] { + return map { + return $0.asDomain() + } + } +} diff --git a/Platform/Repository/Realm+ext.swift b/Platform/Repository/Realm+ext.swift new file mode 100644 index 00000000..338b6508 --- /dev/null +++ b/Platform/Repository/Realm+ext.swift @@ -0,0 +1,61 @@ +// +// Realm+ext.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import Realm +import RealmSwift +import RxSwift + +extension Object { + static func build(_ builder: (O) -> () ) -> O { + let object = O() + builder(object) + return object + } +} + +extension SortDescriptor { + init(sortDescriptor: NSSortDescriptor) { + self.init(keyPath: sortDescriptor.key ?? "", ascending: sortDescriptor.ascending) + } +} + +extension Reactive where Base: Realm { + func save(entity: R, update: Bool = true) -> Observable where R.RealmType: Object { + return Observable.create { observer in + do { + try self.base.write { + self.base.add(entity.asRealm(), update: update) + } + observer.onNext(Void()) + observer.onCompleted() + } catch { + observer.onError(error) + } + return Disposables.create() + } + } + + func delete(entity: R) -> Observable where R.RealmType: Object { + return Observable.create { observer in + do { + guard let object = self.base.object(ofType: R.RealmType.self, forPrimaryKey: entity.uid) else { fatalError() } + + try self.base.write { + self.base.delete(object) + } + + observer.onNext(Void()) + observer.onCompleted() + } catch { + observer.onError(error) + } + return Disposables.create() + } + } +} diff --git a/Platform/Repository/RealmRepresentable.swift b/Platform/Repository/RealmRepresentable.swift new file mode 100644 index 00000000..b7ebea89 --- /dev/null +++ b/Platform/Repository/RealmRepresentable.swift @@ -0,0 +1,17 @@ +// +// RealmRepresentable.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +protocol RealmRepresentable { + associatedtype RealmType: DomainConvertibleType + + var uid: String {get} + + func asRealm() -> RealmType +} diff --git a/Platform/Repository/Repository.swift b/Platform/Repository/Repository.swift new file mode 100644 index 00000000..7d3161da --- /dev/null +++ b/Platform/Repository/Repository.swift @@ -0,0 +1,84 @@ +// +// Repository.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import Realm +import RealmSwift +import RxSwift +import RxRealm + +protocol AbstractRepository { + associatedtype T + func queryObject(id: String) -> T? + func countObject() -> Int + + func queryAll() -> Observable<[T]> + func query(with predicate: NSPredicate?, + sortDescriptors: [NSSortDescriptor]) -> Observable<[T]> + func save(entity: T) -> Observable + func delete(entity: T) -> Observable +} + +final class Repository: AbstractRepository where T == T.RealmType.DomainType, T.RealmType: Object { + private let configuration: Realm.Configuration + private let scheduler: RunLoopThreadScheduler + + private var realm: Realm { + return try! Realm(configuration: self.configuration) + } + + init(configuration: Realm.Configuration) { + self.configuration = configuration + let threadName = "com.todolist.realm.repository" + self.scheduler = RunLoopThreadScheduler(threadName: threadName) + } + + func queryObject(id: String) -> T? { + return self.realm.object(ofType: T.RealmType.self, forPrimaryKey: id)?.asDomain() + } + + func countObject() -> Int { + return self.realm.objects(T.RealmType.self).count + } + + func queryAll() -> Observable<[T]> { + return Observable.deferred { + let objects = self.realm.objects(T.RealmType.self) + return Observable.array(from: objects).mapToDomain() + } + .subscribeOn(scheduler) + .observeOn(MainScheduler.instance) + } + + func query(with predicate: NSPredicate?, + sortDescriptors: [NSSortDescriptor] = []) -> Observable<[T]> { + return Observable.deferred { + var objects = self.realm.objects(T.RealmType.self) + if let predicate = predicate { + objects = objects.filter(predicate) + } + let sortedObjects = objects.sorted(by: sortDescriptors.map(SortDescriptor.init)) + return Observable.array(from: sortedObjects).mapToDomain() + } + .subscribeOn(scheduler) + .observeOn(MainScheduler.instance) + } + + func save(entity: T) -> Observable { + return Observable.deferred { + return self.realm.rx.save(entity: entity) + }.subscribeOn(scheduler) + } + + func delete(entity: T) -> Observable { + return Observable.deferred { + return self.realm.rx.delete(entity: entity) + }.subscribeOn(scheduler) + } + +} diff --git a/Platform/Repository/RunLoopThreadScheduler.swift b/Platform/Repository/RunLoopThreadScheduler.swift new file mode 100644 index 00000000..f4db84c3 --- /dev/null +++ b/Platform/Repository/RunLoopThreadScheduler.swift @@ -0,0 +1,71 @@ +// +// File.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 17/02/18. +// Copyright © 2018 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import RxSwift + +final class RunLoopThreadScheduler: ImmediateSchedulerType { + private let thread: Thread + private let target: ThreadTarget + + init(threadName: String) { + self.target = ThreadTarget() + self.thread = Thread(target: target, + selector: #selector(ThreadTarget.threadEntryPoint), + object: nil) + self.thread.name = threadName + self.thread.start() + } + + func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { + let disposable = SingleAssignmentDisposable() + + var action: Action? = Action { + if disposable.isDisposed { + return + } + disposable.setDisposable(action(state)) + } + + action?.perform(#selector(Action.performAction), + on: thread, + with: nil, + waitUntilDone: false, + modes: [RunLoop.Mode.default.rawValue]) + + let actionDisposable = Disposables.create { + action = nil + } + + return Disposables.create(disposable, actionDisposable) + } + + deinit { + thread.cancel() + } +} + +private final class ThreadTarget: NSObject { + @objc fileprivate func threadEntryPoint() { + let runLoop = RunLoop.current + runLoop.add(NSMachPort(), forMode: RunLoop.Mode.default) + runLoop.run() + } +} + +private final class Action: NSObject { + private let action: () -> () + + init(action: @escaping () -> ()) { + self.action = action + } + + @objc func performAction() { + action() + } +} diff --git a/Platform/UseCases/ApiUseCase.swift b/Platform/UseCases/ApiUseCase.swift new file mode 100644 index 00000000..0311ec21 --- /dev/null +++ b/Platform/UseCases/ApiUseCase.swift @@ -0,0 +1,123 @@ +// +// ApiUseCase.swift +// ToDoList1.1 +// +// Created by Erika de Almeida Segatto on 03/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import Domain +import RxSwift +import RxAlamofire + +struct APIConstants { + static let baseURL = "https://floating-mountain-50292.herokuapp.com/" + + static let getCells = "cells.json" + static let getFund = "fund.json" +} + +final class ApiUseCaseImplementation: ApiUseCase { + static let instance = ApiUseCaseImplementation() + private init() { + } + + public static func getUseCase() -> ApiUseCase { + return instance + } + + + // MARK: API Function + public func getFormFields() -> Observable<[FormCell]> { + let urlString = APIConstants.baseURL + APIConstants.getCells + + return RxAlamofire.json(.get, urlString) + .map({ (response) -> [FormCell] in + print("URL success: \(urlString)") + var result = [FormCell]() + guard let json = response as? [String: Any] else { throw UseCaseError.invalidField("", response) } + guard let cells = json["cells"] as? [[String: Any]] else { throw UseCaseError.invalidField("cells", json) } + + for cell in cells { + guard let id = cell["id"] as? Int else { throw UseCaseError.invalidAttribute("id", cell["id"]) } + guard let type = cell["type"] as? Int else { throw UseCaseError.invalidAttribute("type", cell["type"]) } + guard let message = cell["message"] as? String else { throw UseCaseError.invalidAttribute("message", cell["message"]) } + guard let topSpacing = cell["topSpacing"] as? Double else { throw UseCaseError.invalidAttribute("topSpacing", cell["topSpacing"]) } + guard let hidden = cell["hidden"] as? Bool else { throw UseCaseError.invalidAttribute("hidden", cell["hidden"]) } + guard let required = cell["required"] as? Bool else { throw UseCaseError.invalidAttribute("required", cell["required"]) } + var fieldType = "" + if let fieldTypeInt = cell["typefield"] as? Int { + fieldType = String(fieldTypeInt) + } else { + fieldType = cell["typefield"] as? String ?? "" + } + let show = cell["show"] as? Int + + let formcell = try FormCell(id: id, cellType: type, fieldType: fieldType, message: message, topSpacing: topSpacing, show: show, hidden: hidden, required: required) + result.append(formcell) + } + return result + }) + .subscribeOn(ConcurrentMainScheduler.instance) + .observeOn(MainScheduler.instance) + } + + public func getFundInfo() -> Observable { + let urlString = APIConstants.baseURL + APIConstants.getFund + + return RxAlamofire.json(.get, urlString) + .map({ (response) -> Fund in + print("URL success: \(urlString)") + guard let json = response as? [String: Any] else { throw UseCaseError.invalidField("", response) } + guard let fund = json["screen"] as? [String: Any] else { throw UseCaseError.invalidField("screen", json) } + + // fund attributes + guard let title = fund["title"] as? String else { throw UseCaseError.invalidAttribute("title", fund) } + guard let fundName = fund["fundName"] as? String else { throw UseCaseError.invalidAttribute("fundName", fund) } + guard let whatIs = fund["whatIs"] as? String else { throw UseCaseError.invalidAttribute("whatIs", fund) } + guard let definition = fund["definition"] as? String else { throw UseCaseError.invalidAttribute("definition", fund) } + guard let riskTitle = fund["riskTitle"] as? String else { throw UseCaseError.invalidAttribute("riskTitle", fund) } + guard let risk = fund["risk"] as? Int else { throw UseCaseError.invalidAttribute("risk", fund) } + guard let infoTitle = fund["infoTitle"] as? String else { throw UseCaseError.invalidAttribute("infoTitle", fund) } + + // moreInfo + guard let moreInfo = fund["moreInfo"] as? [String: [String: Any?]] else { throw UseCaseError.invalidField("moreInfo", fund) } + guard let monthFund = moreInfo["month"]?["fund"] as? Double else { throw UseCaseError.invalidAttribute("month.fund", moreInfo) } + guard let monthCdi = moreInfo["month"]?["CDI"] as? Double else { throw UseCaseError.invalidAttribute("month.cdi", moreInfo) } + guard let yearFund = moreInfo["year"]?["fund"] as? Double else { throw UseCaseError.invalidAttribute("year.fund", moreInfo) } + guard let yearCdi = moreInfo["year"]?["CDI"] as? Double else { throw UseCaseError.invalidAttribute("year.cdi", moreInfo) } + guard let twelveMonthsFund = moreInfo["12months"]?["fund"] as? Double else { throw UseCaseError.invalidAttribute("12months.fund", moreInfo) } + guard let twelveMonthsCdi = moreInfo["12months"]?["CDI"] as? Double else { throw UseCaseError.invalidAttribute("12months.cdi", moreInfo) } + + // info + var fundInfo = [FundInfo]() + guard let infoList = fund["info"] as? [[String: Any?]] else { throw UseCaseError.invalidField("info", fund) } + for info in infoList { + guard let name = info["name"] as? String else { throw UseCaseError.invalidAttribute("name", info) } + let data = (info["data"] as? String) ?? "" + fundInfo.append(FundInfo(name: name, data: data)) + } + + // downInfo + var fundDownInfo = [FundInfo]() + guard let downInfoList = fund["downInfo"] as? [[String: Any?]] else { throw UseCaseError.invalidField("downInfo", fund) } + for downInfo in downInfoList { + guard let name = downInfo["name"] as? String else { throw UseCaseError.invalidAttribute("name", downInfo) } + let data = (downInfo["data"] as? String) ?? "Baixar" + fundDownInfo.append(FundInfo(name: name, data: data)) + } + + return Fund(id: "1", title: title, fundName: fundName, whatIs: whatIs, definition: definition, riskTitle: riskTitle, risk: risk, infoTitle: infoTitle, monthFund: monthFund, monthCdi: monthCdi, yearFund: yearFund, yearCdi: yearCdi, twelveMonthsFund: twelveMonthsFund, twelveMonthsCdi: twelveMonthsCdi, info: fundInfo, downInfo: fundDownInfo) + }) + .subscribeOn(ConcurrentMainScheduler.instance) + .observeOn(MainScheduler.instance) + } + + + func sendForm(_ form: [FormCell]) -> Observable { + return Observable.just(Void()) + .subscribeOn(ConcurrentMainScheduler.instance) + .observeOn(MainScheduler.instance) + } +} diff --git a/Platform/UseCases/UseCaseError.swift b/Platform/UseCases/UseCaseError.swift new file mode 100644 index 00000000..7918539d --- /dev/null +++ b/Platform/UseCases/UseCaseError.swift @@ -0,0 +1,25 @@ +// +// UseCaseError.swift +// Platform +// +// Created by Erika de Almeida Segatto on 10/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation + +enum UseCaseError: Error { + case invalidField(String, Any?) + case invalidAttribute(String, Any?) +} + +extension UseCaseError: LocalizedError { + public var errorDescription: String? { + switch self { + case .invalidField(let fieldname, let json): + return "invalid field '\(fieldname)' in json \(String(describing: json))" + case .invalidAttribute(let fieldname, let json): + return "invalid field '\(fieldname)' in json \(String(describing: json))" + } + } +} diff --git a/Platform/UseCases/UseCaseManager.swift b/Platform/UseCases/UseCaseManager.swift new file mode 100644 index 00000000..b2b28f6b --- /dev/null +++ b/Platform/UseCases/UseCaseManager.swift @@ -0,0 +1,16 @@ +// +// UseCaseManager.swift +// TesteiOS +// +// Created by Erika de Almeida Segatto on 10/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import Foundation +import Domain + +public struct UseCaseManager { + public static func getApiUseCase() -> ApiUseCase { + return ApiUseCaseImplementation.getUseCase() + } +} diff --git a/Podfile b/Podfile new file mode 100644 index 00000000..0af06026 --- /dev/null +++ b/Podfile @@ -0,0 +1,44 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' +use_frameworks! + + +def shared_pods + pod 'RxSwift', '~> 4.3' +end + +target 'TesteiOS' do + + # UI + pod 'MaterialComponents/TextFields', '~> 84.0.0' + pod 'MaterialComponents/TextFields+Theming', '~> 84.0.0' + pod 'MaterialComponents/TextFields+TypographyThemer', '~> 84.0.0' + pod 'MaterialComponents/Buttons', '~> 84.0.0' + pod 'MaterialComponents/Buttons+Theming', '~> 84.0.0' + pod 'MaterialComponents/Tabs', '~> 84.0.0' + pod 'MaterialComponents/Tabs+Theming', '~> 84.0.0' + pod 'MaterialComponents/Tabs+TypographyThemer', '~> 84.0.0' + + # dependency injection + pod 'Swinject', '~> 2.6.2' + pod 'SwinjectStoryboard', '~> 2.2.0' +end + +target 'Domain' do + shared_pods +end + +target 'Platform' do + shared_pods + + # Database + pod 'RealmSwift', '~> 3.10.0' + pod 'RxRealm', '~> 0.7.5' + + # HTTP + pod 'RxAlamofire', '~> 4.4' +end + +target 'Tests' do + shared_pods +end diff --git a/README.md b/README.md index 73f60d6c..31440dc3 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,29 @@ -# Show me the code +# Santander Teste iOS -### # DESAFIO: +Link para o teste: https://github.com/InterviewTests/TesteiOS. +Empresa por qual estou me candidatando: Zup. -Em uma tela terá um formulário dinâmico com alguns campos predefinidos, conforme o arquivo JSON disponível no link ([https://floating-mountain-50292.herokuapp.com/cells.json](https://floating-mountain-50292.herokuapp.com/cells.json)) que deverá - ser consumido. Este formulário terá de ser desenhado e exibir uma tela de sucesso quando as informações preenchidas estiverem corretas. +## Requisitos -Na segunda tela terá o detalhe de um ativo financeiro. As informações devem ser consumidas através do link ([https://floating-mountain-50292.herokuapp.com/fund.json](https://floating-mountain-50292.herokuapp.com/fund.json)). +* XCode 10+ +* iOS 9 +* Swift 4.2 -O visual do aplicativo está em anexo no arquivo telas.png e em um arquivo do [Sketch](https://www.sketchapp.com) (30 dias grátis, caso não tenha a licença). +## Como executar o projeto -![Image](https://floating-mountain-50292.herokuapp.com/telas.png) +1) Faça o download do projeto; +2) Abra o terminal no diretório onde o projeto foi salvo; +3) Instale os pods através do comando `pod install`; +4) Abra o projeto `TesteiOS.xcworkspace` no XCode e execute =) +Obs: Para utilizar dados *mockados*, basta editar o *scheme* e acrescentar o argumento `TESTING`. -### # Avaliação +## Testes -Você será avaliado pela usabilidade, por respeitar o design e pela arquitetura do app. É esperado que você consiga explicar as decisões que tomou durante o desenvolvimento através de commits. +Os testes realizados foram: +* Validação dos campos *email*, *telNumber* e *text* +* Testes unitários da *FormViewPresenter* +* Testes unitários da *FundViewPresenter* -* Swift 3.0 ou superior -* Autolayout -* O app deve funcionar no iOS 9 -* Testes unitários (De preferência XCTest). Mas pode usar o que você tem mais experiência, só nos explique o que ele tem de bom. -* Arquitetura a ser utilizada: Swift Clean ([https://clean-swift.com/handbook/](https://clean-swift.com/handbook/) && [https://github.com/Clean-Swift/CleanStore](https://github.com/Clean-Swift/CleanStore) && [https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)). -* Uso do git. +Obs: Os testes já estão configurados para utilizar os dados *mockados*. -### # Dicas para o layout - -* O formulário deve respeitar o conteúdo do cells.json ([https://floating-mountain-50292.herokuapp.com/cells.json](https://floating-mountain-50292.herokuapp.com/cells.json)) . -* Se o texto estiver muito grande, quebre em linhas e exiba por completo. -* O sketch está na proporção do iPhone 6, para iPhones menores/maiores é indicado que os espaçamentos se adaptem proporcionalmente. -* Na tela Fundos, o botão baixar irá abrir um SafariViewController no [google.com](http://google.com). -* A fonte a ser utilizada está em anexo no repositório. - -### # Como interpretar o cells.json: - -```Swift -Enum Type { - case field = 1, - case text = 2, - case image = 3, - case checkbox = 4, - case send = 5 -} -``` - -```Swift -Enum TypeField { - case text = 1, - case telNumber = 2, - case email = 3 -} -``` - -`"type":` tipo da célula; - -`"message":` mensagem que vai aparecer na label para type = text ou placeholder para field; - -`typeField":` tipo do field a ser exibido, para exibir corretamente a validação daquele campo. - -`hidden":` indica se o campo está visível; - -`topSpacing":` espaçamento entre o topo da célula e o topo da label/field/ checkbox; - -`show":` indica o campo que será exibido quando este campo for selecionado. No caso é o id do campo a ser exibido. - -`type":` "send" esse botão irá validar todas informações que foram preenchidas e ir para a tela de sucesso quando tudo tiver ok; - -`risk":` pode ser um int de 1 a 5 - -O tipo `text` a validação é digitou alguma coisa, já ficou válido.
-Para "telNumber" o campo deve ser formatado `(##) ####-#### || (##) #####-####` e validado de acordo.
-Para "email" o email deve ser válido. - -### # Observações gerais - -Adicione um arquivo [README.md](http://README.md) com os procedimentos para executar o projeto. -Pedimos que trabalhe sozinho e não divulgue o resultado na internet. - -Faça um fork desse desse repositório em seu Github e nos envie um Pull Request com o resultado, por favor informe por qual empresa você esta se candidatando. - -### # Importante: não há prazo de entrega, faça com qualidade! - -# BOA SORTE! diff --git a/TesteiOS.xcodeproj/project.pbxproj b/TesteiOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..26583f5c --- /dev/null +++ b/TesteiOS.xcodeproj/project.pbxproj @@ -0,0 +1,1351 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 304626AB2FB80E114C6FE78B /* Pods_Domain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6212F99226D89A14034E1293 /* Pods_Domain.framework */; }; + 305A8CFD0645AB77AAFF26EB /* Pods_TesteiOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A8920050411DDA82B21D7A55 /* Pods_TesteiOS.framework */; }; + 3F12294323117522009F8DD2 /* FundViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F12294223117522009F8DD2 /* FundViewPresenter.swift */; }; + 3F1229462311791F009F8DD2 /* ButtonViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3F1229452311791F009F8DD2 /* ButtonViewCell.xib */; }; + 3F12294B23117A99009F8DD2 /* TextViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3F12294723117A99009F8DD2 /* TextViewCell.xib */; }; + 3F12294C23117A99009F8DD2 /* ImageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3F12294823117A99009F8DD2 /* ImageViewCell.xib */; }; + 3F12294D23117A99009F8DD2 /* FieldViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3F12294923117A99009F8DD2 /* FieldViewCell.xib */; }; + 3F12294E23117A99009F8DD2 /* CheckBoxViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3F12294A23117A99009F8DD2 /* CheckBoxViewCell.xib */; }; + 3F12295023117EC9009F8DD2 /* FormViewCellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F12294F23117EC9009F8DD2 /* FormViewCellProtocol.swift */; }; + 3F1229542311838F009F8DD2 /* SafariViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1229532311838F009F8DD2 /* SafariViewController.swift */; }; + 3F1229562311868E009F8DD2 /* MessageSentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1229552311868E009F8DD2 /* MessageSentViewController.swift */; }; + 3F1229582311A904009F8DD2 /* FundViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1229572311A904009F8DD2 /* FundViewCell.swift */; }; + 3F30230F22FF019300CD98AF /* DomainError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F30230E22FF019300CD98AF /* DomainError.swift */; }; + 3F30231322FF14B400CD98AF /* UseCaseError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F30231222FF14B400CD98AF /* UseCaseError.swift */; }; + 3F30231422FF386200CD98AF /* UseCaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F30231022FF13C500CD98AF /* UseCaseManager.swift */; }; + 3F3023162300564A00CD98AF /* MainTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3023152300564A00CD98AF /* MainTabViewController.swift */; }; + 3F302333230261BD00CD98AF /* DINPro-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232A230261BD00CD98AF /* DINPro-Black.otf */; }; + 3F302334230261BD00CD98AF /* DINMittelschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232B230261BD00CD98AF /* DINMittelschriftStd.otf */; }; + 3F302335230261BD00CD98AF /* DINPro-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232C230261BD00CD98AF /* DINPro-Light.otf */; }; + 3F302336230261BD00CD98AF /* DINPro-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232D230261BD00CD98AF /* DINPro-Medium.otf */; }; + 3F302337230261BD00CD98AF /* DINNeuzeitGroteskStd-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232E230261BD00CD98AF /* DINNeuzeitGroteskStd-Light.otf */; }; + 3F302338230261BD00CD98AF /* DINPro-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F30232F230261BD00CD98AF /* DINPro-Regular.otf */; }; + 3F302339230261BD00CD98AF /* DINPro-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F302330230261BD00CD98AF /* DINPro-Bold.otf */; }; + 3F30233A230261BD00CD98AF /* DINNeuzeitGroteskStd-BdCond.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F302331230261BD00CD98AF /* DINNeuzeitGroteskStd-BdCond.otf */; }; + 3F30233B230261BD00CD98AF /* DINEngschriftStd.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3F302332230261BD00CD98AF /* DINEngschriftStd.otf */; }; + 3F30233F23026BF500CD98AF /* FormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F30233E23026BF500CD98AF /* FormViewController.swift */; }; + 3F30234123026C1D00CD98AF /* FundViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F30234023026C1D00CD98AF /* FundViewController.swift */; }; + 3F302343230274F500CD98AF /* ButtonViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F302342230274F500CD98AF /* ButtonViewCell.swift */; }; + 3F34766D2141F2C100D7B4FC /* Domain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F34766B2141F2C100D7B4FC /* Domain.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3F3476702141F2C100D7B4FC /* Domain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F3476692141F2C100D7B4FC /* Domain.framework */; }; + 3F3476712141F2C100D7B4FC /* Domain.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F3476692141F2C100D7B4FC /* Domain.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 3F3476802141F3BD00D7B4FC /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F34767E2141F3BD00D7B4FC /* Platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3F3476832141F3BD00D7B4FC /* Platform.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F34767C2141F3BD00D7B4FC /* Platform.framework */; }; + 3F3476842141F3BD00D7B4FC /* Platform.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F34767C2141F3BD00D7B4FC /* Platform.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 3F34769D2141F4EC00D7B4FC /* RealmRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476932141F4EB00D7B4FC /* RealmRepresentable.swift */; }; + 3F34769E2141F4EC00D7B4FC /* Observable+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476942141F4EB00D7B4FC /* Observable+ext.swift */; }; + 3F34769F2141F4EC00D7B4FC /* RunLoopThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476952141F4EB00D7B4FC /* RunLoopThreadScheduler.swift */; }; + 3F3476A02141F4EC00D7B4FC /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476962141F4EB00D7B4FC /* Repository.swift */; }; + 3F3476A12141F4EC00D7B4FC /* DomainConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476972141F4EB00D7B4FC /* DomainConvertibleType.swift */; }; + 3F3476A22141F4EC00D7B4FC /* Realm+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476982141F4EB00D7B4FC /* Realm+ext.swift */; }; + 3F3476A52141F4EC00D7B4FC /* ApiUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F34769C2141F4EC00D7B4FC /* ApiUseCase.swift */; }; + 3F3476A72141F9D900D7B4FC /* Fund.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476A62141F9D900D7B4FC /* Fund.swift */; }; + 3F3476A92141FA6000D7B4FC /* RMUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3476A82141FA6000D7B4FC /* RMUser.swift */; }; + 3F41D0C722F60BA5008D21A0 /* ApiUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F41D0C622F60BA5008D21A0 /* ApiUseCase.swift */; }; + 3F41D0C922F610AE008D21A0 /* FormCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F41D0C822F610AE008D21A0 /* FormCell.swift */; }; + 3F41D0CB22F611C0008D21A0 /* CellType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F41D0CA22F611C0008D21A0 /* CellType.swift */; }; + 3F41D0CD22F611DE008D21A0 /* FieldType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F41D0CC22F611DE008D21A0 /* FieldType.swift */; }; + 3F4C82F5230E205E008F236C /* DomainValidationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4C82F4230E205E008F236C /* DomainValidationTest.swift */; }; + 3F8033AF2140B51A005DC4AF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033AE2140B51A005DC4AF /* AppDelegate.swift */; }; + 3F8033B92140B51C005DC4AF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3F8033B72140B51C005DC4AF /* LaunchScreen.storyboard */; }; + 3F8033D12140B570005DC4AF /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033CC2140B570005DC4AF /* ThemeManager.swift */; }; + 3F8033DB2140B5AA005DC4AF /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033D62140B5AA005DC4AF /* BasicView.swift */; }; + 3F8033DC2140B5AA005DC4AF /* UIColor+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033D72140B5AA005DC4AF /* UIColor+ext.swift */; }; + 3F8033DE2140B5AA005DC4AF /* BasicPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033D92140B5AA005DC4AF /* BasicPresenter.swift */; }; + 3F8033DF2140B5AA005DC4AF /* UIViewController+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033DA2140B5AA005DC4AF /* UIViewController+ext.swift */; }; + 3F8033E42140B6AD005DC4AF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3F8033E32140B6AD005DC4AF /* Main.storyboard */; }; + 3F922E3B23077DF900B5FCE8 /* FormViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E3A23077DF900B5FCE8 /* FormViewPresenter.swift */; }; + 3F922E3D23077FEF00B5FCE8 /* SwinjectStoryboard+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E3C23077FEF00B5FCE8 /* SwinjectStoryboard+Setup.swift */; }; + 3F922E4623082E5C00B5FCE8 /* ApiUseCaseMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E4523082E5C00B5FCE8 /* ApiUseCaseMock.swift */; }; + 3F922E4D230831B000B5FCE8 /* ApiUseCaseMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E4523082E5C00B5FCE8 /* ApiUseCaseMock.swift */; }; + 3F922E4F230971F200B5FCE8 /* FieldViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E4E230971F200B5FCE8 /* FieldViewCell.swift */; }; + 3F922E53230972A800B5FCE8 /* ImageViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E50230972A800B5FCE8 /* ImageViewCell.swift */; }; + 3F922E54230972A800B5FCE8 /* TextViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E51230972A800B5FCE8 /* TextViewCell.swift */; }; + 3F922E55230972A800B5FCE8 /* CheckBoxViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E52230972A800B5FCE8 /* CheckBoxViewCell.swift */; }; + 3F922E592309861D00B5FCE8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3F922E582309861D00B5FCE8 /* Assets.xcassets */; }; + 3F922E5D2309DB2F00B5FCE8 /* String+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8033CA2140B570005DC4AF /* String+ext.swift */; }; + 3F922E5F2309E14200B5FCE8 /* ViewError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F922E5E2309E14200B5FCE8 /* ViewError.swift */; }; + 3FD56E67230CBE0E0063D8A6 /* FormViewPresenterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD56E66230CBE0E0063D8A6 /* FormViewPresenterTest.swift */; }; + 3FD56E6A230CC1240063D8A6 /* FormViewControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD56E69230CC1240063D8A6 /* FormViewControllerMock.swift */; }; + 3FD56E6C230CC1D60063D8A6 /* BasicViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD56E6B230CC1D60063D8A6 /* BasicViewMock.swift */; }; + 3FD56E6E230CC8210063D8A6 /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD56E6D230CC8210063D8A6 /* TestError.swift */; }; + 3FD56E6F230CC89A0063D8A6 /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD56E6D230CC8210063D8A6 /* TestError.swift */; }; + 3FFEBAC22312EB67000878AF /* UIImage+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBAC12312EB67000878AF /* UIImage+ext.swift */; }; + 3FFEBAC42312FAAA000878AF /* FundInfoViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBAC32312FAAA000878AF /* FundInfoViewCell.swift */; }; + 3FFEBAC62312FD6B000878AF /* FundDownInfoViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBAC52312FD6B000878AF /* FundDownInfoViewCell.swift */; }; + 3FFEBAC82314BB36000878AF /* Number+ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBAC72314BB36000878AF /* Number+ext.swift */; }; + 3FFEBACA2314CF02000878AF /* FundViewPresenterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBAC92314CF02000878AF /* FundViewPresenterTest.swift */; }; + 3FFEBACE2314CF7D000878AF /* FundViewControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFEBACD2314CF7D000878AF /* FundViewControllerMock.swift */; }; + C4F36BDB131C132B33F04528 /* Pods_Platform.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 695D2E89CC14DF68B24B74FA /* Pods_Platform.framework */; }; + DD2C02BEB389DC4511213BB6 /* Pods_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B6E7C380C81BE9F76AB14 /* Pods_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3F34766E2141F2C100D7B4FC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3F8033A32140B51A005DC4AF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3F3476682141F2C100D7B4FC; + remoteInfo = Model; + }; + 3F3476812141F3BD00D7B4FC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3F8033A32140B51A005DC4AF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3F34767B2141F3BD00D7B4FC; + remoteInfo = Platform; + }; + 3F922E4823082E5C00B5FCE8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3F8033A32140B51A005DC4AF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3F8033AA2140B51A005DC4AF; + remoteInfo = TesteiOS; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 3F3476752141F2C100D7B4FC /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3F3476712141F2C100D7B4FC /* Domain.framework in Embed Frameworks */, + 3F3476842141F3BD00D7B4FC /* Platform.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 13CCDE1B42F562B40C6DB37B /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; + 1421F059DFB238FCB394B0AA /* Pods-Platform.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Platform.release.xcconfig"; path = "Pods/Target Support Files/Pods-Platform/Pods-Platform.release.xcconfig"; sourceTree = ""; }; + 2A0C839DD581C93AA270927F /* Pods-Domain.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Domain.release.xcconfig"; path = "Pods/Target Support Files/Pods-Domain/Pods-Domain.release.xcconfig"; sourceTree = ""; }; + 3F12294223117522009F8DD2 /* FundViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundViewPresenter.swift; sourceTree = ""; }; + 3F1229452311791F009F8DD2 /* ButtonViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ButtonViewCell.xib; sourceTree = ""; }; + 3F12294723117A99009F8DD2 /* TextViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextViewCell.xib; sourceTree = ""; }; + 3F12294823117A99009F8DD2 /* ImageViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ImageViewCell.xib; sourceTree = ""; }; + 3F12294923117A99009F8DD2 /* FieldViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FieldViewCell.xib; sourceTree = ""; }; + 3F12294A23117A99009F8DD2 /* CheckBoxViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CheckBoxViewCell.xib; sourceTree = ""; }; + 3F12294F23117EC9009F8DD2 /* FormViewCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormViewCellProtocol.swift; sourceTree = ""; }; + 3F1229532311838F009F8DD2 /* SafariViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariViewController.swift; sourceTree = ""; }; + 3F1229552311868E009F8DD2 /* MessageSentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageSentViewController.swift; sourceTree = ""; }; + 3F1229572311A904009F8DD2 /* FundViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundViewCell.swift; sourceTree = ""; }; + 3F30230E22FF019300CD98AF /* DomainError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainError.swift; sourceTree = ""; }; + 3F30231022FF13C500CD98AF /* UseCaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseCaseManager.swift; sourceTree = ""; }; + 3F30231222FF14B400CD98AF /* UseCaseError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UseCaseError.swift; sourceTree = ""; }; + 3F3023152300564A00CD98AF /* MainTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabViewController.swift; sourceTree = ""; }; + 3F30232A230261BD00CD98AF /* DINPro-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Black.otf"; sourceTree = ""; }; + 3F30232B230261BD00CD98AF /* DINMittelschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINMittelschriftStd.otf; sourceTree = ""; }; + 3F30232C230261BD00CD98AF /* DINPro-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Light.otf"; sourceTree = ""; }; + 3F30232D230261BD00CD98AF /* DINPro-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Medium.otf"; sourceTree = ""; }; + 3F30232E230261BD00CD98AF /* DINNeuzeitGroteskStd-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-Light.otf"; sourceTree = ""; }; + 3F30232F230261BD00CD98AF /* DINPro-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Regular.otf"; sourceTree = ""; }; + 3F302330230261BD00CD98AF /* DINPro-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINPro-Bold.otf"; sourceTree = ""; }; + 3F302331230261BD00CD98AF /* DINNeuzeitGroteskStd-BdCond.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "DINNeuzeitGroteskStd-BdCond.otf"; sourceTree = ""; }; + 3F302332230261BD00CD98AF /* DINEngschriftStd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = DINEngschriftStd.otf; sourceTree = ""; }; + 3F30233E23026BF500CD98AF /* FormViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormViewController.swift; sourceTree = ""; }; + 3F30234023026C1D00CD98AF /* FundViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundViewController.swift; sourceTree = ""; }; + 3F302342230274F500CD98AF /* ButtonViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonViewCell.swift; sourceTree = ""; }; + 3F3476692141F2C100D7B4FC /* Domain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Domain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F34766B2141F2C100D7B4FC /* Domain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Domain.h; sourceTree = ""; }; + 3F34766C2141F2C100D7B4FC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3F34767C2141F3BD00D7B4FC /* Platform.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Platform.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F34767E2141F3BD00D7B4FC /* Platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = ""; }; + 3F34767F2141F3BD00D7B4FC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3F3476932141F4EB00D7B4FC /* RealmRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmRepresentable.swift; sourceTree = ""; }; + 3F3476942141F4EB00D7B4FC /* Observable+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+ext.swift"; sourceTree = ""; }; + 3F3476952141F4EB00D7B4FC /* RunLoopThreadScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RunLoopThreadScheduler.swift; sourceTree = ""; }; + 3F3476962141F4EB00D7B4FC /* Repository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repository.swift; sourceTree = ""; }; + 3F3476972141F4EB00D7B4FC /* DomainConvertibleType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainConvertibleType.swift; sourceTree = ""; }; + 3F3476982141F4EB00D7B4FC /* Realm+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Realm+ext.swift"; sourceTree = ""; }; + 3F34769C2141F4EC00D7B4FC /* ApiUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiUseCase.swift; sourceTree = ""; }; + 3F3476A62141F9D900D7B4FC /* Fund.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fund.swift; sourceTree = ""; }; + 3F3476A82141FA6000D7B4FC /* RMUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RMUser.swift; sourceTree = ""; }; + 3F41D0C622F60BA5008D21A0 /* ApiUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiUseCase.swift; sourceTree = ""; }; + 3F41D0C822F610AE008D21A0 /* FormCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormCell.swift; sourceTree = ""; }; + 3F41D0CA22F611C0008D21A0 /* CellType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellType.swift; sourceTree = ""; }; + 3F41D0CC22F611DE008D21A0 /* FieldType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldType.swift; sourceTree = ""; }; + 3F4C82F4230E205E008F236C /* DomainValidationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainValidationTest.swift; sourceTree = ""; }; + 3F8033AB2140B51A005DC4AF /* TesteiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TesteiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F8033AE2140B51A005DC4AF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 3F8033B82140B51C005DC4AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 3F8033BA2140B51C005DC4AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3F8033CA2140B570005DC4AF /* String+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+ext.swift"; sourceTree = ""; }; + 3F8033CC2140B570005DC4AF /* ThemeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = ""; }; + 3F8033D62140B5AA005DC4AF /* BasicView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicView.swift; sourceTree = ""; }; + 3F8033D72140B5AA005DC4AF /* UIColor+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+ext.swift"; sourceTree = ""; }; + 3F8033D92140B5AA005DC4AF /* BasicPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicPresenter.swift; sourceTree = ""; }; + 3F8033DA2140B5AA005DC4AF /* UIViewController+ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+ext.swift"; sourceTree = ""; }; + 3F8033E32140B6AD005DC4AF /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + 3F922E3A23077DF900B5FCE8 /* FormViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormViewPresenter.swift; sourceTree = ""; }; + 3F922E3C23077FEF00B5FCE8 /* SwinjectStoryboard+Setup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwinjectStoryboard+Setup.swift"; sourceTree = ""; }; + 3F922E4323082E5C00B5FCE8 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F922E4523082E5C00B5FCE8 /* ApiUseCaseMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiUseCaseMock.swift; sourceTree = ""; }; + 3F922E4723082E5C00B5FCE8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3F922E4E230971F200B5FCE8 /* FieldViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldViewCell.swift; sourceTree = ""; }; + 3F922E50230972A800B5FCE8 /* ImageViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewCell.swift; sourceTree = ""; }; + 3F922E51230972A800B5FCE8 /* TextViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewCell.swift; sourceTree = ""; }; + 3F922E52230972A800B5FCE8 /* CheckBoxViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckBoxViewCell.swift; sourceTree = ""; }; + 3F922E582309861D00B5FCE8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3F922E5E2309E14200B5FCE8 /* ViewError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewError.swift; sourceTree = ""; }; + 3FD56E66230CBE0E0063D8A6 /* FormViewPresenterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormViewPresenterTest.swift; sourceTree = ""; }; + 3FD56E69230CC1240063D8A6 /* FormViewControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormViewControllerMock.swift; sourceTree = ""; }; + 3FD56E6B230CC1D60063D8A6 /* BasicViewMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicViewMock.swift; sourceTree = ""; }; + 3FD56E6D230CC8210063D8A6 /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = ""; }; + 3FFEBAC12312EB67000878AF /* UIImage+ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+ext.swift"; sourceTree = ""; }; + 3FFEBAC32312FAAA000878AF /* FundInfoViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundInfoViewCell.swift; sourceTree = ""; }; + 3FFEBAC52312FD6B000878AF /* FundDownInfoViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundDownInfoViewCell.swift; sourceTree = ""; }; + 3FFEBAC72314BB36000878AF /* Number+ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Number+ext.swift"; sourceTree = ""; }; + 3FFEBAC92314CF02000878AF /* FundViewPresenterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundViewPresenterTest.swift; sourceTree = ""; }; + 3FFEBACD2314CF7D000878AF /* FundViewControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FundViewControllerMock.swift; sourceTree = ""; }; + 45E0316D7F351C66A7EAABF7 /* Pods-MedMe.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MedMe.release.xcconfig"; path = "Pods/Target Support Files/Pods-MedMe/Pods-MedMe.release.xcconfig"; sourceTree = ""; }; + 474B6E7C380C81BE9F76AB14 /* Pods_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6212F99226D89A14034E1293 /* Pods_Domain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Domain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 695D2E89CC14DF68B24B74FA /* Pods_Platform.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Platform.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A02B31C55A998F2E17E8FE94 /* Pods-Platform.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Platform.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Platform/Pods-Platform.debug.xcconfig"; sourceTree = ""; }; + A62658915FEAF73834503E3C /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; + A8920050411DDA82B21D7A55 /* Pods_TesteiOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TesteiOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B3B851C15FCA593A3448B0E0 /* Pods-TesteiOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TesteiOS/Pods-TesteiOS.debug.xcconfig"; sourceTree = ""; }; + E4F3CD46F7BADEE9D064D980 /* Pods-Domain.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Domain.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Domain/Pods-Domain.debug.xcconfig"; sourceTree = ""; }; + E9A5A2CCD342D90E7E6500E1 /* Pods-TesteiOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TesteiOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-TesteiOS/Pods-TesteiOS.release.xcconfig"; sourceTree = ""; }; + EAF0E71B9C589BB8E798E076 /* Pods-MedMe.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MedMe.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MedMe/Pods-MedMe.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3F3476652141F2C100D7B4FC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 304626AB2FB80E114C6FE78B /* Pods_Domain.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F3476782141F3BD00D7B4FC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C4F36BDB131C132B33F04528 /* Pods_Platform.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F8033A82140B51A005DC4AF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F3476702141F2C100D7B4FC /* Domain.framework in Frameworks */, + 3F3476832141F3BD00D7B4FC /* Platform.framework in Frameworks */, + 305A8CFD0645AB77AAFF26EB /* Pods_TesteiOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F922E4023082E5C00B5FCE8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DD2C02BEB389DC4511213BB6 /* Pods_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3F122944231178F4009F8DD2 /* FormViewCells */ = { + isa = PBXGroup; + children = ( + 3F12294F23117EC9009F8DD2 /* FormViewCellProtocol.swift */, + 3F1229452311791F009F8DD2 /* ButtonViewCell.xib */, + 3F302342230274F500CD98AF /* ButtonViewCell.swift */, + 3F12294A23117A99009F8DD2 /* CheckBoxViewCell.xib */, + 3F922E52230972A800B5FCE8 /* CheckBoxViewCell.swift */, + 3F12294923117A99009F8DD2 /* FieldViewCell.xib */, + 3F922E4E230971F200B5FCE8 /* FieldViewCell.swift */, + 3F12294823117A99009F8DD2 /* ImageViewCell.xib */, + 3F922E50230972A800B5FCE8 /* ImageViewCell.swift */, + 3F12294723117A99009F8DD2 /* TextViewCell.xib */, + 3F922E51230972A800B5FCE8 /* TextViewCell.swift */, + ); + path = FormViewCells; + sourceTree = ""; + }; + 3F30230C22FF016400CD98AF /* Model */ = { + isa = PBXGroup; + children = ( + 3F3476A62141F9D900D7B4FC /* Fund.swift */, + 3F41D0C822F610AE008D21A0 /* FormCell.swift */, + 3F41D0CA22F611C0008D21A0 /* CellType.swift */, + 3F41D0CC22F611DE008D21A0 /* FieldType.swift */, + ); + path = Model; + sourceTree = ""; + }; + 3F30230D22FF017500CD98AF /* UseCases */ = { + isa = PBXGroup; + children = ( + 3F30230E22FF019300CD98AF /* DomainError.swift */, + 3F41D0C622F60BA5008D21A0 /* ApiUseCase.swift */, + ); + path = UseCases; + sourceTree = ""; + }; + 3F3023172302617A00CD98AF /* Fonts */ = { + isa = PBXGroup; + children = ( + 3F302332230261BD00CD98AF /* DINEngschriftStd.otf */, + 3F30232B230261BD00CD98AF /* DINMittelschriftStd.otf */, + 3F302331230261BD00CD98AF /* DINNeuzeitGroteskStd-BdCond.otf */, + 3F30232E230261BD00CD98AF /* DINNeuzeitGroteskStd-Light.otf */, + 3F30232A230261BD00CD98AF /* DINPro-Black.otf */, + 3F302330230261BD00CD98AF /* DINPro-Bold.otf */, + 3F30232C230261BD00CD98AF /* DINPro-Light.otf */, + 3F30232D230261BD00CD98AF /* DINPro-Medium.otf */, + 3F30232F230261BD00CD98AF /* DINPro-Regular.otf */, + ); + path = Fonts; + sourceTree = ""; + }; + 3F30233C23026B8900CD98AF /* FundView */ = { + isa = PBXGroup; + children = ( + 3F30234023026C1D00CD98AF /* FundViewController.swift */, + 3F12294223117522009F8DD2 /* FundViewPresenter.swift */, + 3F1229532311838F009F8DD2 /* SafariViewController.swift */, + 3F1229572311A904009F8DD2 /* FundViewCell.swift */, + 3FFEBAC32312FAAA000878AF /* FundInfoViewCell.swift */, + 3FFEBAC52312FD6B000878AF /* FundDownInfoViewCell.swift */, + ); + path = FundView; + sourceTree = ""; + }; + 3F30233D23026BA700CD98AF /* FormView */ = { + isa = PBXGroup; + children = ( + 3F30233E23026BF500CD98AF /* FormViewController.swift */, + 3F922E3A23077DF900B5FCE8 /* FormViewPresenter.swift */, + 3F1229552311868E009F8DD2 /* MessageSentViewController.swift */, + ); + path = FormView; + sourceTree = ""; + }; + 3F34766A2141F2C100D7B4FC /* Domain */ = { + isa = PBXGroup; + children = ( + 3F30230D22FF017500CD98AF /* UseCases */, + 3F30230C22FF016400CD98AF /* Model */, + 3F8033CA2140B570005DC4AF /* String+ext.swift */, + 3FFEBAC72314BB36000878AF /* Number+ext.swift */, + 3F34766B2141F2C100D7B4FC /* Domain.h */, + 3F34766C2141F2C100D7B4FC /* Info.plist */, + ); + path = Domain; + sourceTree = ""; + }; + 3F34767D2141F3BD00D7B4FC /* Platform */ = { + isa = PBXGroup; + children = ( + 3F3476922141F4EB00D7B4FC /* Repository */, + 3F3476992141F4EC00D7B4FC /* UseCases */, + 3F3476892141F4E100D7B4FC /* Entities */, + 3F34767E2141F3BD00D7B4FC /* Platform.h */, + 3F34767F2141F3BD00D7B4FC /* Info.plist */, + ); + path = Platform; + sourceTree = ""; + }; + 3F3476892141F4E100D7B4FC /* Entities */ = { + isa = PBXGroup; + children = ( + 3F3476A82141FA6000D7B4FC /* RMUser.swift */, + ); + path = Entities; + sourceTree = ""; + }; + 3F3476922141F4EB00D7B4FC /* Repository */ = { + isa = PBXGroup; + children = ( + 3F3476932141F4EB00D7B4FC /* RealmRepresentable.swift */, + 3F3476942141F4EB00D7B4FC /* Observable+ext.swift */, + 3F3476952141F4EB00D7B4FC /* RunLoopThreadScheduler.swift */, + 3F3476962141F4EB00D7B4FC /* Repository.swift */, + 3F3476972141F4EB00D7B4FC /* DomainConvertibleType.swift */, + 3F3476982141F4EB00D7B4FC /* Realm+ext.swift */, + ); + path = Repository; + sourceTree = ""; + }; + 3F3476992141F4EC00D7B4FC /* UseCases */ = { + isa = PBXGroup; + children = ( + 3F30231022FF13C500CD98AF /* UseCaseManager.swift */, + 3F34769C2141F4EC00D7B4FC /* ApiUseCase.swift */, + 3F30231222FF14B400CD98AF /* UseCaseError.swift */, + ); + path = UseCases; + sourceTree = ""; + }; + 3F3476AC2143012500D7B4FC /* MainTabView */ = { + isa = PBXGroup; + children = ( + 3F3023152300564A00CD98AF /* MainTabViewController.swift */, + ); + path = MainTabView; + sourceTree = ""; + }; + 3F8033A22140B51A005DC4AF = { + isa = PBXGroup; + children = ( + 3F8033AD2140B51A005DC4AF /* View */, + 3F34766A2141F2C100D7B4FC /* Domain */, + 3F34767D2141F3BD00D7B4FC /* Platform */, + 3F922E4423082E5C00B5FCE8 /* Tests */, + 3F8033AC2140B51A005DC4AF /* Products */, + B4588052C3CE91F2C0990281 /* Pods */, + EA0FE3DDD71CF76602716B8C /* Frameworks */, + ); + sourceTree = ""; + }; + 3F8033AC2140B51A005DC4AF /* Products */ = { + isa = PBXGroup; + children = ( + 3F8033AB2140B51A005DC4AF /* TesteiOS.app */, + 3F3476692141F2C100D7B4FC /* Domain.framework */, + 3F34767C2141F3BD00D7B4FC /* Platform.framework */, + 3F922E4323082E5C00B5FCE8 /* Tests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 3F8033AD2140B51A005DC4AF /* View */ = { + isa = PBXGroup; + children = ( + 3F8033E02140B5BC005DC4AF /* Extensions */, + 3F8033E12140B5CA005DC4AF /* Scenes */, + 3F8033D52140B57A005DC4AF /* Supporting Files */, + ); + path = View; + sourceTree = ""; + }; + 3F8033D52140B57A005DC4AF /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 3F3023172302617A00CD98AF /* Fonts */, + 3F8033B72140B51C005DC4AF /* LaunchScreen.storyboard */, + 3F922E582309861D00B5FCE8 /* Assets.xcassets */, + 3F8033AE2140B51A005DC4AF /* AppDelegate.swift */, + 3F8033BA2140B51C005DC4AF /* Info.plist */, + 3F8033CC2140B570005DC4AF /* ThemeManager.swift */, + 3F922E3C23077FEF00B5FCE8 /* SwinjectStoryboard+Setup.swift */, + ); + path = "Supporting Files"; + sourceTree = ""; + }; + 3F8033E02140B5BC005DC4AF /* Extensions */ = { + isa = PBXGroup; + children = ( + 3F8033D72140B5AA005DC4AF /* UIColor+ext.swift */, + 3F8033DA2140B5AA005DC4AF /* UIViewController+ext.swift */, + 3FFEBAC12312EB67000878AF /* UIImage+ext.swift */, + 3F922E5E2309E14200B5FCE8 /* ViewError.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 3F8033E12140B5CA005DC4AF /* Scenes */ = { + isa = PBXGroup; + children = ( + 3F8033E32140B6AD005DC4AF /* Main.storyboard */, + 3F8033E22140B639005DC4AF /* Basic */, + 3F122944231178F4009F8DD2 /* FormViewCells */, + 3F3476AC2143012500D7B4FC /* MainTabView */, + 3F30233C23026B8900CD98AF /* FundView */, + 3F30233D23026BA700CD98AF /* FormView */, + ); + path = Scenes; + sourceTree = ""; + }; + 3F8033E22140B639005DC4AF /* Basic */ = { + isa = PBXGroup; + children = ( + 3F8033D92140B5AA005DC4AF /* BasicPresenter.swift */, + 3F8033D62140B5AA005DC4AF /* BasicView.swift */, + ); + path = Basic; + sourceTree = ""; + }; + 3F922E4423082E5C00B5FCE8 /* Tests */ = { + isa = PBXGroup; + children = ( + 3FD56E68230CC08C0063D8A6 /* Helpers */, + 3FFEBAC92314CF02000878AF /* FundViewPresenterTest.swift */, + 3FD56E66230CBE0E0063D8A6 /* FormViewPresenterTest.swift */, + 3F4C82F4230E205E008F236C /* DomainValidationTest.swift */, + 3F922E4723082E5C00B5FCE8 /* Info.plist */, + ); + path = Tests; + sourceTree = ""; + }; + 3FD56E68230CC08C0063D8A6 /* Helpers */ = { + isa = PBXGroup; + children = ( + 3FD56E6D230CC8210063D8A6 /* TestError.swift */, + 3FFEBACC2314CF1E000878AF /* View */, + 3FFEBACB2314CF14000878AF /* UseCase */, + ); + path = Helpers; + sourceTree = ""; + }; + 3FFEBACB2314CF14000878AF /* UseCase */ = { + isa = PBXGroup; + children = ( + 3F922E4523082E5C00B5FCE8 /* ApiUseCaseMock.swift */, + ); + path = UseCase; + sourceTree = ""; + }; + 3FFEBACC2314CF1E000878AF /* View */ = { + isa = PBXGroup; + children = ( + 3FD56E6B230CC1D60063D8A6 /* BasicViewMock.swift */, + 3FFEBACD2314CF7D000878AF /* FundViewControllerMock.swift */, + 3FD56E69230CC1240063D8A6 /* FormViewControllerMock.swift */, + ); + path = View; + sourceTree = ""; + }; + B4588052C3CE91F2C0990281 /* Pods */ = { + isa = PBXGroup; + children = ( + E4F3CD46F7BADEE9D064D980 /* Pods-Domain.debug.xcconfig */, + 2A0C839DD581C93AA270927F /* Pods-Domain.release.xcconfig */, + EAF0E71B9C589BB8E798E076 /* Pods-MedMe.debug.xcconfig */, + 45E0316D7F351C66A7EAABF7 /* Pods-MedMe.release.xcconfig */, + A02B31C55A998F2E17E8FE94 /* Pods-Platform.debug.xcconfig */, + 1421F059DFB238FCB394B0AA /* Pods-Platform.release.xcconfig */, + B3B851C15FCA593A3448B0E0 /* Pods-TesteiOS.debug.xcconfig */, + E9A5A2CCD342D90E7E6500E1 /* Pods-TesteiOS.release.xcconfig */, + A62658915FEAF73834503E3C /* Pods-Tests.debug.xcconfig */, + 13CCDE1B42F562B40C6DB37B /* Pods-Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + EA0FE3DDD71CF76602716B8C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6212F99226D89A14034E1293 /* Pods_Domain.framework */, + 695D2E89CC14DF68B24B74FA /* Pods_Platform.framework */, + A8920050411DDA82B21D7A55 /* Pods_TesteiOS.framework */, + 474B6E7C380C81BE9F76AB14 /* Pods_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3F3476662141F2C100D7B4FC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F34766D2141F2C100D7B4FC /* Domain.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F3476792141F3BD00D7B4FC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F3476802141F3BD00D7B4FC /* Platform.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3F3476682141F2C100D7B4FC /* Domain */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3F3476742141F2C100D7B4FC /* Build configuration list for PBXNativeTarget "Domain" */; + buildPhases = ( + DC4CE964DB6787F3A71B9098 /* [CP] Check Pods Manifest.lock */, + 3F3476642141F2C100D7B4FC /* Sources */, + 3F3476652141F2C100D7B4FC /* Frameworks */, + 3F3476662141F2C100D7B4FC /* Headers */, + 3F3476672141F2C100D7B4FC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Domain; + productName = Model; + productReference = 3F3476692141F2C100D7B4FC /* Domain.framework */; + productType = "com.apple.product-type.framework"; + }; + 3F34767B2141F3BD00D7B4FC /* Platform */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3F3476852141F3BD00D7B4FC /* Build configuration list for PBXNativeTarget "Platform" */; + buildPhases = ( + A028D36200F26BB6461177AC /* [CP] Check Pods Manifest.lock */, + 3F3476772141F3BD00D7B4FC /* Sources */, + 3F3476782141F3BD00D7B4FC /* Frameworks */, + 3F3476792141F3BD00D7B4FC /* Headers */, + 3F34767A2141F3BD00D7B4FC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Platform; + productName = Platform; + productReference = 3F34767C2141F3BD00D7B4FC /* Platform.framework */; + productType = "com.apple.product-type.framework"; + }; + 3F8033AA2140B51A005DC4AF /* TesteiOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3F8033BD2140B51C005DC4AF /* Build configuration list for PBXNativeTarget "TesteiOS" */; + buildPhases = ( + B5A395C59E23218C54456302 /* [CP] Check Pods Manifest.lock */, + 3F8033A72140B51A005DC4AF /* Sources */, + 3F8033A82140B51A005DC4AF /* Frameworks */, + 3F8033A92140B51A005DC4AF /* Resources */, + 3F3476752141F2C100D7B4FC /* Embed Frameworks */, + 659C48B115F643A9162D420C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3F34766F2141F2C100D7B4FC /* PBXTargetDependency */, + 3F3476822141F3BD00D7B4FC /* PBXTargetDependency */, + ); + name = TesteiOS; + productName = MedMe; + productReference = 3F8033AB2140B51A005DC4AF /* TesteiOS.app */; + productType = "com.apple.product-type.application"; + }; + 3F922E4223082E5C00B5FCE8 /* Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3F922E4A23082E5C00B5FCE8 /* Build configuration list for PBXNativeTarget "Tests" */; + buildPhases = ( + DCCF06F493877FF6F30B73E0 /* [CP] Check Pods Manifest.lock */, + 3F922E3F23082E5C00B5FCE8 /* Sources */, + 3F922E4023082E5C00B5FCE8 /* Frameworks */, + 3F922E4123082E5C00B5FCE8 /* Resources */, + 8C542C3D249738F4C5E6F949 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3F922E4923082E5C00B5FCE8 /* PBXTargetDependency */, + ); + name = Tests; + productName = Tests; + productReference = 3F922E4323082E5C00B5FCE8 /* Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3F8033A32140B51A005DC4AF /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 0940; + ORGANIZATIONNAME = "Erika de Almeida Segatto"; + TargetAttributes = { + 3F3476682141F2C100D7B4FC = { + CreatedOnToolsVersion = 9.4.1; + LastSwiftMigration = 1010; + }; + 3F34767B2141F3BD00D7B4FC = { + CreatedOnToolsVersion = 9.4.1; + LastSwiftMigration = 1010; + }; + 3F8033AA2140B51A005DC4AF = { + CreatedOnToolsVersion = 9.4.1; + LastSwiftMigration = 1010; + }; + 3F922E4223082E5C00B5FCE8 = { + CreatedOnToolsVersion = 10.1; + TestTargetID = 3F8033AA2140B51A005DC4AF; + }; + }; + }; + buildConfigurationList = 3F8033A62140B51A005DC4AF /* Build configuration list for PBXProject "TesteiOS" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 3F8033A22140B51A005DC4AF; + productRefGroup = 3F8033AC2140B51A005DC4AF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3F8033AA2140B51A005DC4AF /* TesteiOS */, + 3F3476682141F2C100D7B4FC /* Domain */, + 3F34767B2141F3BD00D7B4FC /* Platform */, + 3F922E4223082E5C00B5FCE8 /* Tests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3F3476672141F2C100D7B4FC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F34767A2141F3BD00D7B4FC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F8033A92140B51A005DC4AF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F8033B92140B51C005DC4AF /* LaunchScreen.storyboard in Resources */, + 3F12294D23117A99009F8DD2 /* FieldViewCell.xib in Resources */, + 3F12294C23117A99009F8DD2 /* ImageViewCell.xib in Resources */, + 3F12294B23117A99009F8DD2 /* TextViewCell.xib in Resources */, + 3F30233A230261BD00CD98AF /* DINNeuzeitGroteskStd-BdCond.otf in Resources */, + 3F12294E23117A99009F8DD2 /* CheckBoxViewCell.xib in Resources */, + 3F302333230261BD00CD98AF /* DINPro-Black.otf in Resources */, + 3F302335230261BD00CD98AF /* DINPro-Light.otf in Resources */, + 3F302338230261BD00CD98AF /* DINPro-Regular.otf in Resources */, + 3F302339230261BD00CD98AF /* DINPro-Bold.otf in Resources */, + 3F30233B230261BD00CD98AF /* DINEngschriftStd.otf in Resources */, + 3F302337230261BD00CD98AF /* DINNeuzeitGroteskStd-Light.otf in Resources */, + 3F8033E42140B6AD005DC4AF /* Main.storyboard in Resources */, + 3F302334230261BD00CD98AF /* DINMittelschriftStd.otf in Resources */, + 3F1229462311791F009F8DD2 /* ButtonViewCell.xib in Resources */, + 3F922E592309861D00B5FCE8 /* Assets.xcassets in Resources */, + 3F302336230261BD00CD98AF /* DINPro-Medium.otf in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F922E4123082E5C00B5FCE8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 659C48B115F643A9162D420C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TesteiOS/Pods-TesteiOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TesteiOS/Pods-TesteiOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TesteiOS/Pods-TesteiOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8C542C3D249738F4C5E6F949 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Tests/Pods-Tests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Tests/Pods-Tests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A028D36200F26BB6461177AC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Platform-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; + }; + B5A395C59E23218C54456302 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + 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; + }; + DC4CE964DB6787F3A71B9098 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Domain-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; + }; + DCCF06F493877FF6F30B73E0 /* [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-Tests-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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3F3476642141F2C100D7B4FC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3FFEBAC82314BB36000878AF /* Number+ext.swift in Sources */, + 3F922E5D2309DB2F00B5FCE8 /* String+ext.swift in Sources */, + 3F41D0C722F60BA5008D21A0 /* ApiUseCase.swift in Sources */, + 3F41D0CD22F611DE008D21A0 /* FieldType.swift in Sources */, + 3F3476A72141F9D900D7B4FC /* Fund.swift in Sources */, + 3F41D0CB22F611C0008D21A0 /* CellType.swift in Sources */, + 3F30230F22FF019300CD98AF /* DomainError.swift in Sources */, + 3F41D0C922F610AE008D21A0 /* FormCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F3476772141F3BD00D7B4FC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F3476A92141FA6000D7B4FC /* RMUser.swift in Sources */, + 3F3476A52141F4EC00D7B4FC /* ApiUseCase.swift in Sources */, + 3F34769D2141F4EC00D7B4FC /* RealmRepresentable.swift in Sources */, + 3F3476A02141F4EC00D7B4FC /* Repository.swift in Sources */, + 3F34769F2141F4EC00D7B4FC /* RunLoopThreadScheduler.swift in Sources */, + 3F3476A12141F4EC00D7B4FC /* DomainConvertibleType.swift in Sources */, + 3F34769E2141F4EC00D7B4FC /* Observable+ext.swift in Sources */, + 3F30231422FF386200CD98AF /* UseCaseManager.swift in Sources */, + 3F30231322FF14B400CD98AF /* UseCaseError.swift in Sources */, + 3F3476A22141F4EC00D7B4FC /* Realm+ext.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F8033A72140B51A005DC4AF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F8033DF2140B5AA005DC4AF /* UIViewController+ext.swift in Sources */, + 3F922E5F2309E14200B5FCE8 /* ViewError.swift in Sources */, + 3F12294323117522009F8DD2 /* FundViewPresenter.swift in Sources */, + 3FFEBAC42312FAAA000878AF /* FundInfoViewCell.swift in Sources */, + 3F8033DB2140B5AA005DC4AF /* BasicView.swift in Sources */, + 3F922E4D230831B000B5FCE8 /* ApiUseCaseMock.swift in Sources */, + 3F1229582311A904009F8DD2 /* FundViewCell.swift in Sources */, + 3F922E55230972A800B5FCE8 /* CheckBoxViewCell.swift in Sources */, + 3F302343230274F500CD98AF /* ButtonViewCell.swift in Sources */, + 3F922E3B23077DF900B5FCE8 /* FormViewPresenter.swift in Sources */, + 3F8033AF2140B51A005DC4AF /* AppDelegate.swift in Sources */, + 3F8033DE2140B5AA005DC4AF /* BasicPresenter.swift in Sources */, + 3F922E54230972A800B5FCE8 /* TextViewCell.swift in Sources */, + 3FD56E6F230CC89A0063D8A6 /* TestError.swift in Sources */, + 3F8033D12140B570005DC4AF /* ThemeManager.swift in Sources */, + 3F1229542311838F009F8DD2 /* SafariViewController.swift in Sources */, + 3FFEBAC62312FD6B000878AF /* FundDownInfoViewCell.swift in Sources */, + 3F30234123026C1D00CD98AF /* FundViewController.swift in Sources */, + 3F1229562311868E009F8DD2 /* MessageSentViewController.swift in Sources */, + 3F8033DC2140B5AA005DC4AF /* UIColor+ext.swift in Sources */, + 3FFEBAC22312EB67000878AF /* UIImage+ext.swift in Sources */, + 3F12295023117EC9009F8DD2 /* FormViewCellProtocol.swift in Sources */, + 3F922E3D23077FEF00B5FCE8 /* SwinjectStoryboard+Setup.swift in Sources */, + 3F922E4F230971F200B5FCE8 /* FieldViewCell.swift in Sources */, + 3F30233F23026BF500CD98AF /* FormViewController.swift in Sources */, + 3F922E53230972A800B5FCE8 /* ImageViewCell.swift in Sources */, + 3F3023162300564A00CD98AF /* MainTabViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F922E3F23082E5C00B5FCE8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F4C82F5230E205E008F236C /* DomainValidationTest.swift in Sources */, + 3FFEBACA2314CF02000878AF /* FundViewPresenterTest.swift in Sources */, + 3FD56E6A230CC1240063D8A6 /* FormViewControllerMock.swift in Sources */, + 3FD56E6E230CC8210063D8A6 /* TestError.swift in Sources */, + 3FD56E6C230CC1D60063D8A6 /* BasicViewMock.swift in Sources */, + 3FFEBACE2314CF7D000878AF /* FundViewControllerMock.swift in Sources */, + 3F922E4623082E5C00B5FCE8 /* ApiUseCaseMock.swift in Sources */, + 3FD56E67230CBE0E0063D8A6 /* FormViewPresenterTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3F34766F2141F2C100D7B4FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3F3476682141F2C100D7B4FC /* Domain */; + targetProxy = 3F34766E2141F2C100D7B4FC /* PBXContainerItemProxy */; + }; + 3F3476822141F3BD00D7B4FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3F34767B2141F3BD00D7B4FC /* Platform */; + targetProxy = 3F3476812141F3BD00D7B4FC /* PBXContainerItemProxy */; + }; + 3F922E4923082E5C00B5FCE8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3F8033AA2140B51A005DC4AF /* TesteiOS */; + targetProxy = 3F922E4823082E5C00B5FCE8 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 3F8033B72140B51C005DC4AF /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 3F8033B82140B51C005DC4AF /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 3F3476722141F2C100D7B4FC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E4F3CD46F7BADEE9D064D980 /* Pods-Domain.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Q2B7BA4L63; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Domain/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.domain.testeios; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 3F3476732141F2C100D7B4FC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2A0C839DD581C93AA270927F /* Pods-Domain.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Q2B7BA4L63; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Domain/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.domain.testeios; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 3F3476862141F3BD00D7B4FC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A02B31C55A998F2E17E8FE94 /* Pods-Platform.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Q2B7BA4L63; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Platform/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.platform.testeios; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 3F3476872141F3BD00D7B4FC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1421F059DFB238FCB394B0AA /* Pods-Platform.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Q2B7BA4L63; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Platform/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.platform.testeios; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 3F8033BB2140B51C005DC4AF /* 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 3F8033BC2140B51C005DC4AF /* 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3F8033BE2140B51C005DC4AF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B3B851C15FCA593A3448B0E0 /* Pods-TesteiOS.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q2B7BA4L63; + INFOPLIST_FILE = "$(SRCROOT)/View/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.testeios; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3F8033BF2140B51C005DC4AF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E9A5A2CCD342D90E7E6500E1 /* Pods-TesteiOS.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q2B7BA4L63; + INFOPLIST_FILE = "$(SRCROOT)/View/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erika.testeios; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 3F922E4B23082E5C00B5FCE8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A62658915FEAF73834503E3C /* Pods-Tests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q2B7BA4L63; + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = erikasegatto.Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TesteiOS.app/TesteiOS"; + }; + name = Debug; + }; + 3F922E4C23082E5C00B5FCE8 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 13CCDE1B42F562B40C6DB37B /* Pods-Tests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q2B7BA4L63; + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = erikasegatto.Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TesteiOS.app/TesteiOS"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3F3476742141F2C100D7B4FC /* Build configuration list for PBXNativeTarget "Domain" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F3476722141F2C100D7B4FC /* Debug */, + 3F3476732141F2C100D7B4FC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3F3476852141F3BD00D7B4FC /* Build configuration list for PBXNativeTarget "Platform" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F3476862141F3BD00D7B4FC /* Debug */, + 3F3476872141F3BD00D7B4FC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3F8033A62140B51A005DC4AF /* Build configuration list for PBXProject "TesteiOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F8033BB2140B51C005DC4AF /* Debug */, + 3F8033BC2140B51C005DC4AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3F8033BD2140B51C005DC4AF /* Build configuration list for PBXNativeTarget "TesteiOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F8033BE2140B51C005DC4AF /* Debug */, + 3F8033BF2140B51C005DC4AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3F922E4A23082E5C00B5FCE8 /* Build configuration list for PBXNativeTarget "Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F922E4B23082E5C00B5FCE8 /* Debug */, + 3F922E4C23082E5C00B5FCE8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3F8033A32140B51A005DC4AF /* Project object */; +} diff --git a/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..15a04365 --- /dev/null +++ b/TesteiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/TesteiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/erikasegatto.xcuserdatad/UserInterfaceState.xcuserstate b/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/erikasegatto.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..f7553eae Binary files /dev/null and b/TesteiOS.xcodeproj/project.xcworkspace/xcuserdata/erikasegatto.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme b/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme new file mode 100644 index 00000000..d43ff482 --- /dev/null +++ b/TesteiOS.xcodeproj/xcshareddata/xcschemes/TesteiOS.xcscheme @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TesteiOS.xcodeproj/xcuserdata/erikasegatto.xcuserdatad/xcschemes/xcschememanagement.plist b/TesteiOS.xcodeproj/xcuserdata/erikasegatto.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..3090a02a --- /dev/null +++ b/TesteiOS.xcodeproj/xcuserdata/erikasegatto.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,62 @@ + + + + + SchemeUserState + + Domain.xcscheme + + orderHint + 9 + + Domain.xcscheme_^#shared#^_ + + orderHint + 16 + + MedMe.xcscheme + + orderHint + 8 + + MedMe.xcscheme_^#shared#^_ + + orderHint + 0 + + Model.xcscheme + + orderHint + 0 + + Platform.xcscheme + + orderHint + 10 + + Platform.xcscheme_^#shared#^_ + + orderHint + 17 + + TesteiOS.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + 3F8033AA2140B51A005DC4AF + + primary + + + 3F922E4223082E5C00B5FCE8 + + primary + + + + + diff --git a/Tests/DomainValidationTest.swift b/Tests/DomainValidationTest.swift new file mode 100644 index 00000000..af6e8d5f --- /dev/null +++ b/Tests/DomainValidationTest.swift @@ -0,0 +1,97 @@ +// +// DomainValidationTest.swift +// Tests +// +// Created by Erika de Almeida Segatto on 21/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import XCTest +import Domain +@testable import TesteiOS + +class DomainValidationTest: XCTestCase { + + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + + func test_phoneCellValidation() { + // Given + let inputList = [ + ("0000000000", true), + ("00000000000", true), + ("00000000000".formatAsPhone(), true), + ("(00) 00000-0000", true), + ("(00) 00000-0000", true), + ("(00)00000-0000", true), + ("(00)0000-0000", true), + ("000000000", false), + ("000000000000", false), + ("00 00000000".formatAsPhone(), true), + ("00 00000000", false), + ("0", false), + ("a", false), + ("aaaaaa0000000", false), + ("", false), + ("0000000000aaaa", false) + ] + + for (index, input) in inputList.enumerated() { + + // When + let isValid = FieldType.telNumber.isValid(input.0) + + // Then + XCTAssertEqual(input.1, isValid, " at index \(index)") + } + } + + func test_textCellValidation() { + // Given + let inputList = [ + ("a", true), + ("0", true), + ("aabaohihihoihdogidugygdjvbl", true), + ("-", true), + ("", false) + ] + + for (index, input) in inputList.enumerated() { + + // When + let isValid = FieldType.text.isValid(input.0) + + // Then + XCTAssertEqual(input.1, isValid, " at index \(index)") + } + } + + + func test_emailCellValidation() { + // Given + let inputList = [ + ("a@b.com.br", true), + ("m@aaaaaaa.com", true), + ("@bbb.com.br", false), + ("1@2.com", true), + ("a@b.com.", false), + ("", false) + ] + + for (index, input) in inputList.enumerated() { + + // When + let isValid = FieldType.email.isValid(input.0) + + // Then + XCTAssertEqual(input.1, isValid, " at index \(index)") + } + } +} diff --git a/Tests/FormViewPresenterTest.swift b/Tests/FormViewPresenterTest.swift new file mode 100644 index 00000000..95a894ad --- /dev/null +++ b/Tests/FormViewPresenterTest.swift @@ -0,0 +1,358 @@ +// +// FormViewPresenterTest.swift +// Tests +// +// Created by Erika de Almeida Segatto on 20/08/19. +// Copyright © 2019 Erika de Almeida Segatto. All rights reserved. +// + +import XCTest +import Domain +@testable import TesteiOS + +class FormViewPresenterTest: XCTestCase { + + var apiUseCase = ApiUseCaseMock() + var view = FormViewControllerMock() + var presenter: FormViewPresenter! + + override func setUp() { + super.setUp() + presenter = FormViewPresenterImplementation(view: view, apiUseCase: apiUseCase) + } + + override func tearDown() { + presenter = nil + super.tearDown() + } + + func test_viewDidLoad_getFormFieldsCalled_success() { + // Given + apiUseCase.getFormFieldsCalled = false + apiUseCase.forceError = false + + // When + presenter.viewDidLoad() + + // Then + XCTAssertNil(view.errorShowed) + XCTAssertTrue(apiUseCase.getFormFieldsCalled, "apiUseCase.getFormFieldsCalled") + } + + func test_viewDidLoad_getFormFieldsCalled_error() { + // Given + apiUseCase.getFormFieldsCalled = false + apiUseCase.forceError = true + + // When + presenter.viewDidLoad() + + // Then + XCTAssertNotNil(view.errorShowed) + XCTAssertTrue(apiUseCase.getFormFieldsCalled, "apiUseCase.getFormFieldsCalled") + } + + func test_getRowCount() { + // Given + apiUseCase.formCellList = FormCell.newList(count: 20) + apiUseCase.forceError = false + + // When + presenter.viewDidLoad() + let num = presenter.getRowCount() + + // Then + XCTAssertNil(view.errorShowed) + XCTAssertEqual(apiUseCase.formCellList.count, num, "cell count") + } + + func test_getRowType() { + // Given + apiUseCase.formCellList = FormCell.newList(count: 35) + apiUseCase.forceError = false + + presenter.viewDidLoad() + + for index in -1...apiUseCase.formCellList.count+1 { + //Given + let expectedCell = (index>=0 && index=0 && index