=4.2)
+ private var _animationCurve : UIView.AnimationOptions = .curveEaseOut
+ #else
+ private var _animationCurve : UIViewAnimationOptions = .curveEaseOut
+ #endif
+
+ /*******************************************/
+
+ /** Boolean to maintain keyboard is showing or it is hide. To solve rootViewController.view.frame calculations. */
+ private var _privateIsKeyboardShowing = false
+
+ private var _privateMovedDistance : CGFloat = 0.0
+
+ /** To use with keyboardDistanceFromTextField. */
+ private var _privateKeyboardDistanceFromTextField: CGFloat = 10.0
+
+ /** To know if we have any pending request to adjust view position. */
+ private var _privateHasPendingAdjustRequest = false
+
+ /**************************************************************************************/
+
+ ///--------------------------------------
+ /// MARK: Initialization/Deinitialization
+ ///--------------------------------------
+
+ /* Singleton Object Initialization. */
+ override init() {
+
+ super.init()
+
+ self.registerAllNotifications()
+
+ //Creating gesture for @shouldResignOnTouchOutside. (Enhancement ID: #14)
+ resignFirstResponderGesture.isEnabled = shouldResignOnTouchOutside
+
+ //Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550)
+ //If you experience exception breakpoint issue at below line then try these solutions https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator
+ let textField = UITextField()
+ textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:)))
+ textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:)))
+
+ disabledDistanceHandlingClasses.append(UITableViewController.self)
+ disabledDistanceHandlingClasses.append(UIAlertController.self)
+ disabledToolbarClasses.append(UIAlertController.self)
+ disabledTouchResignedClasses.append(UIAlertController.self)
+ toolbarPreviousNextAllowedClasses.append(UITableView.self)
+ toolbarPreviousNextAllowedClasses.append(UICollectionView.self)
+ toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self)
+ touchResignedGestureIgnoreClasses.append(UIControl.self)
+ touchResignedGestureIgnoreClasses.append(UINavigationBar.self)
+ }
+
+ /** Override +load method to enable KeyboardManager when class loader load IQKeyboardManager. Enabling when app starts (No need to write any code) */
+ /** It doesn't work from Swift 1.2 */
+// override public class func load() {
+// super.load()
+//
+// //Enabling IQKeyboardManager.
+// IQKeyboardManager.shared.enable = true
+// }
+
+ deinit {
+ // Disable the keyboard manager.
+ enable = false
+
+ //Removing notification observers on dealloc.
+ NotificationCenter.default.removeObserver(self)
+ }
+
+ /** Getting keyWindow. */
+ private func keyWindow() -> UIWindow? {
+
+ if let keyWindow = _textFieldView?.window {
+ return keyWindow
+ } else {
+
+ struct Static {
+ /** @abstract Save keyWindow object for reuse.
+ @discussion Sometimes [[UIApplication sharedApplication] keyWindow] is returning nil between the app. */
+ static weak var keyWindow : UIWindow?
+ }
+
+ //If original key window is not nil and the cached keywindow is also not original keywindow then changing keywindow.
+ if let originalKeyWindow = UIApplication.shared.keyWindow,
+ (Static.keyWindow == nil || Static.keyWindow != originalKeyWindow) {
+ Static.keyWindow = originalKeyWindow
+ }
+
+ //Return KeyWindow
+ return Static.keyWindow
+ }
+ }
+
+ ///-----------------------
+ /// MARK: Helper Functions
+ ///-----------------------
+
+ private func optimizedAdjustPosition() {
+ if _privateHasPendingAdjustRequest == false {
+ _privateHasPendingAdjustRequest = true
+ OperationQueue.main.addOperation {
+ self.adjustPosition()
+ self._privateHasPendingAdjustRequest = false
+ }
+ }
+ }
+
+ /* Adjusting RootViewController's frame according to interface orientation. */
+ private func adjustPosition() {
+
+ // We are unable to get textField object while keyboard showing on UIWebView's textField. (Bug ID: #11)
+ if _privateHasPendingAdjustRequest == true,
+ let textFieldView = _textFieldView,
+ let rootController = textFieldView.parentContainerViewController(),
+ let window = keyWindow(),
+ let textFieldViewRectInWindow = textFieldView.superview?.convert(textFieldView.frame, to: window),
+ let textFieldViewRectInRootSuperview = textFieldView.superview?.convert(textFieldView.frame, to: rootController.view?.superview)
+ {
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ // Getting RootViewOrigin.
+ var rootViewOrigin = rootController.view.frame.origin
+
+ //Maintain keyboardDistanceFromTextField
+ var specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField
+
+ if let searchBar = textFieldView.textFieldSearchBar() {
+
+ specialKeyboardDistanceFromTextField = searchBar.keyboardDistanceFromTextField
+ }
+
+ let newKeyboardDistanceFromTextField = (specialKeyboardDistanceFromTextField == kIQUseDefaultKeyboardDistance) ? keyboardDistanceFromTextField : specialKeyboardDistanceFromTextField
+ var kbSize = _kbSize
+ kbSize.height += newKeyboardDistanceFromTextField
+
+ let navigationBarAreaHeight : CGFloat = UIApplication.shared.statusBarFrame.height + ( rootController.navigationController?.navigationBar.frame.height ?? 0)
+ let layoutAreaHeight : CGFloat = rootController.view.layoutMargins.bottom
+
+ let topLayoutGuide : CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + 5
+ let bottomLayoutGuide : CGFloat = (textFieldView is UITextView) ? 0 : rootController.view.layoutMargins.bottom //Validation of textView for case where there is a tab bar at the bottom or running on iPhone X and textView is at the bottom.
+
+ // Move positive = textField is hidden.
+ // Move negative = textField is showing.
+ // Calculating move position.
+ var move : CGFloat = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY-(window.frame.height-kbSize.height)+bottomLayoutGuide)
+
+ showLog("Need to move: \(move)")
+
+ var superScrollView : UIScrollView? = nil
+ var superView = textFieldView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+
+ //Getting UIScrollView whose scrolling is enabled. // (Bug ID: #285)
+ while let view = superView {
+
+ if (view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false) {
+ superScrollView = view
+ break
+ }
+ else {
+ // Getting it's superScrollView. // (Enhancement ID: #21, #24)
+ superView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
+ }
+ }
+
+ //If there was a lastScrollView. // (Bug ID: #34)
+ if let lastScrollView = _lastScrollView {
+ //If we can't find current superScrollView, then setting lastScrollView to it's original form.
+ if superScrollView == nil {
+
+ showLog("Restoring \(lastScrollView._IQDescription()) contentInset to : \(_startingContentInsets) and contentOffset to : \(_startingContentOffset)")
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ lastScrollView.contentInset = self._startingContentInsets
+ lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
+ }) { (animated:Bool) -> Void in }
+
+ if lastScrollView.shouldRestoreScrollViewContentOffset == true {
+ lastScrollView.setContentOffset(_startingContentOffset, animated: UIView.areAnimationsEnabled)
+ }
+
+ _startingContentInsets = UIEdgeInsets()
+ _startingScrollIndicatorInsets = UIEdgeInsets()
+ _startingContentOffset = CGPoint.zero
+ _lastScrollView = nil
+ } else if superScrollView != lastScrollView { //If both scrollView's are different, then reset lastScrollView to it's original frame and setting current scrollView as last scrollView.
+
+ showLog("Restoring \(lastScrollView._IQDescription()) contentInset to : \(_startingContentInsets) and contentOffset to : \(_startingContentOffset)")
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ lastScrollView.contentInset = self._startingContentInsets
+ lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
+ }) { (animated:Bool) -> Void in }
+
+ if lastScrollView.shouldRestoreScrollViewContentOffset == true {
+ lastScrollView.setContentOffset(_startingContentOffset, animated: UIView.areAnimationsEnabled)
+ }
+
+ _lastScrollView = superScrollView
+ if let scrollView = superScrollView {
+ _startingContentInsets = scrollView.contentInset
+ _startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets
+ _startingContentOffset = scrollView.contentOffset
+ }
+
+ showLog("Saving New \(lastScrollView._IQDescription()) contentInset : \(_startingContentInsets) and contentOffset : \(_startingContentOffset)")
+ }
+ //Else the case where superScrollView == lastScrollView means we are on same scrollView after switching to different textField. So doing nothing, going ahead
+ } else if let unwrappedSuperScrollView = superScrollView { //If there was no lastScrollView and we found a current scrollView. then setting it as lastScrollView.
+ _lastScrollView = unwrappedSuperScrollView
+ _startingContentInsets = unwrappedSuperScrollView.contentInset
+ _startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets
+ _startingContentOffset = unwrappedSuperScrollView.contentOffset
+
+ showLog("Saving \(unwrappedSuperScrollView._IQDescription()) contentInset : \(_startingContentInsets) and contentOffset : \(_startingContentOffset)")
+ }
+
+ // Special case for ScrollView.
+ // If we found lastScrollView then setting it's contentOffset to show textField.
+ if let lastScrollView = _lastScrollView {
+ //Saving
+ var lastView = textFieldView
+ var superScrollView = _lastScrollView
+
+ while let scrollView = superScrollView {
+
+ //Looping in upper hierarchy until we don't found any scrollView in it's upper hirarchy till UIWindow object.
+ if move > 0 ? (move > (-scrollView.contentOffset.y - scrollView.contentInset.top)) : scrollView.contentOffset.y>0 {
+
+ var tempScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+ var nextScrollView : UIScrollView? = nil
+ while let view = tempScrollView {
+
+ if (view.isScrollEnabled && view.shouldIgnoreScrollingAdjustment == false) {
+ nextScrollView = view
+ break
+ } else {
+ tempScrollView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView
+ }
+ }
+
+ //Getting lastViewRect.
+ if let lastViewRect = lastView.superview?.convert(lastView.frame, to: scrollView) {
+
+ //Calculating the expected Y offset from move and scrollView's contentOffset.
+ var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y,-move)
+
+ //Rearranging the expected Y offset according to the view.
+ shouldOffsetY = min(shouldOffsetY, lastViewRect.origin.y)
+
+ //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+ //nextScrollView == nil If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.)
+ //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+ //shouldOffsetY >= 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92)
+ if textFieldView is UITextView == true &&
+ nextScrollView == nil &&
+ shouldOffsetY >= 0 {
+
+ // Converting Rectangle according to window bounds.
+ if let currentTextFieldViewRect = textFieldView.superview?.convert(textFieldView.frame, to: window) {
+
+ //Calculating expected fix distance which needs to be managed from navigation bar
+ let expectedFixDistance = currentTextFieldViewRect.minY - topLayoutGuide
+
+ //Now if expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) is lower than current shouldOffsetY, which means we're in a position where navigationBar up and hide, then reducing shouldOffsetY with expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance)
+ shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance)
+
+ //Setting move to 0 because now we don't want to move any view anymore (All will be managed by our contentInset logic.
+ move = 0
+ }
+ else {
+ //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
+ move -= (shouldOffsetY-scrollView.contentOffset.y)
+ }
+ }
+ else
+ {
+ //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY.
+ move -= (shouldOffsetY-scrollView.contentOffset.y)
+ }
+
+ //Getting problem while using `setContentOffset:animated:`, So I used animation API.
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.showLog("Adjusting \(scrollView.contentOffset.y-shouldOffsetY) to \(scrollView._IQDescription()) ContentOffset")
+
+ self.showLog("Remaining Move: \(move)")
+
+ scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: shouldOffsetY)
+ }) { (animated:Bool) -> Void in }
+ }
+
+ // Getting next lastView & superScrollView.
+ lastView = scrollView
+ superScrollView = nextScrollView
+ } else {
+ break
+ }
+ }
+
+ //Updating contentInset
+ if let lastScrollViewRect = lastScrollView.superview?.convert(lastScrollView.frame, to: window) {
+
+ let bottom : CGFloat = (kbSize.height-newKeyboardDistanceFromTextField)-(window.frame.height-lastScrollViewRect.maxY)
+
+ // Update the insets so that the scroll vew doesn't shift incorrectly when the offset is near the bottom of the scroll view.
+ var movedInsets = lastScrollView.contentInset
+
+ movedInsets.bottom = max(_startingContentInsets.bottom, bottom)
+
+ showLog("\(lastScrollView._IQDescription()) old ContentInset : \(lastScrollView.contentInset)")
+
+ //Getting problem while using `setContentOffset:animated:`, So I used animation API.
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+ lastScrollView.contentInset = movedInsets
+
+ var newInset = lastScrollView.scrollIndicatorInsets
+ newInset.bottom = movedInsets.bottom
+ lastScrollView.scrollIndicatorInsets = newInset
+
+ }) { (animated:Bool) -> Void in }
+
+ showLog("\(lastScrollView._IQDescription()) new ContentInset : \(lastScrollView.contentInset)")
+ }
+ }
+ //Going ahead. No else if.
+
+ //Special case for UITextView(Readjusting textView.contentInset when textView hight is too big to fit on screen)
+ //_lastScrollView If not having inside any scrollView, (now contentInset manages the full screen textView.
+ //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type
+ if let textView = textFieldView as? UITextView {
+
+// CGRect rootSuperViewFrameInWindow = [_rootViewController.view.superview convertRect:_rootViewController.view.superview.bounds toView:keyWindow];
+//
+// CGFloat keyboardOverlapping = CGRectGetMaxY(rootSuperViewFrameInWindow) - keyboardYPosition;
+//
+// CGFloat textViewHeight = MIN(CGRectGetHeight(_textFieldView.frame), (CGRectGetHeight(rootSuperViewFrameInWindow)-topLayoutGuide-keyboardOverlapping));
+
+ let keyboardYPosition = window.frame.height - (kbSize.height-newKeyboardDistanceFromTextField)
+ var rootSuperViewFrameInWindow = window.frame
+ if let rootSuperview = rootController.view.superview {
+ rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window)
+ }
+
+ let keyboardOverlapping = rootSuperViewFrameInWindow.maxY - keyboardYPosition
+
+ let textViewHeight = min(textView.frame.height, rootSuperViewFrameInWindow.height-topLayoutGuide-keyboardOverlapping)
+
+ if (textView.frame.size.height-textView.contentInset.bottom>textViewHeight)
+ {
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.showLog("\(textFieldView._IQDescription()) Old UITextView.contentInset : \(textView.contentInset)")
+
+ //_isTextViewContentInsetChanged, If frame is not change by library in past, then saving user textView properties (Bug ID: #92)
+ if (self.isTextViewContentInsetChanged == false)
+ {
+ self.startingTextViewContentInsets = textView.contentInset
+ self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets
+ }
+
+ var newContentInset = textView.contentInset
+ newContentInset.bottom = textView.frame.size.height-textViewHeight
+ textView.contentInset = newContentInset
+ textView.scrollIndicatorInsets = newContentInset
+ self.isTextViewContentInsetChanged = true
+
+ self.showLog("\(textFieldView._IQDescription()) Old UITextView.contentInset : \(textView.contentInset)")
+
+
+ }, completion: { (finished) -> Void in })
+ }
+ }
+
+ // +Positive or zero.
+ if move >= 0 {
+
+ rootViewOrigin.y -= move
+
+ rootViewOrigin.y = max(rootViewOrigin.y, min(0, -(kbSize.height-newKeyboardDistanceFromTextField)))
+
+ showLog("Moving Upward")
+ // Setting adjusted rootViewRect
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ var rect = rootController.view.frame
+ rect.origin = rootViewOrigin
+ rootController.view.frame = rect
+
+ //Animating content if needed (Bug ID: #204)
+ if self.layoutIfNeededOnUpdate == true {
+ //Animating content (Bug ID: #160)
+ rootController.view.setNeedsLayout()
+ rootController.view.layoutIfNeeded()
+ }
+
+ self.showLog("Set \(String(describing: rootController._IQDescription())) origin to : \(rootViewOrigin)")
+
+ }) { (finished) -> Void in }
+
+ _privateMovedDistance = (_topViewBeginOrigin.y-rootViewOrigin.y)
+ } else { // -Negative
+ let disturbDistance : CGFloat = rootViewOrigin.y-_topViewBeginOrigin.y
+
+ // disturbDistance Negative = frame disturbed.
+ // disturbDistance positive = frame not disturbed.
+ if disturbDistance <= 0 {
+
+ rootViewOrigin.y -= max(move, disturbDistance)
+
+ showLog("Moving Downward")
+ // Setting adjusted rootViewRect
+ // Setting adjusted rootViewRect
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ var rect = rootController.view.frame
+ rect.origin = rootViewOrigin
+ rootController.view.frame = rect
+
+ //Animating content if needed (Bug ID: #204)
+ if self.layoutIfNeededOnUpdate == true {
+ //Animating content (Bug ID: #160)
+ rootController.view.setNeedsLayout()
+ rootController.view.layoutIfNeeded()
+ }
+
+ self.showLog("Set \(String(describing: rootController._IQDescription())) origin to : \(rootViewOrigin)")
+
+ }) { (finished) -> Void in }
+
+ _privateMovedDistance = (_topViewBeginOrigin.y-rootViewOrigin.y)
+ }
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+ }
+
+ private func restorePosition() {
+
+ _privateHasPendingAdjustRequest = false
+
+ // Setting rootViewController frame to it's original position. // (Bug ID: #18)
+ if _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false {
+
+ if let rootViewController = _rootViewController {
+
+ //Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations.
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.showLog("Restoring \(rootViewController._IQDescription()) origin to : \(self._topViewBeginOrigin)")
+
+ // Setting it's new frame
+ var rect = rootViewController.view.frame
+ rect.origin = self._topViewBeginOrigin
+ rootViewController.view.frame = rect
+
+ self._privateMovedDistance = 0
+
+ if rootViewController.navigationController?.interactivePopGestureRecognizer?.state == .began {
+ self._rootViewControllerWhilePopGestureRecognizerActive = rootViewController
+ self._topViewBeginOriginWhilePopGestureRecognizerActive = self._topViewBeginOrigin
+ }
+
+ //Animating content if needed (Bug ID: #204)
+ if self.layoutIfNeededOnUpdate == true {
+ //Animating content (Bug ID: #160)
+ rootViewController.view.setNeedsLayout()
+ rootViewController.view.layoutIfNeeded()
+ }
+ }) { (finished) -> Void in }
+
+ _rootViewController = nil
+ }
+ }
+ }
+
+ ///---------------------
+ /// MARK: Public Methods
+ ///---------------------
+
+ /* Refreshes textField/textView position if any external changes is explicitly made by user. */
+ @objc public func reloadLayoutIfNeeded() -> Void {
+
+ if privateIsEnabled() == true {
+ if _privateIsKeyboardShowing == true,
+ _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false,
+ let textFieldView = _textFieldView,
+ textFieldView.isAlertViewTextField() == false {
+ optimizedAdjustPosition()
+ }
+ }
+ }
+
+ ///-------------------------------
+ /// MARK: UIKeyboard Notifications
+ ///-------------------------------
+
+ /* UIKeyboardWillShowNotification. */
+ @objc internal func keyboardWillShow(_ notification : Notification?) -> Void {
+
+ _kbShowNotification = notification
+
+ // Boolean to know keyboard is showing/hiding
+ _privateIsKeyboardShowing = true
+
+ let oldKBSize = _kbSize
+
+ if let info = notification?.userInfo {
+
+ #if swift(>=4.2)
+ let curveUserInfoKey = UIResponder.keyboardAnimationCurveUserInfoKey
+ let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
+ let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey
+ #else
+ let curveUserInfoKey = UIKeyboardAnimationCurveUserInfoKey
+ let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
+ let frameEndUserInfoKey = UIKeyboardFrameEndUserInfoKey
+ #endif
+
+ // Getting keyboard animation.
+ if let curve = info[curveUserInfoKey] as? UInt {
+ _animationCurve = .init(rawValue: curve)
+ } else {
+ _animationCurve = .curveEaseOut
+ }
+
+ // Getting keyboard animation duration
+ if let duration = info[durationUserInfoKey] as? TimeInterval {
+
+ //Saving animation duration
+ if duration != 0.0 {
+ _animationDuration = duration
+ }
+ } else {
+ _animationDuration = 0.25
+ }
+
+ // Getting UIKeyboardSize.
+ if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
+
+ let screenSize = UIScreen.main.bounds
+
+ //Calculating actual keyboard displayed size, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381)
+ let intersectRect = kbFrame.intersection(screenSize)
+
+ if intersectRect.isNull {
+ _kbSize = CGSize(width: screenSize.size.width, height: 0)
+ } else {
+ _kbSize = intersectRect.size
+ }
+
+ showLog("UIKeyboard Size : \(_kbSize)")
+ }
+ }
+
+ if privateIsEnabled() == false {
+ return
+ }
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ // (Bug ID: #5)
+ if let textFieldView = _textFieldView, _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true {
+
+ // keyboard is not showing(At the beginning only). We should save rootViewRect.
+ _rootViewController = textFieldView.parentContainerViewController()
+ if let controller = _rootViewController {
+
+ if _rootViewControllerWhilePopGestureRecognizerActive == controller {
+ _topViewBeginOrigin = _topViewBeginOriginWhilePopGestureRecognizerActive
+ } else {
+ _topViewBeginOrigin = controller.view.frame.origin
+ }
+
+ _rootViewControllerWhilePopGestureRecognizerActive = nil
+ _topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+
+ self.showLog("Saving \(controller._IQDescription()) beginning origin : \(self._topViewBeginOrigin)")
+ }
+ }
+
+ //If last restored keyboard size is different(any orientation accure), then refresh. otherwise not.
+ if _kbSize.equalTo(oldKBSize) == false {
+
+ //If _textFieldView is inside UITableViewController then let UITableViewController to handle it (Bug ID: #37) (Bug ID: #76) See note:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
+
+ if _privateIsKeyboardShowing == true,
+ let textFieldView = _textFieldView,
+ textFieldView.isAlertViewTextField() == false {
+
+ // keyboard is already showing. adjust position.
+ optimizedAdjustPosition()
+ }
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ /* UIKeyboardDidShowNotification. */
+ @objc internal func keyboardDidShow(_ notification : Notification?) -> Void {
+
+ if privateIsEnabled() == false {
+ return
+ }
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ if let textFieldView = _textFieldView,
+ let parentController = textFieldView.parentContainerViewController(), (parentController.modalPresentationStyle == UIModalPresentationStyle.formSheet || parentController.modalPresentationStyle == UIModalPresentationStyle.pageSheet),
+ textFieldView.isAlertViewTextField() == false {
+
+ self.optimizedAdjustPosition()
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ /* UIKeyboardWillHideNotification. So setting rootViewController to it's default frame. */
+ @objc internal func keyboardWillHide(_ notification : Notification?) -> Void {
+
+ //If it's not a fake notification generated by [self setEnable:NO].
+ if notification != nil {
+ _kbShowNotification = nil
+ }
+
+ // Boolean to know keyboard is showing/hiding
+ _privateIsKeyboardShowing = false
+
+ if let info = notification?.userInfo {
+
+ #if swift(>=4.2)
+ let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
+ #else
+ let durationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey
+ #endif
+
+ // Getting keyboard animation duration
+ if let duration = info[durationUserInfoKey] as? TimeInterval {
+ if duration != 0 {
+ // Setitng keyboard animation duration
+ _animationDuration = duration
+ }
+ }
+ }
+
+ //If not enabled then do nothing.
+ if privateIsEnabled() == false {
+ return
+ }
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ //Commented due to #56. Added all the conditions below to handle UIWebView's textFields. (Bug ID: #56)
+ // We are unable to get textField object while keyboard showing on UIWebView's textField. (Bug ID: #11)
+ // if (_textFieldView == nil) return
+
+ //Restoring the contentOffset of the lastScrollView
+ if let lastScrollView = _lastScrollView {
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ lastScrollView.contentInset = self._startingContentInsets
+ lastScrollView.scrollIndicatorInsets = self._startingScrollIndicatorInsets
+
+ if lastScrollView.shouldRestoreScrollViewContentOffset == true {
+ lastScrollView.contentOffset = self._startingContentOffset
+ }
+
+ self.showLog("Restoring \(lastScrollView._IQDescription()) contentInset to : \(self._startingContentInsets) and contentOffset to : \(self._startingContentOffset)")
+
+ // TODO: restore scrollView state
+ // This is temporary solution. Have to implement the save and restore scrollView state
+ var superScrollView : UIScrollView? = lastScrollView
+
+ while let scrollView = superScrollView {
+
+ let contentSize = CGSize(width: max(scrollView.contentSize.width, scrollView.frame.width), height: max(scrollView.contentSize.height, scrollView.frame.height))
+
+ let minimumY = contentSize.height - scrollView.frame.height
+
+ if minimumY < scrollView.contentOffset.y {
+ scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: minimumY)
+
+ self.showLog("Restoring \(scrollView._IQDescription()) contentOffset to : \(self._startingContentOffset)")
+ }
+
+ superScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView
+ }
+ }) { (finished) -> Void in }
+ }
+
+ restorePosition()
+
+ //Reset all values
+ _lastScrollView = nil
+ _kbSize = CGSize.zero
+ _startingContentInsets = UIEdgeInsets()
+ _startingScrollIndicatorInsets = UIEdgeInsets()
+ _startingContentOffset = CGPoint.zero
+ // topViewBeginRect = CGRectZero //Commented due to #82
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ @objc internal func keyboardDidHide(_ notification:Notification) {
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ _topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid
+
+ _kbSize = CGSize.zero
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ ///-------------------------------------------
+ /// MARK: UITextField/UITextView Notifications
+ ///-------------------------------------------
+
+ /** UITextFieldTextDidBeginEditingNotification, UITextViewTextDidBeginEditingNotification. Fetching UITextFieldView object. */
+ @objc internal func textFieldViewDidBeginEditing(_ notification:Notification) {
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ // Getting object
+ _textFieldView = notification.object as? UIView
+
+ if overrideKeyboardAppearance == true {
+
+ if let textFieldView = _textFieldView as? UITextField {
+ //If keyboard appearance is not like the provided appearance
+ if textFieldView.keyboardAppearance != keyboardAppearance {
+ //Setting textField keyboard appearance and reloading inputViews.
+ textFieldView.keyboardAppearance = keyboardAppearance
+ textFieldView.reloadInputViews()
+ }
+ } else if let textFieldView = _textFieldView as? UITextView {
+ //If keyboard appearance is not like the provided appearance
+ if textFieldView.keyboardAppearance != keyboardAppearance {
+ //Setting textField keyboard appearance and reloading inputViews.
+ textFieldView.keyboardAppearance = keyboardAppearance
+ textFieldView.reloadInputViews()
+ }
+ }
+ }
+
+ //If autoToolbar enable, then add toolbar on all the UITextField/UITextView's if required.
+ if privateIsEnableAutoToolbar() == true {
+
+ //UITextView special case. Keyboard Notification is firing before textView notification so we need to resign it first and then again set it as first responder to add toolbar on it.
+ if let textView = _textFieldView as? UITextView,
+ textView.inputAccessoryView == nil {
+
+ UIView.animate(withDuration: 0.00001, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.addToolbarIfRequired()
+
+ }, completion: { (finished) -> Void in
+
+ //On textView toolbar didn't appear on first time, so forcing textView to reload it's inputViews.
+ textView.reloadInputViews()
+ })
+ } else {
+ //Adding toolbar
+ addToolbarIfRequired()
+ }
+ } else {
+ removeToolbarIfRequired()
+ }
+
+ resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside()
+ _textFieldView?.window?.addGestureRecognizer(resignFirstResponderGesture) // (Enhancement ID: #14)
+
+ if privateIsEnabled() == true {
+ if _topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == true { // (Bug ID: #5)
+
+ _rootViewController = _textFieldView?.parentContainerViewController()
+
+ if let controller = _rootViewController {
+
+ if _rootViewControllerWhilePopGestureRecognizerActive == controller {
+ _topViewBeginOrigin = _topViewBeginOriginWhilePopGestureRecognizerActive
+ } else {
+ _topViewBeginOrigin = controller.view.frame.origin
+ }
+
+ _rootViewControllerWhilePopGestureRecognizerActive = nil
+ _topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid
+
+ self.showLog("Saving \(controller._IQDescription()) beginning origin : \(self._topViewBeginOrigin)")
+ }
+ }
+
+ //If _textFieldView is inside ignored responder then do nothing. (Bug ID: #37, #74, #76)
+ //See notes:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70).
+ if _privateIsKeyboardShowing == true,
+ let textFieldView = _textFieldView,
+ textFieldView.isAlertViewTextField() == false {
+
+ // keyboard is already showing. adjust position.
+ optimizedAdjustPosition()
+ }
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ /** UITextFieldTextDidEndEditingNotification, UITextViewTextDidEndEditingNotification. Removing fetched object. */
+ @objc internal func textFieldViewDidEndEditing(_ notification:Notification) {
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ //Removing gesture recognizer (Enhancement ID: #14)
+ _textFieldView?.window?.removeGestureRecognizer(resignFirstResponderGesture)
+
+ // We check if there's a change in original frame or not.
+
+ if let textView = _textFieldView as? UITextView {
+
+ if isTextViewContentInsetChanged == true {
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.isTextViewContentInsetChanged = false
+
+ self.showLog("Restoring \(textView._IQDescription()) textView.contentInset to : \(self.startingTextViewContentInsets)")
+
+ //Setting textField to it's initial contentInset
+ textView.contentInset = self.startingTextViewContentInsets
+ textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
+
+ }, completion: { (finished) -> Void in })
+ }
+ }
+
+ //Setting object to nil
+ _textFieldView = nil
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ ///---------------------------------------
+ /// MARK: UIStatusBar Notification methods
+ ///---------------------------------------
+
+ /** UIApplicationWillChangeStatusBarOrientationNotification. Need to set the textView to it's original position. If any frame changes made. (Bug ID: #92)*/
+ @objc internal func willChangeStatusBarOrientation(_ notification:Notification) {
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ //If textViewContentInsetChanged is saved then restore it.
+ if let textView = _textFieldView as? UITextView {
+
+ if isTextViewContentInsetChanged == true {
+
+ UIView.animate(withDuration: _animationDuration, delay: 0, options: _animationCurve.union(.beginFromCurrentState), animations: { () -> Void in
+
+ self.isTextViewContentInsetChanged = false
+
+ self.showLog("Restoring \(textView._IQDescription()) textView.contentInset to : \(self.startingTextViewContentInsets)")
+
+ //Setting textField to it's initial contentInset
+ textView.contentInset = self.startingTextViewContentInsets
+ textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets
+
+ }, completion: { (finished) -> Void in })
+ }
+ }
+
+ restorePosition()
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ ///------------------
+ /// MARK: AutoToolbar
+ ///------------------
+
+ /** Get all UITextField/UITextView siblings of textFieldView. */
+ private func responderViews()-> [UIView]? {
+
+ var superConsideredView : UIView?
+
+ //If find any consider responderView in it's upper hierarchy then will get deepResponderView.
+ for disabledClass in toolbarPreviousNextAllowedClasses {
+
+ superConsideredView = _textFieldView?.superviewOfClassType(disabledClass)
+
+ if superConsideredView != nil {
+ break
+ }
+ }
+
+ //If there is a superConsideredView in view's hierarchy, then fetching all it's subview that responds. No sorting for superConsideredView, it's by subView position. (Enhancement ID: #22)
+ if let view = superConsideredView {
+ return view.deepResponderViews()
+ } else { //Otherwise fetching all the siblings
+
+ if let textFields = _textFieldView?.responderSiblings() {
+
+ //Sorting textFields according to behaviour
+ switch toolbarManageBehaviour {
+ //If autoToolbar behaviour is bySubviews, then returning it.
+ case IQAutoToolbarManageBehaviour.bySubviews: return textFields
+
+ //If autoToolbar behaviour is by tag, then sorting it according to tag property.
+ case IQAutoToolbarManageBehaviour.byTag: return textFields.sortedArrayByTag()
+
+ //If autoToolbar behaviour is by tag, then sorting it according to tag property.
+ case IQAutoToolbarManageBehaviour.byPosition: return textFields.sortedArrayByPosition()
+ }
+ } else {
+ return nil
+ }
+ }
+ }
+
+ /** Add toolbar if it is required to add on textFields and it's siblings. */
+ private func addToolbarIfRequired() {
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ // Getting all the sibling textFields.
+ if let siblings = responderViews(), !siblings.isEmpty {
+
+ showLog("Found \(siblings.count) responder sibling(s)")
+
+ if let textField = _textFieldView {
+ //Either there is no inputAccessoryView or if accessoryView is not appropriate for current situation(There is Previous/Next/Done toolbar).
+ //setInputAccessoryView: check (Bug ID: #307)
+ if textField.responds(to: #selector(setter: UITextField.inputAccessoryView)) {
+
+ if textField.inputAccessoryView == nil ||
+ textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag ||
+ textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag {
+
+ let rightConfiguration : IQBarButtonItemConfiguration
+
+ if let doneBarButtonItemImage = toolbarDoneBarButtonItemImage {
+ rightConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.doneAction(_:)))
+ } else if let doneBarButtonItemText = toolbarDoneBarButtonItemText {
+ rightConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.doneAction(_:)))
+ } else {
+ rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: #selector(self.doneAction(_:)))
+ }
+
+ // If only one object is found, then adding only Done button.
+ if (siblings.count == 1 && previousNextDisplayMode == .Default) || previousNextDisplayMode == .alwaysHide {
+
+ textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder : nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil)
+
+ textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag // (Bug ID: #78)
+
+ } else if (siblings.count > 1 && previousNextDisplayMode == .Default) || previousNextDisplayMode == .alwaysShow {
+
+ let prevConfiguration : IQBarButtonItemConfiguration
+
+ if let doneBarButtonItemImage = toolbarPreviousBarButtonItemImage {
+ prevConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.previousAction(_:)))
+ } else if let doneBarButtonItemText = toolbarPreviousBarButtonItemText {
+ prevConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.previousAction(_:)))
+ } else {
+ prevConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardPreviousImage() ?? UIImage()), action: #selector(self.previousAction(_:)))
+ }
+
+ let nextConfiguration : IQBarButtonItemConfiguration
+
+ if let doneBarButtonItemImage = toolbarNextBarButtonItemImage {
+ nextConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.nextAction(_:)))
+ } else if let doneBarButtonItemText = toolbarNextBarButtonItemText {
+ nextConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.nextAction(_:)))
+ } else {
+ nextConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardNextImage() ?? UIImage()), action: #selector(self.nextAction(_:)))
+ }
+
+ textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder : nil), rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
+
+ textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag // (Bug ID: #78)
+ }
+
+ let toolbar = textField.keyboardToolbar
+
+ // Setting toolbar to keyboard.
+ if let _textField = textField as? UITextField {
+
+ //Bar style according to keyboard appearance
+ switch _textField.keyboardAppearance {
+
+ case .dark:
+ toolbar.barStyle = UIBarStyle.black
+ toolbar.tintColor = UIColor.white
+ toolbar.barTintColor = nil
+ default:
+ toolbar.barStyle = UIBarStyle.default
+ toolbar.barTintColor = toolbarBarTintColor
+
+ //Setting toolbar tintColor // (Enhancement ID: #30)
+ if shouldToolbarUsesTextFieldTintColor {
+ toolbar.tintColor = _textField.tintColor
+ } else if let tintColor = toolbarTintColor {
+ toolbar.tintColor = tintColor
+ } else {
+ toolbar.tintColor = UIColor.black
+ }
+ }
+ } else if let _textView = textField as? UITextView {
+
+ //Bar style according to keyboard appearance
+ switch _textView.keyboardAppearance {
+
+ case .dark:
+ toolbar.barStyle = UIBarStyle.black
+ toolbar.tintColor = UIColor.white
+ toolbar.barTintColor = nil
+ default:
+ toolbar.barStyle = UIBarStyle.default
+ toolbar.barTintColor = toolbarBarTintColor
+
+ if shouldToolbarUsesTextFieldTintColor {
+ toolbar.tintColor = _textView.tintColor
+ } else if let tintColor = toolbarTintColor {
+ toolbar.tintColor = tintColor
+ } else {
+ toolbar.tintColor = UIColor.black
+ }
+ }
+ }
+
+ //Setting toolbar title font. // (Enhancement ID: #30)
+ if shouldShowToolbarPlaceholder == true &&
+ textField.shouldHideToolbarPlaceholder == false {
+
+ //Updating placeholder font to toolbar. //(Bug ID: #148, #272)
+ if toolbar.titleBarButton.title == nil ||
+ toolbar.titleBarButton.title != textField.drawingToolbarPlaceholder {
+ toolbar.titleBarButton.title = textField.drawingToolbarPlaceholder
+ }
+
+ //Setting toolbar title font. // (Enhancement ID: #30)
+ if let font = placeholderFont {
+ toolbar.titleBarButton.titleFont = font
+ }
+
+ //Setting toolbar title color. // (Enhancement ID: #880)
+ if let color = placeholderColor {
+ toolbar.titleBarButton.titleColor = color
+ }
+
+ //Setting toolbar button title color. // (Enhancement ID: #880)
+ if let color = placeholderButtonColor {
+ toolbar.titleBarButton.selectableTitleColor = color
+ }
+
+ } else {
+
+ toolbar.titleBarButton.title = nil
+ }
+
+ //In case of UITableView (Special), the next/previous buttons has to be refreshed everytime. (Bug ID: #56)
+ // If firstTextField, then previous should not be enabled.
+ if siblings.first == textField {
+ if (siblings.count == 1) {
+ textField.keyboardToolbar.previousBarButton.isEnabled = false
+ textField.keyboardToolbar.nextBarButton.isEnabled = false
+ } else {
+ textField.keyboardToolbar.previousBarButton.isEnabled = false
+ textField.keyboardToolbar.nextBarButton.isEnabled = true
+ }
+ } else if siblings.last == textField { // If lastTextField then next should not be enaled.
+ textField.keyboardToolbar.previousBarButton.isEnabled = true
+ textField.keyboardToolbar.nextBarButton.isEnabled = false
+ } else {
+ textField.keyboardToolbar.previousBarButton.isEnabled = true
+ textField.keyboardToolbar.nextBarButton.isEnabled = true
+ }
+ }
+ }
+ }
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ /** Remove any toolbar if it is IQToolbar. */
+ private func removeToolbarIfRequired() { // (Bug ID: #18)
+
+ let startTime = CACurrentMediaTime()
+ showLog("****** \(#function) started ******")
+
+ // Getting all the sibling textFields.
+ if let siblings = responderViews() {
+
+ showLog("Found \(siblings.count) responder sibling(s)")
+
+ for view in siblings {
+
+ if let toolbar = view.inputAccessoryView as? IQToolbar {
+
+ //setInputAccessoryView: check (Bug ID: #307)
+ if view.responds(to: #selector(setter: UITextField.inputAccessoryView)) &&
+ (toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag || toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag) {
+
+ if let textField = view as? UITextField {
+ textField.inputAccessoryView = nil
+ textField.reloadInputViews()
+ } else if let textView = view as? UITextView {
+ textView.inputAccessoryView = nil
+ textView.reloadInputViews()
+ }
+ }
+ }
+ }
+ }
+
+ let elapsedTime = CACurrentMediaTime() - startTime
+ showLog("****** \(#function) ended: \(elapsedTime) seconds ******\n")
+ }
+
+ /** reloadInputViews to reload toolbar buttons enable/disable state on the fly Enhancement ID #434. */
+ @objc public func reloadInputViews() {
+
+ //If enabled then adding toolbar.
+ if privateIsEnableAutoToolbar() == true {
+ self.addToolbarIfRequired()
+ } else {
+ self.removeToolbarIfRequired()
+ }
+ }
+
+ ///------------------------------------
+ /// MARK: Debugging & Developer options
+ ///------------------------------------
+
+ @objc public var enableDebugging = false
+
+ /**
+ @warning Use below methods to completely enable/disable notifications registered by library internally. Please keep in mind that library is totally dependent on NSNotification of UITextField, UITextField, Keyboard etc. If you do unregisterAllNotifications then library will not work at all. You should only use below methods if you want to completedly disable all library functions. You should use below methods at your own risk.
+ */
+ @objc public func registerAllNotifications() {
+
+ #if swift(>=4.2)
+ let UIKeyboardWillShow = UIResponder.keyboardWillShowNotification
+ let UIKeyboardDidShow = UIResponder.keyboardDidShowNotification
+ let UIKeyboardWillHide = UIResponder.keyboardWillHideNotification
+ let UIKeyboardDidHide = UIResponder.keyboardDidHideNotification
+
+ let UITextFieldTextDidBeginEditing = UITextField.textDidBeginEditingNotification
+ let UITextFieldTextDidEndEditing = UITextField.textDidEndEditingNotification
+
+ let UITextViewTextDidBeginEditing = UITextView.textDidBeginEditingNotification
+ let UITextViewTextDidEndEditing = UITextView.textDidEndEditingNotification
+
+ let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
+ #else
+ let UIKeyboardWillShow = Notification.Name.UIKeyboardWillShow
+ let UIKeyboardDidShow = Notification.Name.UIKeyboardDidShow
+ let UIKeyboardWillHide = Notification.Name.UIKeyboardWillHide
+ let UIKeyboardDidHide = Notification.Name.UIKeyboardDidHide
+
+ let UITextFieldTextDidBeginEditing = Notification.Name.UITextFieldTextDidBeginEditing
+ let UITextFieldTextDidEndEditing = Notification.Name.UITextFieldTextDidEndEditing
+
+ let UITextViewTextDidBeginEditing = Notification.Name.UITextViewTextDidBeginEditing
+ let UITextViewTextDidEndEditing = Notification.Name.UITextViewTextDidEndEditing
+
+ let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
+ #endif
+
+ // Registering for keyboard notification.
+ NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIKeyboardWillShow, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: UIKeyboardDidShow, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIKeyboardWillHide, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidHide(_:)), name: UIKeyboardDidHide, object: nil)
+
+ // Registering for UITextField notification.
+ registerTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
+
+ // Registering for UITextView notification.
+ registerTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
+
+ // Registering for orientation changes notification
+ NotificationCenter.default.addObserver(self, selector: #selector(self.willChangeStatusBarOrientation(_:)), name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
+ }
+
+ @objc public func unregisterAllNotifications() {
+
+ #if swift(>=4.2)
+ let UIKeyboardWillShow = UIResponder.keyboardWillShowNotification
+ let UIKeyboardDidShow = UIResponder.keyboardDidShowNotification
+ let UIKeyboardWillHide = UIResponder.keyboardWillHideNotification
+ let UIKeyboardDidHide = UIResponder.keyboardDidHideNotification
+
+ let UITextFieldTextDidBeginEditing = UITextField.textDidBeginEditingNotification
+ let UITextFieldTextDidEndEditing = UITextField.textDidEndEditingNotification
+
+ let UITextViewTextDidBeginEditing = UITextView.textDidBeginEditingNotification
+ let UITextViewTextDidEndEditing = UITextView.textDidEndEditingNotification
+
+ let UIApplicationWillChangeStatusBarOrientation = UIApplication.willChangeStatusBarOrientationNotification
+ #else
+ let UIKeyboardWillShow = Notification.Name.UIKeyboardWillShow
+ let UIKeyboardDidShow = Notification.Name.UIKeyboardDidShow
+ let UIKeyboardWillHide = Notification.Name.UIKeyboardWillHide
+ let UIKeyboardDidHide = Notification.Name.UIKeyboardDidHide
+
+ let UITextFieldTextDidBeginEditing = Notification.Name.UITextFieldTextDidBeginEditing
+ let UITextFieldTextDidEndEditing = Notification.Name.UITextFieldTextDidEndEditing
+
+ let UITextViewTextDidBeginEditing = Notification.Name.UITextViewTextDidBeginEditing
+ let UITextViewTextDidEndEditing = Notification.Name.UITextViewTextDidEndEditing
+
+ let UIApplicationWillChangeStatusBarOrientation = Notification.Name.UIApplicationWillChangeStatusBarOrientation
+ #endif
+
+ // Unregistering for keyboard notification.
+ NotificationCenter.default.removeObserver(self, name: UIKeyboardWillShow, object: nil)
+ NotificationCenter.default.removeObserver(self, name: UIKeyboardDidShow, object: nil)
+ NotificationCenter.default.removeObserver(self, name: UIKeyboardWillHide, object: nil)
+ NotificationCenter.default.removeObserver(self, name: UIKeyboardDidHide, object: nil)
+
+ // Unregistering for UITextField notification.
+ unregisterTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextFieldTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextFieldTextDidEndEditing.rawValue)
+
+ // Unregistering for UITextView notification.
+ unregisterTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextViewTextDidBeginEditing.rawValue, didEndEditingNotificationName: UITextViewTextDidEndEditing.rawValue)
+
+ // Unregistering for orientation changes notification
+ NotificationCenter.default.removeObserver(self, name: UIApplicationWillChangeStatusBarOrientation, object: UIApplication.shared)
+ }
+
+ private func showLog(_ logString: String) {
+
+ if enableDebugging {
+ print("IQKeyboardManager: " + logString)
+ }
+ }
+}
+
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift
new file mode 100644
index 00000000..cd85eccb
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift
@@ -0,0 +1,628 @@
+//
+// IQKeyboardReturnKeyHandler.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import Foundation
+import UIKit
+
+fileprivate class IQTextFieldViewInfoModal : NSObject {
+
+ fileprivate weak var textFieldDelegate: UITextFieldDelegate?
+ fileprivate weak var textViewDelegate: UITextViewDelegate?
+ fileprivate weak var textFieldView: UIView?
+ fileprivate var originalReturnKeyType = UIReturnKeyType.default
+
+ init(textFieldView : UIView?, textFieldDelegate : UITextFieldDelegate?, textViewDelegate : UITextViewDelegate?, originalReturnKeyType : UIReturnKeyType = .default) {
+ self.textFieldView = textFieldView
+ self.textFieldDelegate = textFieldDelegate
+ self.textViewDelegate = textViewDelegate
+ self.originalReturnKeyType = originalReturnKeyType
+ }
+}
+
+/**
+Manages the return key to work like next/done in a view hierarchy.
+*/
+public class IQKeyboardReturnKeyHandler: NSObject , UITextFieldDelegate, UITextViewDelegate {
+
+
+ ///---------------
+ /// MARK: Settings
+ ///---------------
+
+ /**
+ Delegate of textField/textView.
+ */
+ @objc public weak var delegate: (UITextFieldDelegate & UITextViewDelegate)?
+
+ /**
+ Set the last textfield return key type. Default is UIReturnKeyDefault.
+ */
+ @objc public var lastTextFieldReturnKeyType : UIReturnKeyType = UIReturnKeyType.default {
+
+ didSet {
+
+ for modal in textFieldInfoCache {
+
+ if let view = modal.textFieldView {
+ updateReturnKeyTypeOnTextField(view)
+ }
+ }
+ }
+ }
+
+ ///--------------------------------------
+ /// MARK: Initialization/Deinitialization
+ ///--------------------------------------
+
+ @objc public override init() {
+ super.init()
+ }
+
+ /**
+ Add all the textFields available in UIViewController's view.
+ */
+ @objc public init(controller : UIViewController) {
+ super.init()
+
+ addResponderFromView(controller.view)
+ }
+
+ deinit {
+
+ for modal in textFieldInfoCache {
+
+ if let textField = modal.textFieldView as? UITextField {
+ textField.returnKeyType = modal.originalReturnKeyType
+
+ textField.delegate = modal.textFieldDelegate
+
+ } else if let textView = modal.textFieldView as? UITextView {
+
+ textView.returnKeyType = modal.originalReturnKeyType
+
+ textView.delegate = modal.textViewDelegate
+ }
+ }
+
+ textFieldInfoCache.removeAll()
+ }
+
+
+ ///------------------------
+ /// MARK: Private variables
+ ///------------------------
+ private var textFieldInfoCache = [IQTextFieldViewInfoModal]()
+
+ ///------------------------
+ /// MARK: Private Functions
+ ///------------------------
+ private func textFieldViewCachedInfo(_ textField : UIView) -> IQTextFieldViewInfoModal? {
+
+ for modal in textFieldInfoCache {
+
+ if let view = modal.textFieldView {
+
+ if view == textField {
+ return modal
+ }
+ }
+ }
+
+ return nil
+ }
+
+ private func updateReturnKeyTypeOnTextField(_ view : UIView)
+ {
+ var superConsideredView : UIView?
+
+ //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
+ for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
+
+ superConsideredView = view.superviewOfClassType(disabledClass)
+
+ if superConsideredView != nil {
+ break
+ }
+ }
+
+ var textFields = [UIView]()
+
+ //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
+ if let unwrappedTableView = superConsideredView { // (Enhancement ID: #22)
+ textFields = unwrappedTableView.deepResponderViews()
+ } else { //Otherwise fetching all the siblings
+
+ textFields = view.responderSiblings()
+
+ //Sorting textFields according to behaviour
+ switch IQKeyboardManager.shared.toolbarManageBehaviour {
+ //If needs to sort it by tag
+ case .byTag: textFields = textFields.sortedArrayByTag()
+ //If needs to sort it by Position
+ case .byPosition: textFields = textFields.sortedArrayByPosition()
+ default: break
+ }
+ }
+
+ if let lastView = textFields.last {
+
+ if let textField = view as? UITextField {
+
+ //If it's the last textField in responder view, else next
+ textField.returnKeyType = (view == lastView) ? lastTextFieldReturnKeyType : UIReturnKeyType.next
+ } else if let textView = view as? UITextView {
+
+ //If it's the last textField in responder view, else next
+ textView.returnKeyType = (view == lastView) ? lastTextFieldReturnKeyType : UIReturnKeyType.next
+ }
+ }
+ }
+
+
+ ///----------------------------------------------
+ /// MARK: Registering/Unregistering textFieldView
+ ///----------------------------------------------
+
+ /**
+ Should pass UITextField/UITextView intance. Assign textFieldView delegate to self, change it's returnKeyType.
+
+ @param view UITextField/UITextView object to register.
+ */
+ @objc public func addTextFieldView(_ view : UIView) {
+
+ let modal = IQTextFieldViewInfoModal(textFieldView: view, textFieldDelegate: nil, textViewDelegate: nil)
+
+ if let textField = view as? UITextField {
+
+ modal.originalReturnKeyType = textField.returnKeyType
+ modal.textFieldDelegate = textField.delegate
+ textField.delegate = self
+
+ } else if let textView = view as? UITextView {
+
+ modal.originalReturnKeyType = textView.returnKeyType
+ modal.textViewDelegate = textView.delegate
+ textView.delegate = self
+ }
+
+ textFieldInfoCache.append(modal)
+ }
+
+ /**
+ Should pass UITextField/UITextView intance. Restore it's textFieldView delegate and it's returnKeyType.
+
+ @param view UITextField/UITextView object to unregister.
+ */
+ @objc public func removeTextFieldView(_ view : UIView) {
+
+ if let modal = textFieldViewCachedInfo(view) {
+
+ if let textField = view as? UITextField {
+
+ textField.returnKeyType = modal.originalReturnKeyType
+ textField.delegate = modal.textFieldDelegate
+ } else if let textView = view as? UITextView {
+
+ textView.returnKeyType = modal.originalReturnKeyType
+ textView.delegate = modal.textViewDelegate
+ }
+
+ if let index = textFieldInfoCache.index(where: { $0.textFieldView == view}) {
+
+ textFieldInfoCache.remove(at: index)
+ }
+ }
+ }
+
+ /**
+ Add all the UITextField/UITextView responderView's.
+
+ @param view UIView object to register all it's responder subviews.
+ */
+ @objc public func addResponderFromView(_ view : UIView) {
+
+ let textFields = view.deepResponderViews()
+
+ for textField in textFields {
+
+ addTextFieldView(textField)
+ }
+ }
+
+ /**
+ Remove all the UITextField/UITextView responderView's.
+
+ @param view UIView object to unregister all it's responder subviews.
+ */
+ @objc public func removeResponderFromView(_ view : UIView) {
+
+ let textFields = view.deepResponderViews()
+
+ for textField in textFields {
+
+ removeTextFieldView(textField)
+ }
+ }
+
+ @discardableResult private func goToNextResponderOrResign(_ view : UIView) -> Bool {
+
+ var superConsideredView : UIView?
+
+ //If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347)
+ for disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses {
+
+ superConsideredView = view.superviewOfClassType(disabledClass)
+
+ if superConsideredView != nil {
+ break
+ }
+ }
+
+ var textFields = [UIView]()
+
+ //If there is a tableView in view's hierarchy, then fetching all it's subview that responds.
+ if let unwrappedTableView = superConsideredView { // (Enhancement ID: #22)
+ textFields = unwrappedTableView.deepResponderViews()
+ } else { //Otherwise fetching all the siblings
+
+ textFields = view.responderSiblings()
+
+ //Sorting textFields according to behaviour
+ switch IQKeyboardManager.shared.toolbarManageBehaviour {
+ //If needs to sort it by tag
+ case .byTag: textFields = textFields.sortedArrayByTag()
+ //If needs to sort it by Position
+ case .byPosition: textFields = textFields.sortedArrayByPosition()
+ default:
+ break
+ }
+ }
+
+ //Getting index of current textField.
+ if let index = textFields.index(of: view) {
+ //If it is not last textField. then it's next object becomeFirstResponder.
+ if index < (textFields.count - 1) {
+
+ let nextTextField = textFields[index+1]
+ nextTextField.becomeFirstResponder()
+ return false
+ } else {
+
+ view.resignFirstResponder()
+ return true
+ }
+ } else {
+ return true
+ }
+ }
+
+
+ ///---------------------------------------
+ /// MARK: UITextField/UITextView delegates
+ ///---------------------------------------
+
+ @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) {
+ return unwrapDelegate.textFieldShouldBeginEditing?(textField) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) {
+ return unwrapDelegate.textFieldShouldEndEditing?(textField) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @objc public func textFieldDidBeginEditing(_ textField: UITextField) {
+ updateReturnKeyTypeOnTextField(textField)
+
+ var aDelegate : UITextFieldDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textField) {
+ aDelegate = modal.textFieldDelegate
+ }
+ }
+
+ aDelegate?.textFieldDidBeginEditing?(textField)
+ }
+
+ @objc public func textFieldDidEndEditing(_ textField: UITextField) {
+
+ var aDelegate : UITextFieldDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textField) {
+ aDelegate = modal.textFieldDelegate
+ }
+ }
+
+ aDelegate?.textFieldDidEndEditing?(textField)
+ }
+
+ #if swift(>=4.2)
+ @available(iOS 10.0, *)
+ @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
+
+ var aDelegate : UITextFieldDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textField) {
+ aDelegate = modal.textFieldDelegate
+ }
+ }
+
+ aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
+ }
+ #else
+ @available(iOS 10.0, *)
+ @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
+
+ var aDelegate : UITextFieldDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textField) {
+ aDelegate = modal.textFieldDelegate
+ }
+ }
+
+ aDelegate?.textFieldDidEndEditing?(textField, reason: reason)
+ }
+ #endif
+
+ @objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn:replacementString:))) {
+ return unwrapDelegate.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == true
+ }
+ }
+ }
+ return true
+ }
+
+ @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) {
+ return unwrapDelegate.textFieldShouldClear?(textField) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+
+ @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+
+ var shouldReturn = true
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) {
+ shouldReturn = unwrapDelegate.textFieldShouldReturn?(textField) == true
+ }
+ }
+ }
+
+ if shouldReturn == true {
+ goToNextResponderOrResign(textField)
+ return true
+ } else {
+ return goToNextResponderOrResign(textField)
+ }
+ }
+
+
+ @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldBeginEditing(_:))) {
+ return unwrapDelegate.textViewShouldBeginEditing?(textView) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldEndEditing(_:))) {
+ return unwrapDelegate.textViewShouldEndEditing?(textView) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @objc public func textViewDidBeginEditing(_ textView: UITextView) {
+ updateReturnKeyTypeOnTextField(textView)
+
+ var aDelegate : UITextViewDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textView) {
+ aDelegate = modal.textViewDelegate
+ }
+ }
+
+ aDelegate?.textViewDidBeginEditing?(textView)
+ }
+
+ @objc public func textViewDidEndEditing(_ textView: UITextView) {
+
+ var aDelegate : UITextViewDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textView) {
+ aDelegate = modal.textViewDelegate
+ }
+ }
+
+ aDelegate?.textViewDidEndEditing?(textView)
+ }
+
+ @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
+
+ var shouldReturn = true
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:))) {
+ shouldReturn = (unwrapDelegate.textView?(textView, shouldChangeTextIn: range, replacementText: text)) == true
+ }
+ }
+ }
+
+ if shouldReturn == true && text == "\n" {
+ shouldReturn = goToNextResponderOrResign(textView)
+ }
+
+ return shouldReturn
+ }
+
+ @objc public func textViewDidChange(_ textView: UITextView) {
+
+ var aDelegate : UITextViewDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textView) {
+ aDelegate = modal.textViewDelegate
+ }
+ }
+
+ aDelegate?.textViewDidChange?(textView)
+ }
+
+ @objc public func textViewDidChangeSelection(_ textView: UITextView) {
+
+ var aDelegate : UITextViewDelegate? = delegate
+
+ if aDelegate == nil {
+
+ if let modal = textFieldViewCachedInfo(textView) {
+ aDelegate = modal.textViewDelegate
+ }
+ }
+
+ aDelegate?.textViewDidChangeSelection?(textView)
+ }
+
+ @available(iOS 10.0, *)
+ @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange, UITextItemInteraction) -> Bool)) {
+ return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange, interaction: interaction) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @available(iOS 10.0, *)
+ @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) -> Bool)) {
+ return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @available(iOS, deprecated: 10.0)
+ @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange) -> Bool)) {
+ return unwrapDelegate.textView?(aTextView, shouldInteractWith: URL, in: characterRange) == true
+ }
+ }
+ }
+
+ return true
+ }
+
+ @available(iOS, deprecated: 10.0)
+ @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool {
+
+ if delegate == nil {
+
+ if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate {
+ if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange) -> Bool)) {
+ return unwrapDelegate.textView?(aTextView, shouldInteractWith: textAttachment, in: characterRange) == true
+ }
+ }
+ }
+
+ return true
+ }
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift
new file mode 100644
index 00000000..3f7ec316
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift
@@ -0,0 +1,209 @@
+//
+// IQTextView.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import UIKit
+
+/** @abstract UITextView with placeholder support */
+open class IQTextView : UITextView {
+
+ @objc required public init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ #if swift(>=4.2)
+ let UITextViewTextDidChange = UITextView.textDidChangeNotification
+ #else
+ let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange
+ #endif
+
+ NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name:UITextViewTextDidChange, object: self)
+ }
+
+ @objc override public init(frame: CGRect, textContainer: NSTextContainer?) {
+ super.init(frame: frame, textContainer: textContainer)
+
+ #if swift(>=4.2)
+ let notificationName = UITextView.textDidChangeNotification
+ #else
+ let notificationName = Notification.Name.UITextViewTextDidChange
+ #endif
+
+ NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: notificationName, object: self)
+ }
+
+ @objc override open func awakeFromNib() {
+ super.awakeFromNib()
+
+ #if swift(>=4.2)
+ let UITextViewTextDidChange = UITextView.textDidChangeNotification
+ #else
+ let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange
+ #endif
+
+ NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
+ }
+
+ deinit {
+ placeholderLabel.removeFromSuperview()
+ NotificationCenter.default.removeObserver(self)
+ }
+
+ private var placeholderInsets : UIEdgeInsets {
+ return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding)
+ }
+
+ private var placeholderExpectedFrame : CGRect {
+ let placeholderInsets = self.placeholderInsets
+ let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right
+ let expectedSize = placeholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom))
+
+ return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height)
+ }
+
+ lazy var placeholderLabel: UILabel = {
+ let label = UILabel()
+
+ label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ label.lineBreakMode = .byWordWrapping
+ label.numberOfLines = 0
+ label.font = self.font
+ label.textAlignment = self.textAlignment
+ label.backgroundColor = UIColor.clear
+ label.textColor = UIColor(white: 0.7, alpha: 1.0)
+ label.alpha = 0
+ self.addSubview(label)
+
+ return label
+ }()
+
+ /** @abstract To set textView's placeholder text color. */
+ @IBInspectable open var placeholderTextColor : UIColor? {
+
+ get {
+ return placeholderLabel.textColor
+ }
+
+ set {
+ placeholderLabel.textColor = newValue
+ }
+ }
+
+ /** @abstract To set textView's placeholder text. Default is nil. */
+ @IBInspectable open var placeholder : String? {
+
+ get {
+ return placeholderLabel.text
+ }
+
+ set {
+ placeholderLabel.text = newValue
+ refreshPlaceholder()
+ }
+ }
+
+ /** @abstract To set textView's placeholder attributed text. Default is nil. */
+ open var attributedPlaceholder: NSAttributedString? {
+ get {
+ return placeholderLabel.attributedText
+ }
+
+ set {
+ placeholderLabel.attributedText = newValue
+ refreshPlaceholder()
+ }
+ }
+
+ @objc override open func layoutSubviews() {
+ super.layoutSubviews()
+
+ placeholderLabel.frame = placeholderExpectedFrame
+ }
+
+ @objc internal func refreshPlaceholder() {
+
+ if !text.isEmpty || !attributedText.string.isEmpty {
+ placeholderLabel.alpha = 0
+ } else {
+ placeholderLabel.alpha = 1
+ }
+ }
+
+ @objc override open var text: String! {
+
+ didSet {
+ refreshPlaceholder()
+ }
+ }
+
+ open override var attributedText: NSAttributedString! {
+
+ didSet {
+ refreshPlaceholder()
+ }
+ }
+
+ @objc override open var font : UIFont? {
+
+ didSet {
+
+ if let unwrappedFont = font {
+ placeholderLabel.font = unwrappedFont
+ } else {
+ placeholderLabel.font = UIFont.systemFont(ofSize: 12)
+ }
+ }
+ }
+
+ @objc override open var textAlignment: NSTextAlignment
+ {
+ didSet {
+ placeholderLabel.textAlignment = textAlignment
+ }
+ }
+
+ @objc override open var delegate : UITextViewDelegate? {
+
+ get {
+ refreshPlaceholder()
+ return super.delegate
+ }
+
+ set {
+ super.delegate = newValue
+ }
+ }
+
+ @objc override open var intrinsicContentSize: CGSize {
+ guard !hasText else {
+ return super.intrinsicContentSize
+ }
+
+ var newSize = super.intrinsicContentSize
+ let placeholderInsets = self.placeholderInsets
+ newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom
+
+ return newSize
+ }
+}
+
+
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift
new file mode 100644
index 00000000..77bd00a9
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift
@@ -0,0 +1,136 @@
+//
+// IQBarButtonItem.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import UIKit
+import Foundation
+
+open class IQBarButtonItem: UIBarButtonItem {
+
+ private static var _classInitialize: Void = classInitialize()
+
+ @objc public override init() {
+ _ = IQBarButtonItem._classInitialize
+ super.init()
+ }
+
+ @objc public required init?(coder aDecoder: NSCoder) {
+ _ = IQBarButtonItem._classInitialize
+ super.init(coder: aDecoder)
+ }
+
+
+ private class func classInitialize() {
+
+ let appearanceProxy = self.appearance()
+
+ #if swift(>=4.2)
+ let states : [UIControl.State]
+ #else
+ let states : [UIControlState]
+ #endif
+
+ states = [.normal,.highlighted,.disabled,.selected,.application,.reserved]
+
+ for state in states {
+
+ appearanceProxy.setBackgroundImage(nil, for: state, barMetrics: .default)
+ appearanceProxy.setBackgroundImage(nil, for: state, style: .done, barMetrics: .default)
+ appearanceProxy.setBackgroundImage(nil, for: state, style: .plain, barMetrics: .default)
+ appearanceProxy.setBackButtonBackgroundImage(nil, for: state, barMetrics: .default)
+ }
+
+ appearanceProxy.setTitlePositionAdjustment(UIOffset(), for: .default)
+ appearanceProxy.setBackgroundVerticalPositionAdjustment(0, for: .default)
+ appearanceProxy.setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default)
+ }
+
+ @objc override open var tintColor: UIColor? {
+ didSet {
+
+ #if swift(>=4.2)
+ var textAttributes = [NSAttributedString.Key : Any]()
+ let foregroundColorKey = NSAttributedString.Key.foregroundColor
+ #elseif swift(>=4)
+ var textAttributes = [NSAttributedStringKey : Any]()
+ let foregroundColorKey = NSAttributedStringKey.foregroundColor
+ #else
+ var textAttributes = [String:Any]()
+ let foregroundColorKey = NSForegroundColorAttributeName
+ #endif
+
+ textAttributes[foregroundColorKey] = tintColor
+
+ #if swift(>=4)
+
+ if let attributes = titleTextAttributes(for: .normal) {
+
+ for (key, value) in attributes {
+ #if swift(>=4.2)
+ textAttributes[key] = value
+ #else
+ textAttributes[NSAttributedStringKey.init(key)] = value
+ #endif
+ }
+ }
+
+ #else
+
+ if let attributes = titleTextAttributes(for: .normal) {
+ textAttributes = attributes
+ }
+ #endif
+
+ setTitleTextAttributes(textAttributes, for: .normal)
+ }
+ }
+
+ /**
+ Boolean to know if it's a system item or custom item, we are having a limitation that we cannot override a designated initializer, so we are manually setting this property once in initialization
+ */
+ @objc internal var isSystemItem = false
+
+ /**
+ Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback.
+
+ @param target Target object.
+ @param action Target Selector.
+ */
+ @objc open func setTarget(_ target: AnyObject?, action: Selector?) {
+ if let target = target, let action = action {
+ invocation = IQInvocation(target, action)
+ } else {
+ invocation = nil
+ }
+ }
+
+ /**
+ Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method.
+ */
+ @objc open var invocation : IQInvocation?
+
+ deinit {
+ target = nil
+ invocation = nil
+ }
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift
new file mode 100644
index 00000000..cb28e131
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift
@@ -0,0 +1,45 @@
+//
+// IQInvocation.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import UIKit
+
+public class IQInvocation : NSObject {
+ public weak var target: AnyObject?
+ public var action: Selector
+
+ @objc public init(_ target: AnyObject, _ action: Selector) {
+ self.target = target
+ self.action = action
+ }
+
+ @objc public func invoke(from: Any) {
+ if let target = target {
+ UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent())
+ }
+ }
+
+ deinit {
+ target = nil
+ }
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift
new file mode 100644
index 00000000..fb6a879e
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift
@@ -0,0 +1,28 @@
+//
+// IQPreviousNextView.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import UIKit
+
+public class IQPreviousNextView: UIView {
+
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift
new file mode 100644
index 00000000..984f80ff
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift
@@ -0,0 +1,178 @@
+//
+// IQTitleBarButtonItem.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import Foundation
+import UIKit
+
+open class IQTitleBarButtonItem: IQBarButtonItem {
+
+ @objc open var titleFont : UIFont? {
+
+ didSet {
+ if let unwrappedFont = titleFont {
+ titleButton?.titleLabel?.font = unwrappedFont
+ } else {
+ titleButton?.titleLabel?.font = UIFont.systemFont(ofSize: 13)
+ }
+ }
+ }
+
+ @objc override open var title: String? {
+ didSet {
+ titleButton?.setTitle(title, for: .normal)
+ }
+ }
+
+ /**
+ titleColor to be used for displaying button text when displaying title (disabled state).
+ */
+ @objc open var titleColor : UIColor? {
+
+ didSet {
+
+ if let color = titleColor {
+ titleButton?.setTitleColor(color, for:.disabled)
+ } else {
+ titleButton?.setTitleColor(UIColor.lightGray, for:.disabled)
+ }
+ }
+ }
+
+ /**
+ selectableTitleColor to be used for displaying button text when button is enabled.
+ */
+ @objc open var selectableTitleColor : UIColor? {
+
+ didSet {
+
+ if let color = selectableTitleColor {
+ titleButton?.setTitleColor(color, for:.normal)
+ } else {
+ titleButton?.setTitleColor(UIColor.init(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for:.normal)
+ }
+ }
+ }
+
+ /**
+ Customized Invocation to be called on title button action. titleInvocation is internally created using setTitleTarget:action: method.
+ */
+ @objc override open var invocation : IQInvocation? {
+
+ didSet {
+
+ if let target = invocation?.target, let action = invocation?.action {
+ self.isEnabled = true
+ titleButton?.isEnabled = true
+ titleButton?.addTarget(target, action: action, for: .touchUpInside)
+ } else {
+ self.isEnabled = false
+ titleButton?.isEnabled = false
+ titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)
+ }
+ }
+ }
+
+ internal var titleButton : UIButton?
+ private var _titleView : UIView?
+
+ override init() {
+ super.init()
+ }
+
+ @objc public convenience init(title : String?) {
+
+ self.init(title: nil, style: .plain, target: nil, action: nil)
+
+ _titleView = UIView()
+ _titleView?.backgroundColor = UIColor.clear
+
+ titleButton = UIButton(type: .system)
+ titleButton?.isEnabled = false
+ titleButton?.titleLabel?.numberOfLines = 3
+ titleButton?.setTitleColor(UIColor.lightGray, for:.disabled)
+ titleButton?.setTitleColor(UIColor.init(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for:.normal)
+ titleButton?.backgroundColor = UIColor.clear
+ titleButton?.titleLabel?.textAlignment = .center
+ titleButton?.setTitle(title, for: .normal)
+ titleFont = UIFont.systemFont(ofSize: 13.0)
+ titleButton?.titleLabel?.font = self.titleFont
+ _titleView?.addSubview(titleButton!)
+
+#if swift(>=3.2)
+ if #available(iOS 11, *) {
+
+ var layoutDefaultLowPriority : UILayoutPriority
+ var layoutDefaultHighPriority : UILayoutPriority
+
+ #if swift(>=4.0)
+ let layoutPriorityLowValue = UILayoutPriority.defaultLow.rawValue-1
+ let layoutPriorityHighValue = UILayoutPriority.defaultHigh.rawValue-1
+ layoutDefaultLowPriority = UILayoutPriority(rawValue: layoutPriorityLowValue)
+ layoutDefaultHighPriority = UILayoutPriority(rawValue: layoutPriorityHighValue)
+ #else
+ layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1
+ layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1
+ #endif
+
+ _titleView?.translatesAutoresizingMaskIntoConstraints = false
+ _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
+ _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
+ _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
+ _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
+
+ titleButton?.translatesAutoresizingMaskIntoConstraints = false
+ titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
+ titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
+ titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
+ titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
+
+ let top = NSLayoutConstraint.init(item: titleButton!, attribute: .top, relatedBy: .equal, toItem: _titleView, attribute: .top, multiplier: 1, constant: 0)
+ let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0)
+ let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0)
+ let trailing = NSLayoutConstraint.init(item: titleButton!, attribute: .trailing, relatedBy: .equal, toItem: _titleView, attribute: .trailing, multiplier: 1, constant: 0)
+
+ _titleView?.addConstraints([top,bottom,leading,trailing])
+ } else {
+ _titleView?.autoresizingMask = [.flexibleWidth,.flexibleHeight]
+ titleButton?.autoresizingMask = [.flexibleWidth,.flexibleHeight]
+ }
+#else
+ _titleView?.autoresizingMask = [.flexibleWidth,.flexibleHeight]
+ titleButton?.autoresizingMask = [.flexibleWidth,.flexibleHeight]
+#endif
+
+ customView = _titleView
+ }
+
+ @objc required public init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+
+ deinit {
+ customView = nil
+ titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)
+ _titleView = nil
+ titleButton = nil
+ }
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift
new file mode 100644
index 00000000..808bb8e9
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift
@@ -0,0 +1,369 @@
+//
+// IQToolbar.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import UIKit
+
+/** @abstract IQToolbar for IQKeyboardManager. */
+open class IQToolbar: UIToolbar , UIInputViewAudioFeedback {
+
+ private static var _classInitialize: Void = classInitialize()
+
+ private class func classInitialize() {
+
+ let appearanceProxy = self.appearance()
+
+ appearanceProxy.barTintColor = nil
+
+ let positions : [UIBarPosition] = [.any,.bottom,.top,.topAttached]
+
+ for position in positions {
+
+ appearanceProxy.setBackgroundImage(nil, forToolbarPosition: position, barMetrics: .default)
+ appearanceProxy.setShadowImage(nil, forToolbarPosition: .any)
+ }
+
+ //Background color
+ appearanceProxy.backgroundColor = nil
+ }
+
+ /**
+ Previous bar button of toolbar.
+ */
+ private var privatePreviousBarButton: IQBarButtonItem?
+ @objc open var previousBarButton : IQBarButtonItem {
+ get {
+ if privatePreviousBarButton == nil {
+ privatePreviousBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
+ privatePreviousBarButton?.accessibilityLabel = "Toolbar Previous Button"
+ }
+ return privatePreviousBarButton!
+ }
+
+ set (newValue) {
+ privatePreviousBarButton = newValue
+ }
+ }
+
+ /**
+ Next bar button of toolbar.
+ */
+ private var privateNextBarButton: IQBarButtonItem?
+ @objc open var nextBarButton : IQBarButtonItem {
+ get {
+ if privateNextBarButton == nil {
+ privateNextBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
+ privateNextBarButton?.accessibilityLabel = "Toolbar Next Button"
+ }
+ return privateNextBarButton!
+ }
+
+ set (newValue) {
+ privateNextBarButton = newValue
+ }
+ }
+
+ /**
+ Title bar button of toolbar.
+ */
+ private var privateTitleBarButton: IQTitleBarButtonItem?
+ @objc open var titleBarButton : IQTitleBarButtonItem {
+ get {
+ if privateTitleBarButton == nil {
+ privateTitleBarButton = IQTitleBarButtonItem(title: nil)
+ privateTitleBarButton?.accessibilityLabel = "Toolbar Title Button"
+ }
+ return privateTitleBarButton!
+ }
+
+ set (newValue) {
+ privateTitleBarButton = newValue
+ }
+ }
+
+ /**
+ Done bar button of toolbar.
+ */
+ private var privateDoneBarButton: IQBarButtonItem?
+ @objc open var doneBarButton : IQBarButtonItem {
+ get {
+ if privateDoneBarButton == nil {
+ privateDoneBarButton = IQBarButtonItem(title: nil, style: .done, target: nil, action: nil)
+ privateDoneBarButton?.accessibilityLabel = "Toolbar Done Button"
+ }
+ return privateDoneBarButton!
+ }
+
+ set (newValue) {
+ privateDoneBarButton = newValue
+ }
+ }
+
+ /**
+ Fixed space bar button of toolbar.
+ */
+ private var privateFixedSpaceBarButton: IQBarButtonItem?
+ @objc open var fixedSpaceBarButton : IQBarButtonItem {
+ get {
+ if privateFixedSpaceBarButton == nil {
+ privateFixedSpaceBarButton = IQBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
+ }
+ privateFixedSpaceBarButton!.isSystemItem = true
+
+ if #available(iOS 10, *) {
+ privateFixedSpaceBarButton!.width = 6
+ } else {
+ privateFixedSpaceBarButton!.width = 20
+ }
+
+ return privateFixedSpaceBarButton!
+ }
+
+ set (newValue) {
+ privateFixedSpaceBarButton = newValue
+ }
+ }
+
+ override init(frame: CGRect) {
+ _ = IQToolbar._classInitialize
+ super.init(frame: frame)
+
+ sizeToFit()
+
+ autoresizingMask = .flexibleWidth
+ self.isTranslucent = true
+ }
+
+ @objc required public init?(coder aDecoder: NSCoder) {
+ _ = IQToolbar._classInitialize
+ super.init(coder: aDecoder)
+
+ sizeToFit()
+
+ autoresizingMask = .flexibleWidth
+ self.isTranslucent = true
+ }
+
+ @objc override open func sizeThatFits(_ size: CGSize) -> CGSize {
+ var sizeThatFit = super.sizeThatFits(size)
+ sizeThatFit.height = 44
+ return sizeThatFit
+ }
+
+ @objc override open var tintColor: UIColor! {
+
+ didSet {
+ if let unwrappedItems = items {
+ for item in unwrappedItems {
+ item.tintColor = tintColor
+ }
+ }
+ }
+ }
+
+ @objc override open var barStyle: UIBarStyle {
+ didSet {
+
+ if titleBarButton.selectableTitleColor == nil {
+ if barStyle == .default {
+ titleBarButton.titleButton?.setTitleColor(UIColor.init(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal)
+ } else {
+ titleBarButton.titleButton?.setTitleColor(UIColor.yellow, for: .normal)
+ }
+ }
+ }
+ }
+
+ @objc override open func layoutSubviews() {
+
+ super.layoutSubviews()
+
+ //If running on Xcode9 (iOS11) only then we'll validate for iOS version, otherwise for older versions of Xcode (iOS10 and below) we'll just execute the tweak
+#if swift(>=3.2)
+
+ if #available(iOS 11, *) {
+ return
+ } else if let customTitleView = titleBarButton.customView {
+ var leftRect = CGRect.null
+ var rightRect = CGRect.null
+ var isTitleBarButtonFound = false
+
+ let sortedSubviews = self.subviews.sorted(by: { (view1 : UIView, view2 : UIView) -> Bool in
+
+ let x1 = view1.frame.minX
+ let y1 = view1.frame.minY
+ let x2 = view2.frame.minX
+ let y2 = view2.frame.minY
+
+ if x1 != x2 {
+ return x1 < x2
+ } else {
+ return y1 < y2
+ }
+ })
+
+ for barButtonItemView in sortedSubviews {
+
+ if isTitleBarButtonFound == true {
+ rightRect = barButtonItemView.frame
+ break
+ } else if barButtonItemView === customTitleView {
+ isTitleBarButtonFound = true
+ //If it's UIToolbarButton or UIToolbarTextButton (which actually UIBarButtonItem)
+ } else if barButtonItemView.isKind(of: UIControl.self) == true {
+ leftRect = barButtonItemView.frame
+ }
+ }
+
+ let titleMargin : CGFloat = 16
+
+ let maxWidth : CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
+ let maxHeight = self.frame.height
+
+ let sizeThatFits = customTitleView.sizeThatFits(CGSize(width: maxWidth, height: maxHeight))
+
+ var titleRect : CGRect
+
+ if sizeThatFits.width > 0 && sizeThatFits.height > 0 {
+ let width = min(sizeThatFits.width, maxWidth)
+ let height = min(sizeThatFits.height, maxHeight)
+
+ var x : CGFloat
+
+ if (leftRect.isNull == false) {
+ x = titleMargin + leftRect.maxX + ((maxWidth - width)/2)
+ } else {
+ x = titleMargin
+ }
+
+ let y = (maxHeight - height)/2
+
+ titleRect = CGRect(x: x, y: y, width: width, height: height)
+ } else {
+
+ var x : CGFloat
+
+ if (leftRect.isNull == false) {
+ x = titleMargin + leftRect.maxX
+ } else {
+ x = titleMargin
+ }
+
+ let width : CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
+
+ titleRect = CGRect(x: x, y: 0, width: width, height: maxHeight)
+ }
+
+ customTitleView.frame = titleRect
+ }
+
+#else
+ if let customTitleView = titleBarButton.customView {
+ var leftRect = CGRect.null
+ var rightRect = CGRect.null
+ var isTitleBarButtonFound = false
+
+ let sortedSubviews = self.subviews.sorted(by: { (view1 : UIView, view2 : UIView) -> Bool in
+
+ let x1 = view1.frame.minX
+ let y1 = view1.frame.minY
+ let x2 = view2.frame.minX
+ let y2 = view2.frame.minY
+
+ if x1 != x2 {
+ return x1 < x2
+ } else {
+ return y1 < y2
+ }
+ })
+
+ for barButtonItemView in sortedSubviews {
+
+ if isTitleBarButtonFound == true {
+ rightRect = barButtonItemView.frame
+ break
+ } else if barButtonItemView === titleBarButton.customView {
+ isTitleBarButtonFound = true
+ //If it's UIToolbarButton or UIToolbarTextButton (which actually UIBarButtonItem)
+ } else if barButtonItemView.isKind(of: UIControl.self) == true {
+ leftRect = barButtonItemView.frame
+ }
+ }
+
+ let titleMargin : CGFloat = 16
+ let maxWidth : CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
+ let maxHeight = self.frame.height
+
+ let sizeThatFits = customTitleView.sizeThatFits(CGSize(width: maxWidth, height: maxHeight))
+
+ var titleRect : CGRect
+
+ if sizeThatFits.width > 0 && sizeThatFits.height > 0 {
+ let width = min(sizeThatFits.width, maxWidth)
+ let height = min(sizeThatFits.height, maxHeight)
+
+ var x : CGFloat
+
+ if (leftRect.isNull == false) {
+ x = titleMargin + leftRect.maxX + ((maxWidth - width)/2)
+ } else {
+ x = titleMargin
+ }
+
+ let y = (maxHeight - height)/2
+
+ titleRect = CGRect(x: x, y: y, width: width, height: height)
+ } else {
+
+ var x : CGFloat
+
+ if (leftRect.isNull == false) {
+ x = titleMargin + leftRect.maxX
+ } else {
+ x = titleMargin
+ }
+
+ let width : CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
+
+ titleRect = CGRect(x: x, y: 0, width: width, height: maxHeight)
+ }
+
+ customTitleView.frame = titleRect
+ }
+#endif
+ }
+
+ @objc open var enableInputClicksWhenVisible: Bool {
+ return true
+ }
+
+ deinit {
+
+ items = nil
+ privatePreviousBarButton = nil
+ privateNextBarButton = nil
+ privateTitleBarButton = nil
+ privateDoneBarButton = nil
+ privateFixedSpaceBarButton = nil
+ }
+}
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift
new file mode 100644
index 00000000..a59c7fb5
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift
@@ -0,0 +1,612 @@
+//
+// IQUIView+IQKeyboardToolbar.swift
+// https://github.com/hackiftekhar/IQKeyboardManager
+// Copyright (c) 2013-16 Iftekhar Qurashi.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+import UIKit
+
+private var kIQShouldHideToolbarPlaceholder = "kIQShouldHideToolbarPlaceholder"
+private var kIQToolbarPlaceholder = "kIQToolbarPlaceholder"
+
+private var kIQKeyboardToolbar = "kIQKeyboardToolbar"
+
+/**
+ IQBarButtonItemConfiguration for creating toolbar with bar button items
+ */
+public class IQBarButtonItemConfiguration : NSObject {
+
+ #if swift(>=4.2)
+ public init(barButtonSystemItem : UIBarButtonItem.SystemItem, action: Selector) {
+ self.barButtonSystemItem = barButtonSystemItem
+ self.image = nil
+ self.title = nil
+ self.action = action
+ super.init()
+ }
+ #else
+ public init(barButtonSystemItem : UIBarButtonSystemItem, action: Selector) {
+ self.barButtonSystemItem = barButtonSystemItem
+ self.image = nil
+ self.title = nil
+ self.action = action
+ super.init()
+ }
+ #endif
+
+ public init(image : UIImage, action: Selector) {
+ self.barButtonSystemItem = nil
+ self.image = image
+ self.title = nil
+ self.action = action
+ super.init()
+ }
+
+ public init(title : String, action: Selector) {
+ self.barButtonSystemItem = nil
+ self.image = nil
+ self.title = title
+ self.action = action
+ super.init()
+ }
+
+ #if swift(>=4.2)
+ public let barButtonSystemItem : UIBarButtonItem.SystemItem? //System Item to be used to instantiate bar button.
+ #else
+ public let barButtonSystemItem : UIBarButtonSystemItem? //System Item to be used to instantiate bar button.
+ #endif
+
+ public let image : UIImage? //Image to show on bar button item if it's not a system item.
+
+ public let title : String? //Title to show on bar button item if it's not a system item.
+
+ public let action : Selector? //action for bar button item. Usually 'doneAction:(IQBarButtonItem*)item'.
+}
+
+/**
+ UIImage category methods to get next/prev images
+ */
+extension UIImage {
+
+ public static func keyboardPreviousiOS9Image() -> UIImage? {
+
+ struct Static {
+ static var keyboardPreviousiOS9Image : UIImage?
+ }
+
+ if Static.keyboardPreviousiOS9Image == nil {
+ // Get the top level "bundle" which may actually be the framework
+ var bundle = Bundle(for: IQKeyboardManager.self)
+
+ if let resourcePath = bundle.path(forResource: "IQKeyboardManager", ofType: "bundle") {
+ if let resourcesBundle = Bundle(path: resourcePath) {
+ bundle = resourcesBundle
+ }
+ }
+
+ Static.keyboardPreviousiOS9Image = UIImage(named: "IQButtonBarArrowLeft", in: bundle, compatibleWith: nil)
+
+ //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
+ if #available(iOS 9, *) {
+ Static.keyboardPreviousiOS9Image = Static.keyboardPreviousiOS9Image?.imageFlippedForRightToLeftLayoutDirection()
+ }
+ }
+
+ return Static.keyboardPreviousiOS9Image
+ }
+
+ public static func keyboardNextiOS9Image() -> UIImage? {
+
+ struct Static {
+ static var keyboardNextiOS9Image : UIImage?
+ }
+
+ if Static.keyboardNextiOS9Image == nil {
+ // Get the top level "bundle" which may actually be the framework
+ var bundle = Bundle(for: IQKeyboardManager.self)
+
+ if let resourcePath = bundle.path(forResource: "IQKeyboardManager", ofType: "bundle") {
+ if let resourcesBundle = Bundle(path: resourcePath) {
+ bundle = resourcesBundle
+ }
+ }
+
+ Static.keyboardNextiOS9Image = UIImage(named: "IQButtonBarArrowRight", in: bundle, compatibleWith: nil)
+
+ //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
+ if #available(iOS 9, *) {
+ Static.keyboardNextiOS9Image = Static.keyboardNextiOS9Image?.imageFlippedForRightToLeftLayoutDirection()
+ }
+ }
+
+ return Static.keyboardNextiOS9Image
+ }
+
+ public static func keyboardPreviousiOS10Image() -> UIImage? {
+
+ struct Static {
+ static var keyboardPreviousiOS10Image : UIImage?
+ }
+
+ if Static.keyboardPreviousiOS10Image == nil {
+ // Get the top level "bundle" which may actually be the framework
+ var bundle = Bundle(for: IQKeyboardManager.self)
+
+ if let resourcePath = bundle.path(forResource: "IQKeyboardManager", ofType: "bundle") {
+ if let resourcesBundle = Bundle(path: resourcePath) {
+ bundle = resourcesBundle
+ }
+ }
+
+ Static.keyboardPreviousiOS10Image = UIImage(named: "IQButtonBarArrowUp", in: bundle, compatibleWith: nil)
+
+ //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
+ if #available(iOS 9, *) {
+ Static.keyboardPreviousiOS10Image = Static.keyboardPreviousiOS10Image?.imageFlippedForRightToLeftLayoutDirection()
+ }
+ }
+
+ return Static.keyboardPreviousiOS10Image
+ }
+
+ public static func keyboardNextiOS10Image() -> UIImage? {
+
+ struct Static {
+ static var keyboardNextiOS10Image : UIImage?
+ }
+
+ if Static.keyboardNextiOS10Image == nil {
+ // Get the top level "bundle" which may actually be the framework
+ var bundle = Bundle(for: IQKeyboardManager.self)
+
+ if let resourcePath = bundle.path(forResource: "IQKeyboardManager", ofType: "bundle") {
+ if let resourcesBundle = Bundle(path: resourcePath) {
+ bundle = resourcesBundle
+ }
+ }
+
+ Static.keyboardNextiOS10Image = UIImage(named: "IQButtonBarArrowDown", in: bundle, compatibleWith: nil)
+
+ //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
+ if #available(iOS 9, *) {
+ Static.keyboardNextiOS10Image = Static.keyboardNextiOS10Image?.imageFlippedForRightToLeftLayoutDirection()
+ }
+ }
+
+ return Static.keyboardNextiOS10Image
+ }
+
+ public static func keyboardPreviousImage() -> UIImage? {
+
+ if #available(iOS 10, *) {
+ return keyboardPreviousiOS10Image()
+ } else {
+ return keyboardPreviousiOS9Image()
+ }
+ }
+
+ public static func keyboardNextImage() -> UIImage? {
+
+ if #available(iOS 10, *) {
+ return keyboardNextiOS10Image()
+ } else {
+ return keyboardNextiOS9Image()
+ }
+ }
+}
+
+/**
+UIView category methods to add IQToolbar on UIKeyboard.
+*/
+public extension UIView {
+
+ ///--------------
+ /// MARK: Toolbar
+ ///--------------
+
+ /**
+ IQToolbar references for better customization control.
+ */
+ public var keyboardToolbar: IQToolbar {
+ var toolbar = inputAccessoryView as? IQToolbar
+
+ if (toolbar == nil)
+ {
+ toolbar = objc_getAssociatedObject(self, &kIQKeyboardToolbar) as? IQToolbar
+ }
+
+ if let unwrappedToolbar = toolbar {
+
+ return unwrappedToolbar
+
+ } else {
+
+ let newToolbar = IQToolbar()
+
+ objc_setAssociatedObject(self, &kIQKeyboardToolbar, newToolbar, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+
+ return newToolbar
+ }
+ }
+
+ ///--------------------
+ /// MARK: Toolbar title
+ ///--------------------
+
+ /**
+ If `shouldHideToolbarPlaceholder` is YES, then title will not be added to the toolbar. Default to NO.
+ */
+ @objc public var shouldHideToolbarPlaceholder: Bool {
+ get {
+ let aValue = objc_getAssociatedObject(self, &kIQShouldHideToolbarPlaceholder) as Any?
+
+ if let unwrapedValue = aValue as? Bool {
+ return unwrapedValue
+ } else {
+ return false
+ }
+ }
+ set(newValue) {
+ objc_setAssociatedObject(self, &kIQShouldHideToolbarPlaceholder, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+
+ self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder
+ }
+ }
+
+ /**
+ `toolbarPlaceholder` to override default `placeholder` text when drawing text on toolbar.
+ */
+ @objc public var toolbarPlaceholder: String? {
+ get {
+ let aValue = objc_getAssociatedObject(self, &kIQToolbarPlaceholder) as? String
+
+ return aValue
+ }
+ set(newValue) {
+ objc_setAssociatedObject(self, &kIQToolbarPlaceholder, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+
+ self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder
+ }
+ }
+
+ /**
+ `drawingToolbarPlaceholder` will be actual text used to draw on toolbar. This would either `placeholder` or `toolbarPlaceholder`.
+ */
+ @objc public var drawingToolbarPlaceholder: String? {
+
+ if (self.shouldHideToolbarPlaceholder)
+ {
+ return nil
+ }
+ else if (self.toolbarPlaceholder?.isEmpty == false) {
+ return self.toolbarPlaceholder
+ }
+ else if self.responds(to: #selector(getter: UITextField.placeholder)) {
+
+ if let textField = self as? UITextField {
+ return textField.placeholder
+ } else if let textView = self as? IQTextView {
+ return textView.placeholder
+ } else {
+ return nil
+ }
+ }
+ else {
+ return nil
+ }
+ }
+
+ ///---------------------
+ /// MARK: Private helper
+ ///---------------------
+
+ private static func flexibleBarButtonItem () -> IQBarButtonItem {
+
+ struct Static {
+
+ static let nilButton = IQBarButtonItem(barButtonSystemItem:.flexibleSpace, target: nil, action: nil)
+ }
+
+ Static.nilButton.isSystemItem = true
+ return Static.nilButton
+ }
+
+ ///-------------
+ /// MARK: Common
+ ///-------------
+
+ @objc public func addKeyboardToolbarWithTarget(target : AnyObject?, titleText : String?, rightBarButtonConfiguration:IQBarButtonItemConfiguration?, previousBarButtonConfiguration:IQBarButtonItemConfiguration? = nil, nextBarButtonConfiguration:IQBarButtonItemConfiguration? = nil) {
+
+ //If can't set InputAccessoryView. Then return
+ if self.responds(to: #selector(setter: UITextField.inputAccessoryView)) {
+
+ // Creating a toolBar for phoneNumber keyboard
+ let toolbar = self.keyboardToolbar
+
+ var items : [IQBarButtonItem] = []
+
+ if let prevConfig = previousBarButtonConfiguration {
+
+ var prev = toolbar.previousBarButton
+
+ if prevConfig.barButtonSystemItem == nil && prev.isSystemItem == false {
+ prev.title = prevConfig.title
+ prev.image = prevConfig.image
+ prev.target = target
+ prev.action = prevConfig.action
+ } else {
+ if let systemItem = prevConfig.barButtonSystemItem {
+ prev = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: prevConfig.action)
+ prev.isSystemItem = true
+ } else if let image = prevConfig.image {
+ prev = IQBarButtonItem(image: image, style: .plain, target: target, action: prevConfig.action)
+ } else {
+ prev = IQBarButtonItem(title: prevConfig.title, style: .plain, target: target, action: prevConfig.action)
+ }
+
+ prev.invocation = toolbar.previousBarButton.invocation
+ prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel
+ toolbar.previousBarButton = prev
+ }
+
+ items.append(prev)
+ }
+
+ if previousBarButtonConfiguration != nil && nextBarButtonConfiguration != nil {
+
+ items.append(toolbar.fixedSpaceBarButton)
+ }
+
+ if let nextConfig = nextBarButtonConfiguration {
+
+ var next = toolbar.nextBarButton
+
+ if nextConfig.barButtonSystemItem == nil && next.isSystemItem == false {
+ next.title = nextConfig.title
+ next.image = nextConfig.image
+ next.target = target
+ next.action = nextConfig.action
+ } else {
+ if let systemItem = nextConfig.barButtonSystemItem {
+ next = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: nextConfig.action)
+ next.isSystemItem = true
+ } else if let image = nextConfig.image {
+ next = IQBarButtonItem(image: image, style: .plain, target: target, action: nextConfig.action)
+ } else {
+ next = IQBarButtonItem(title: nextConfig.title, style: .plain, target: target, action: nextConfig.action)
+ }
+
+ next.invocation = toolbar.nextBarButton.invocation
+ next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel
+ toolbar.nextBarButton = next
+ }
+
+ items.append(next)
+ }
+
+ //Title bar button item
+ do {
+ //Flexible space
+ items.append(UIView.flexibleBarButtonItem())
+
+ //Title button
+ toolbar.titleBarButton.title = titleText
+
+ #if swift(>=3.2)
+ if #available(iOS 11, *) {}
+ else {
+ toolbar.titleBarButton.customView?.frame = CGRect.zero
+ }
+ #else
+ toolbar.titleBarButton.customView?.frame = CGRect.zero
+ #endif
+
+ items.append(toolbar.titleBarButton)
+
+ //Flexible space
+ items.append(UIView.flexibleBarButtonItem())
+ }
+
+ if let rightConfig = rightBarButtonConfiguration {
+
+ var done = toolbar.doneBarButton
+
+ if rightConfig.barButtonSystemItem == nil && done.isSystemItem == false {
+ done.title = rightConfig.title
+ done.image = rightConfig.image
+ done.target = target
+ done.action = rightConfig.action
+ } else {
+ if let systemItem = rightConfig.barButtonSystemItem {
+ done = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: rightConfig.action)
+ done.isSystemItem = true
+ } else if let image = rightConfig.image {
+ done = IQBarButtonItem(image: image, style: .plain, target: target, action: rightConfig.action)
+ } else {
+ done = IQBarButtonItem(title: rightConfig.title, style: .plain, target: target, action: rightConfig.action)
+ }
+
+ done.invocation = toolbar.doneBarButton.invocation
+ done.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel
+ toolbar.doneBarButton = done
+ }
+
+ items.append(done)
+ }
+
+ // Adding button to toolBar.
+ toolbar.items = items
+
+ // Setting toolbar to keyboard.
+ if let textField = self as? UITextField {
+ textField.inputAccessoryView = toolbar
+
+ switch textField.keyboardAppearance {
+ case .dark:
+ toolbar.barStyle = UIBarStyle.black
+ default:
+ toolbar.barStyle = UIBarStyle.default
+ }
+ } else if let textView = self as? UITextView {
+ textView.inputAccessoryView = toolbar
+
+ switch textView.keyboardAppearance {
+ case .dark:
+ toolbar.barStyle = UIBarStyle.black
+ default:
+ toolbar.barStyle = UIBarStyle.default
+ }
+ }
+ }
+ }
+
+ ///------------
+ /// MARK: Right
+ ///------------
+
+ @objc public func addDoneOnKeyboardWithTarget(_ target : AnyObject?, action : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addDoneOnKeyboardWithTarget(target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addDoneOnKeyboardWithTarget(_ target : AnyObject?, action : Selector, titleText: String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: action)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration)
+ }
+
+
+ @objc public func addRightButtonOnKeyboardWithImage(_ image : UIImage, target : AnyObject?, action : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addRightButtonOnKeyboardWithImage(image, target: target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addRightButtonOnKeyboardWithImage(_ image : UIImage, target : AnyObject?, action : Selector, titleText: String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(image: image, action: action)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration)
+ }
+
+
+ @objc public func addRightButtonOnKeyboardWithText(_ text : String, target : AnyObject?, action : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addRightButtonOnKeyboardWithText(text, target: target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addRightButtonOnKeyboardWithText(_ text : String, target : AnyObject?, action : Selector, titleText: String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(title: text, action: action)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration)
+ }
+
+ ///-----------------
+ /// MARK: Right/Left
+ ///-----------------
+
+ @objc public func addCancelDoneOnKeyboardWithTarget(_ target : AnyObject?, cancelAction : Selector, doneAction : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addCancelDoneOnKeyboardWithTarget(target, cancelAction: cancelAction, doneAction: doneAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addRightLeftOnKeyboardWithTarget(_ target : AnyObject?, leftButtonTitle : String, rightButtonTitle : String, leftButtonAction : Selector, rightButtonAction : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addRightLeftOnKeyboardWithTarget(target, leftButtonTitle: leftButtonTitle, rightButtonTitle: rightButtonTitle, leftButtonAction: leftButtonAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addRightLeftOnKeyboardWithTarget(_ target : AnyObject?, leftButtonImage : UIImage, rightButtonImage : UIImage, leftButtonAction : Selector, rightButtonAction : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addRightLeftOnKeyboardWithTarget(target, leftButtonImage: leftButtonImage, rightButtonImage: rightButtonImage, leftButtonAction: leftButtonAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addCancelDoneOnKeyboardWithTarget(_ target : AnyObject?, cancelAction : Selector, doneAction : Selector, titleText: String?) {
+
+ let leftConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .cancel, action: cancelAction)
+ let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done , action: doneAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration)
+ }
+
+ @objc public func addRightLeftOnKeyboardWithTarget(_ target : AnyObject?, leftButtonTitle : String, rightButtonTitle : String, leftButtonAction : Selector, rightButtonAction : Selector, titleText: String?) {
+
+ let leftConfiguration = IQBarButtonItemConfiguration(title: leftButtonTitle, action: leftButtonAction)
+ let rightConfiguration = IQBarButtonItemConfiguration(title: rightButtonTitle, action: rightButtonAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration)
+ }
+
+ @objc public func addRightLeftOnKeyboardWithTarget(_ target : AnyObject?, leftButtonImage : UIImage, rightButtonImage : UIImage, leftButtonAction : Selector, rightButtonAction : Selector, titleText: String?) {
+
+ let leftConfiguration = IQBarButtonItemConfiguration(image: leftButtonImage, action: leftButtonAction)
+ let rightConfiguration = IQBarButtonItemConfiguration(image: rightButtonImage, action: rightButtonAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration)
+ }
+
+ ///--------------------------
+ /// MARK: Previous/Next/Right
+ ///--------------------------
+
+ @objc public func addPreviousNextDoneOnKeyboardWithTarget (_ target : AnyObject?, previousAction : Selector, nextAction : Selector, doneAction : Selector, shouldShowPlaceholder: Bool = false) {
+
+ addPreviousNextDoneOnKeyboardWithTarget(target, previousAction: previousAction, nextAction: nextAction, doneAction: doneAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addPreviousNextRightOnKeyboardWithTarget(_ target : AnyObject?, rightButtonImage : UIImage, previousAction : Selector, nextAction : Selector, rightButtonAction : Selector, shouldShowPlaceholder : Bool = false) {
+
+ addPreviousNextRightOnKeyboardWithTarget(target, rightButtonImage: rightButtonImage, previousAction: previousAction, nextAction: nextAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addPreviousNextRightOnKeyboardWithTarget(_ target : AnyObject?, rightButtonTitle : String, previousAction : Selector, nextAction : Selector, rightButtonAction : Selector, shouldShowPlaceholder : Bool = false) {
+
+ addPreviousNextRightOnKeyboardWithTarget(target, rightButtonTitle: rightButtonTitle, previousAction: previousAction, nextAction: nextAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder : nil))
+ }
+
+ @objc public func addPreviousNextDoneOnKeyboardWithTarget (_ target : AnyObject?, previousAction : Selector, nextAction : Selector, doneAction : Selector, titleText: String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: doneAction)
+ let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction)
+ let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
+ }
+
+ @objc public func addPreviousNextRightOnKeyboardWithTarget(_ target : AnyObject?, rightButtonImage : UIImage, previousAction : Selector, nextAction : Selector, rightButtonAction : Selector, titleText : String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(image: rightButtonImage, action: rightButtonAction)
+ let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction)
+ let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
+ }
+
+ @objc public func addPreviousNextRightOnKeyboardWithTarget(_ target : AnyObject?, rightButtonTitle : String, previousAction : Selector, nextAction : Selector, rightButtonAction : Selector, titleText : String?) {
+
+ let rightConfiguration = IQBarButtonItemConfiguration(title: rightButtonTitle, action: rightButtonAction)
+ let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction)
+ let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction)
+
+ addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration)
+ }
+}
+
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@2x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@2x.png
new file mode 100644
index 00000000..81db2ed2
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@2x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@3x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@3x.png
new file mode 100644
index 00000000..dd341229
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@3x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png
new file mode 100644
index 00000000..cfc40d6e
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png
new file mode 100644
index 00000000..849b9913
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png
new file mode 100644
index 00000000..c8b9a874
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png
new file mode 100644
index 00000000..95c43973
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@2x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@2x.png
new file mode 100644
index 00000000..8ec96a9d
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@2x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@3x.png b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@3x.png
new file mode 100644
index 00000000..9304f50f
Binary files /dev/null and b/Santander-Test/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@3x.png differ
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/LICENSE.md b/Santander-Test/Pods/IQKeyboardManagerSwift/LICENSE.md
new file mode 100644
index 00000000..c17c1077
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2013-2017 Iftekhar Qurashi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Santander-Test/Pods/IQKeyboardManagerSwift/README.md b/Santander-Test/Pods/IQKeyboardManagerSwift/README.md
new file mode 100644
index 00000000..b3900c02
--- /dev/null
+++ b/Santander-Test/Pods/IQKeyboardManagerSwift/README.md
@@ -0,0 +1,210 @@
+
+
+
+IQKeyboardManager
+
+
+
+
+[](https://travis-ci.org/hackiftekhar/IQKeyboardManager)
+
+
+Often while developing an app, We ran into an issues where the iPhone keyboard slide up and cover the `UITextField/UITextView`. `IQKeyboardManager` allows you to prevent issues of the keyboard sliding up and cover `UITextField/UITextView` without needing you to enter any code and no additional setup required. To use `IQKeyboardManager` you simply need to add source files to your project.
+
+
+#### Key Features
+
+1) `**CODELESS**, Zero Lines Of Code`
+
+2) `Works Automatically`
+
+3) `No More UIScrollView`
+
+4) `No More Subclasses`
+
+5) `No More Manual Work`
+
+6) `No More #imports`
+
+`IQKeyboardManager` works on all orientations, and with the toolbar. There are also nice optional features allowing you to customize the distance from the text field, add the next/previous done button as a keyboard UIToolbar, play sounds when the user navigations through the form and more.
+
+
+## Screenshot
+[](http://youtu.be/6nhLw6hju2A)
+[](http://youtu.be/6nhLw6hju2A)
+
+## GIF animation
+[](http://youtu.be/6nhLw6hju2A)
+
+## Video
+
+
+
+## Tutorial video by @rebeloper ([#1135](https://github.com/hackiftekhar/IQKeyboardManager/issues/1135))
+
+@rebeloper demonstrated two videos on how to implement **IQKeyboardManager** at it's core:
+
+
+
+https://www.youtube.com/playlist?list=PL_csAAO9PQ8aTL87XnueOXi3RpWE2m_8v
+
+## Warning
+
+- **If you're planning to build SDK/library/framework and wants to handle UITextField/UITextView with IQKeyboardManager then you're totally going on wrong way.** I would never suggest to add **IQKeyboardManager** as **dependency/adding/shipping** with any third-party library, instead of adding **IQKeyboardManager** you should implement your own solution to achieve same kind of results. **IQKeyboardManager** is totally designed for projects to help developers for their convenience, it's not designed for **adding/dependency/shipping** with any **third-party library**, because **doing this could block adoption by other developers for their projects as well(who are not using IQKeyboardManager and implemented their custom solution to handle UITextField/UITextView thought the project).**
+- If **IQKeyboardManager** conflicts with other **third-party library**, then it's **developer responsibility** to **enable/disable IQKeyboardManager** when **presenting/dismissing** third-party library UI. Third-party libraries are not responsible to handle IQKeyboardManager.
+
+## Requirements
+[]()
+
+| | Language | Minimum iOS Target | Minimum Xcode Version |
+|------------------------|----------|--------------------|-----------------------|
+| IQKeyboardManager | Obj-C | iOS 8.0 | Xcode 8.2.1 |
+| IQKeyboardManagerSwift | Swift | iOS 8.0 | Xcode 8.2.1 |
+| Demo Project | | | Xcode 9.3 |
+
+**Note**
+- 3.3.7 is the last iOS 7 supported version.
+
+#### Swift versions support
+
+| Swift | Xcode | IQKeyboardManagerSwift |
+|-------------------|-------|------------------------|
+| 4.2, 4.0, 3.2, 3.0| 10.0 | >= 6.0.4 |
+| 4.0, 3.2, 3.0 | 9.0 | 5.0.0 |
+| 3.1 | 8.3 | 4.0.10 |
+| 3.0 (3.0.2) | 8.2 | 4.0.8 |
+| 2.2 or 2.3 | 7.3 | 4.0.5 |
+| 2.1.1 | 7.2 | 4.0.0 |
+| 2.1 | 7.2 | 3.3.7 |
+| 2.0 | 7.0 | 3.3.3.1 |
+| 1.2 | 6.3 | 3.3.1 |
+| 1.0 | 6.0 | 3.3.2 |
+
+Installation
+==========================
+
+#### Installation with CocoaPods
+
+[](http://cocoadocs.org/docsets/IQKeyboardManager)
+
+***IQKeyboardManager (Objective-C):*** IQKeyboardManager is available through [CocoaPods](http://cocoapods.org), to install
+it simply add the following line to your Podfile: ([#9](https://github.com/hackiftekhar/IQKeyboardManager/issues/9))
+
+```ruby
+pod 'IQKeyboardManager' #iOS8 and later
+
+pod 'IQKeyboardManager', '3.3.7' #iOS7
+```
+
+***IQKeyboardManager (Swift):*** IQKeyboardManagerSwift is available through [CocoaPods](http://cocoapods.org), to install
+it simply add the following line to your Podfile: ([#236](https://github.com/hackiftekhar/IQKeyboardManager/issues/236))
+
+*Swift 4.2, 4.0, 3.2, 3.0 (Xcode 9)*
+
+```ruby
+pod 'IQKeyboardManagerSwift'
+```
+
+*Or you can choose version you need based on Swift support table from [Requirements](README.md#requirements)*
+
+```ruby
+pod 'IQKeyboardManagerSwift', '5.0.0'
+```
+
+In AppDelegate.swift, just import IQKeyboardManagerSwift framework and enable IQKeyboardManager.
+
+```swift
+import IQKeyboardManagerSwift
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
+
+ IQKeyboardManager.shared.enable = true
+
+ return true
+ }
+}
+```
+
+#### Installation with Carthage
+
+[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
+
+You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
+
+```bash
+$ brew update
+$ brew install carthage
+```
+
+To integrate `IQKeyboardManger` or `IQKeyboardManagerSwift` into your Xcode project using Carthage, specify it in your `Cartfile`:
+
+```ogdl
+github "hackiftekhar/IQKeyboardManager"
+```
+
+Run `carthage` to build the frameworks and drag the appropriate framework (`IQKeyboardManager.framework` or `IQKeyboardManagerSwift.framework`) into your Xcode project according to your need. Make sure to add only one framework and not both.
+
+
+#### Installation with Source Code
+
+[]()
+
+
+
+***IQKeyboardManager (Objective-C):*** Just ***drag and drop*** `IQKeyboardManager` directory from demo project to your project. That's it.
+
+***IQKeyboardManager (Swift):*** ***Drag and drop*** `IQKeyboardManagerSwift` directory from demo project to your project
+
+In AppDelegate.swift, just enable IQKeyboardManager.
+
+```swift
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
+
+ IQKeyboardManager.shared.enable = true
+
+ return true
+ }
+}
+```
+
+Migration Guide
+==========================
+- [IQKeyboardManager 6.0.0 Migration Guide](https://github.com/hackiftekhar/IQKeyboardManager/wiki/IQKeyboardManager-6.0.0-Migration-Guide)
+
+Other Links
+==========================
+
+- [Known Issues](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Known-Issues)
+- [Manual Management Tweaks](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Manual-Management)
+- [Properties and functions usage](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Properties-&-Functions)
+
+## Flow Diagram
+[](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Screenshot/IQKeyboardManagerFlowDiagram.jpg)
+
+If you would like to see detailed Flow diagram then see [Detailed Flow Diagram](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManagerCFD.jpg).
+
+
+LICENSE
+---
+Distributed under the MIT License.
+
+Contributions
+---
+Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub.
+
+Author
+---
+If you wish to contact me, email at: hack.iftekhar@gmail.com
diff --git a/Santander-Test/Pods/Manifest.lock b/Santander-Test/Pods/Manifest.lock
new file mode 100644
index 00000000..15324d25
--- /dev/null
+++ b/Santander-Test/Pods/Manifest.lock
@@ -0,0 +1,38 @@
+PODS:
+ - Alamofire (4.8.1)
+ - AMPopTip (3.6.0)
+ - IQKeyboardManagerSwift (6.2.0)
+ - Moya (12.0.1):
+ - Moya/Core (= 12.0.1)
+ - Moya/Core (12.0.1):
+ - Alamofire (~> 4.1)
+ - Result (~> 4.0)
+ - Result (4.1.0)
+ - StatusAlert (1.1.0)
+
+DEPENDENCIES:
+ - AMPopTip
+ - IQKeyboardManagerSwift
+ - Moya
+ - StatusAlert
+
+SPEC REPOS:
+ https://github.com/cocoapods/specs.git:
+ - Alamofire
+ - AMPopTip
+ - IQKeyboardManagerSwift
+ - Moya
+ - Result
+ - StatusAlert
+
+SPEC CHECKSUMS:
+ Alamofire: 16ce2c353fb72865124ddae8a57c5942388f4f11
+ AMPopTip: ebfa860ade372f383e8b3500d3101e8c4a4f73ce
+ IQKeyboardManagerSwift: b07ccf9d8cafe993dcd6cb794eb4ba34611a0c4e
+ Moya: cf730b3cd9e005401ef37a85143aa141a12fd38f
+ Result: bd966fac789cc6c1563440b348ab2598cc24d5c7
+ StatusAlert: 4d6dadebf5f7abd5648fa774ef3062f2f95cc4aa
+
+PODFILE CHECKSUM: 4e150ff8c831fa6b97c7c1e6355aa319f0463e89
+
+COCOAPODS: 1.6.0
diff --git a/Santander-Test/Pods/Moya/License.md b/Santander-Test/Pods/Moya/License.md
new file mode 100644
index 00000000..58ef14fc
--- /dev/null
+++ b/Santander-Test/Pods/Moya/License.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-present Artsy, Ash Furrow
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Santander-Test/Pods/Moya/Readme.md b/Santander-Test/Pods/Moya/Readme.md
new file mode 100644
index 00000000..92a01824
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Readme.md
@@ -0,0 +1,320 @@
+
+
+
+
+# Moya
+
+[](https://circleci.com/gh/Moya/Moya/tree/master)
+[](https://codecov.io/github/Moya/Moya?branch=master)
+[](https://github.com/Carthage/Carthage)
+[](https://cocoapods.org/pods/Moya)
+[](https://github.com/apple/swift-package-manager)
+
+*A Chinese version of this document can be found [here](https://github.com/Moya/Moya/blob/master/Readme_CN.md).*
+
+You're a smart developer. You probably use [Alamofire](https://github.com/Alamofire/Alamofire) to abstract away access to
+`URLSession` and all those nasty details you don't really care about. But then,
+like lots of smart developers, you write ad hoc network abstraction layers. They
+are probably called "APIManager" or "NetworkModel", and they always end in tears.
+
+
+
+Ad hoc network layers are common in iOS apps. They're bad for a few reasons:
+
+- Makes it hard to write new apps ("where do I begin?")
+- Makes it hard to maintain existing apps ("oh my god, this mess...")
+- Makes it hard to write unit tests ("how do I do this again?")
+
+So the basic idea of Moya is that we want some network abstraction layer that
+sufficiently encapsulates actually calling Alamofire directly. It should be simple
+enough that common things are easy, but comprehensive enough that complicated things
+are also easy.
+
+> If you use Alamofire to abstract away `URLSession`, why not use something
+to abstract away the nitty gritty of URLs, parameters, etc?
+
+Some awesome features of Moya:
+
+- Compile-time checking for correct API endpoint accesses.
+- Lets you define a clear usage of different endpoints with associated enum values.
+- Treats test stubs as first-class citizens so unit testing is super-easy.
+
+You can check out more about the project direction in the [vision document](https://github.com/Moya/Moya/blob/master/Vision.md).
+
+## Sample Projects
+
+We have provided two sample projects in the repository. To use it download the repo, run `carthage update` to download the required libraries and open [Moya.xcodeproj](https://github.com/Moya/Moya/tree/master/Moya.xcodeproj). You'll see two schemes: `Basic` and `Multi-Target` - select one and then build & run! Source files for these are in the `Examples` directory in project navigator. Have fun!
+
+## Project Status
+
+This project is actively under development, and is being used in [Artsy's
+new auction app](https://github.com/Artsy/eidolon). We consider it
+ready for production use.
+
+## Installation
+
+### Moya version vs Swift version.
+
+Below is a table that shows which version of Moya you should use for
+your Swift version.
+
+| Swift | Moya | RxMoya | ReactiveMoya |
+| ----- | ------------- |---------------|---------------|
+| 4.X | >= 9.0 | >= 10.0 | >= 9.0 |
+| 3.X | 8.0.0 - 8.0.5 | 8.0.0 - 8.0.5 | 8.0.0 - 8.0.5 |
+| 2.3 | 7.0.2 - 7.0.4 | 7.0.2 - 7.0.4 | 7.0.2 - 7.0.4 |
+| 2.2 | <= 7.0.1 | <= 7.0.1 | <= 7.0.1 |
+
+**Upgrading to a new major version of Moya? Check out our [migration guides](https://github.com/Moya/Moya/blob/master/docs/MigrationGuides).**
+
+### Swift Package Manager
+
+To integrate using Apple's Swift package manager, add the following as a dependency to your `Package.swift`:
+
+```swift
+.package(url: "https://github.com/Moya/Moya.git", .upToNextMajor(from: "11.0.0"))
+```
+
+and then specify `"Moya"` as a dependency of the Target in which you wish to use Moya.
+If you want to use reactive extensions, add also `"ReactiveMoya"` or `"RxMoya"` as your Target dependency respectively.
+Here's an example `PackageDescription`:
+
+```swift
+// swift-tools-version:4.0
+import PackageDescription
+
+let package = Package(
+ name: "MyPackage",
+ products: [
+ .library(
+ name: "MyPackage",
+ targets: ["MyPackage"]),
+ ],
+ dependencies: [
+ .package(url: "https://github.com/Moya/Moya.git", .upToNextMajor(from: "12.0.0"))
+ ],
+ targets: [
+ .target(
+ name: "MyPackage",
+ dependencies: ["ReactiveMoya"])
+ ]
+)
+```
+
+Note that as of Moya 10, SPM only works with Swift 4 toolchain and greater.
+
+### CocoaPods
+
+For Moya, use the following entry in your Podfile:
+
+```rb
+pod 'Moya', '~> 12.0'
+
+# or
+
+pod 'Moya/RxSwift', '~> 12.0'
+
+# or
+
+pod 'Moya/ReactiveSwift', '~> 12.0'
+```
+
+Then run `pod install`.
+
+In any file you'd like to use Moya in, don't forget to
+import the framework with `import Moya`.
+
+### Carthage
+
+Carthage users can point to this repository and use whichever
+generated framework they'd like, `Moya`, `RxMoya`, or `ReactiveMoya`.
+
+Make the following entry in your Cartfile:
+
+```
+github "Moya/Moya"
+```
+
+Then run `carthage update`.
+
+If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained [over at Carthage](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application).
+
+> NOTE: At this time, Carthage does not provide a way to build only specific repository submodules. All submodules and their dependencies will be built with the above command. However, you don't need to copy frameworks you aren't using into your project. For instance, if you aren't using `ReactiveSwift`, feel free to delete that framework along with `ReactiveMoya` from the Carthage Build directory after `carthage update` completes. Or if you are using `ReactiveSwift` but not `RxSwift`, then `RxMoya`, `RxTest`, `RxCocoa`, etc. can safely be deleted.
+
+### Manually
+
+- Open up Terminal, `cd` into your top-level project directory, and run the following command *if* your project is not initialized as a git repository:
+
+```bash
+$ git init
+```
+
+- Add Alamofire, Result & Moya as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following commands:
+
+```bash
+$ git submodule add https://github.com/Alamofire/Alamofire.git
+$ git submodule add https://github.com/antitypical/Result.git
+$ git submodule add https://github.com/Moya/Moya.git
+```
+
+- Open the new `Alamofire` folder, and drag the `Alamofire.xcodeproj` into the Project Navigator of your application's Xcode project. Do the same with the `Result.xcodeproj` in the `Result` folder and `Moya.xcodeproj` in the `Moya` folder.
+
+> They should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.
+
+- Verify that the deployment targets of the `xcodeproj`s match that of your application target in the Project Navigator.
+- Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.
+- In the tab bar at the top of that window, open the "General" panel.
+- Click on the `+` button under the "Embedded Binaries" section.
+- You will see two different `Alamofire.xcodeproj` folders each with two different versions of the `Alamofire.framework` nested inside a `Products` folder.
+
+> It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `Alamofire.framework`.
+
+- Select the top `Alamofire.framework` for iOS and the bottom one for macOS.
+
+> You can verify which one you selected by inspecting the build log for your project. The build target for `Alamofire` will be listed as either `Alamofire iOS`, `Alamofire macOS`, `Alamofire tvOS` or `Alamofire watchOS`.
+
+- Click on the `+` button under "Embedded Binaries" again and add the build target you need for `Result`.
+- Click on the `+` button again and add the correct build target for `Moya`.
+
+- And that's it!
+
+> The three frameworks are automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.
+
+## Usage
+
+After [some setup](https://github.com/Moya/Moya/blob/master/docs/Examples/Basic.md), using Moya is really simple. You can access an API like this:
+
+```swift
+provider = MoyaProvider()
+provider.request(.zen) { result in
+ switch result {
+ case let .success(moyaResponse):
+ let data = moyaResponse.data
+ let statusCode = moyaResponse.statusCode
+ // do something with the response data or statusCode
+ case let .failure(error):
+ // this means there was a network failure - either the request
+ // wasn't sent (connectivity), or no response was received (server
+ // timed out). If the server responds with a 4xx or 5xx error, that
+ // will be sent as a ".success"-ful response.
+ }
+}
+```
+
+That's a basic example. Many API requests need parameters. Moya encodes these
+into the enum you use to access the endpoint, like this:
+
+```swift
+provider = MoyaProvider()
+provider.request(.userProfile("ashfurrow")) { result in
+ // do something with the result
+}
+```
+
+No more typos in URLs. No more missing parameter values. No more messing with
+parameter encoding.
+
+For more examples, see the [documentation](https://github.com/Moya/Moya/blob/master/docs/Examples).
+
+## Reactive Extensions
+
+Even cooler are the reactive extensions. Moya provides reactive extensions for
+[ReactiveSwift](https://github.com/ReactiveCocoa/ReactiveSwift) and
+[RxSwift](https://github.com/ReactiveX/RxSwift).
+
+### ReactiveSwift
+
+[`ReactiveSwift` extension](https://github.com/Moya/Moya/blob/master/docs/ReactiveSwift.md) provides both `reactive.request(:callbackQueue:)` and
+`reactive.requestWithProgress(:callbackQueue:)` methods that immediately return
+`SignalProducer`s that you can start, bind, map, or whatever you want to do.
+To handle errors, for instance, we could do the following:
+
+```swift
+provider = MoyaProvider()
+provider.reactive.request(.userProfile("ashfurrow")).start { event in
+ switch event {
+ case let .value(response):
+ image = UIImage(data: response.data)
+ case let .failed(error):
+ print(error)
+ default:
+ break
+ }
+}
+```
+
+### RxSwift
+
+[`RxSwift` extension](https://github.com/Moya/Moya/blob/master/docs/RxSwift.md) also provide both `rx.request(:callbackQueue:)` and
+`rx.requestWithProgress(:callbackQueue:)` methods, but return type is
+different for both. In case of a normal `rx.request(:callbackQueue)`, the
+return type is `Single` which emits either single element or an
+error. In case of a `rx.requestWithProgress(:callbackQueue:)`, the return
+type is `Observable`, since we may get multiple events
+from progress and one last event which is a response.
+
+To handle errors, for instance, we could do the following:
+
+```swift
+provider = MoyaProvider()
+provider.rx.request(.userProfile("ashfurrow")).subscribe { event in
+ switch event {
+ case let .success(response):
+ image = UIImage(data: response.data)
+ case let .error(error):
+ print(error)
+ }
+}
+```
+
+In addition to the option of using signals instead of callback blocks, there are
+also a series of signal operators for RxSwift and ReactiveSwift that will attempt
+to map the data received from the network response into either an image, some JSON,
+or a string, with `mapImage()`, `mapJSON()`, and `mapString()`, respectively. If the mapping is unsuccessful, you'll get an error on the signal. You also get handy methods
+for filtering out certain status codes. This means that you can place your code for
+handling API errors like 400's in the same places as code for handling invalid
+responses.
+
+## Community Projects
+
+[Moya has a great community around it and some people have created some very helpful extensions](https://github.com/Moya/Moya/blob/master/docs/CommunityProjects.md).
+
+## Contributing
+
+Hey! Do you like Moya? Awesome! We could actually really use your help!
+
+Open source isn't just writing code. Moya could use your help with any of the
+following:
+
+- Finding (and reporting!) bugs.
+- New feature suggestions.
+- Answering questions on issues.
+- Documentation improvements.
+- Reviewing pull requests.
+- Helping to manage issue priorities.
+- Fixing bugs/new features.
+
+If any of that sounds cool to you, send a pull request! After your first
+contribution, we will add you as a member to the repo so you can merge pull
+requests and help steer the ship :ship: You can read more details about that [in our contributor guidelines](https://github.com/Moya/Moya/blob/master/Contributing.md).
+
+Moya's community has a tremendous positive energy, and the maintainers are committed to keeping things awesome. Like [in the CocoaPods community](https://github.com/CocoaPods/CocoaPods/wiki/Communication-&-Design-Rules), always assume positive intent; even if a comment sounds mean-spirited, give the person the benefit of the doubt.
+
+Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by [its terms](https://github.com/Moya/Moya/blob/master/Code%20of%20Conduct.md).
+
+### Adding new source files
+
+If you add or remove a source file from Moya, a corresponding change needs to be made to the `Moya.xcodeproj` project at the root of this repository. This project is used for Carthage. Don't worry, you'll get an automated warning when submitting a pull request if you forget.
+
+### Help us improve Moya documentation
+Whether you’re a core member or a user trying it out for the first time, you can make a valuable contribution to Moya by improving the documentation. Help us by:
+
+- sending us feedback about something you thought was confusing or simply missing
+- suggesting better wording or ways of explaining certain topics
+- sending us a pull request via GitHub
+- improving the [Chinese documentation](https://github.com/Moya/Moya/blob/master/Readme_CN.md)
+
+
+## License
+
+Moya is released under an MIT license. See [License.md](https://github.com/Moya/Moya/blob/master/License.md) for more information.
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/AnyEncodable.swift b/Santander-Test/Pods/Moya/Sources/Moya/AnyEncodable.swift
new file mode 100644
index 00000000..15c7128e
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/AnyEncodable.swift
@@ -0,0 +1,14 @@
+import Foundation
+
+struct AnyEncodable: Encodable {
+
+ private let encodable: Encodable
+
+ public init(_ encodable: Encodable) {
+ self.encodable = encodable
+ }
+
+ func encode(to encoder: Encoder) throws {
+ try encodable.encode(to: encoder)
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Cancellable.swift b/Santander-Test/Pods/Moya/Sources/Moya/Cancellable.swift
new file mode 100644
index 00000000..9a9c783f
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Cancellable.swift
@@ -0,0 +1,26 @@
+/// Protocol to define the opaque type returned from a request.
+public protocol Cancellable {
+
+ /// A Boolean value stating whether a request is cancelled.
+ var isCancelled: Bool { get }
+
+ /// Cancels the represented request.
+ func cancel()
+}
+
+internal class CancellableWrapper: Cancellable {
+ internal var innerCancellable: Cancellable = SimpleCancellable()
+
+ var isCancelled: Bool { return innerCancellable.isCancelled }
+
+ internal func cancel() {
+ innerCancellable.cancel()
+ }
+}
+
+internal class SimpleCancellable: Cancellable {
+ var isCancelled = false
+ func cancel() {
+ isCancelled = true
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Endpoint.swift b/Santander-Test/Pods/Moya/Sources/Moya/Endpoint.swift
new file mode 100755
index 00000000..37f79283
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Endpoint.swift
@@ -0,0 +1,137 @@
+import Foundation
+
+/// Used for stubbing responses.
+public enum EndpointSampleResponse {
+
+ /// The network returned a response, including status code and data.
+ case networkResponse(Int, Data)
+
+ /// The network returned response which can be fully customized.
+ case response(HTTPURLResponse, Data)
+
+ /// The network failed to send the request, or failed to retrieve a response (eg a timeout).
+ case networkError(NSError)
+}
+
+/// Class for reifying a target of the `Target` enum unto a concrete `Endpoint`.
+/// - Note: As of Moya 11.0.0 Endpoint is no longer generic.
+/// Existing code should work as is after removing the generic.
+/// See #1529 and #1524 for the discussion.
+open class Endpoint {
+ public typealias SampleResponseClosure = () -> EndpointSampleResponse
+
+ /// A string representation of the URL for the request.
+ public let url: String
+
+ /// A closure responsible for returning an `EndpointSampleResponse`.
+ public let sampleResponseClosure: SampleResponseClosure
+
+ /// The HTTP method for the request.
+ public let method: Moya.Method
+
+ /// The `Task` for the request.
+ public let task: Task
+
+ /// The HTTP header fields for the request.
+ public let httpHeaderFields: [String: String]?
+
+ public init(url: String,
+ sampleResponseClosure: @escaping SampleResponseClosure,
+ method: Moya.Method,
+ task: Task,
+ httpHeaderFields: [String: String]?) {
+
+ self.url = url
+ self.sampleResponseClosure = sampleResponseClosure
+ self.method = method
+ self.task = task
+ self.httpHeaderFields = httpHeaderFields
+ }
+
+ /// Convenience method for creating a new `Endpoint` with the same properties as the receiver, but with added HTTP header fields.
+ open func adding(newHTTPHeaderFields: [String: String]) -> Endpoint {
+ return Endpoint(url: url, sampleResponseClosure: sampleResponseClosure, method: method, task: task, httpHeaderFields: add(httpHeaderFields: newHTTPHeaderFields))
+ }
+
+ /// Convenience method for creating a new `Endpoint` with the same properties as the receiver, but with replaced `task` parameter.
+ open func replacing(task: Task) -> Endpoint {
+ return Endpoint(url: url, sampleResponseClosure: sampleResponseClosure, method: method, task: task, httpHeaderFields: httpHeaderFields)
+ }
+
+ fileprivate func add(httpHeaderFields headers: [String: String]?) -> [String: String]? {
+ guard let unwrappedHeaders = headers, unwrappedHeaders.isEmpty == false else {
+ return self.httpHeaderFields
+ }
+
+ var newHTTPHeaderFields = self.httpHeaderFields ?? [:]
+ unwrappedHeaders.forEach { key, value in
+ newHTTPHeaderFields[key] = value
+ }
+ return newHTTPHeaderFields
+ }
+}
+
+/// Extension for converting an `Endpoint` into a `URLRequest`.
+extension Endpoint {
+ // swiftlint:disable cyclomatic_complexity
+ /// Returns the `Endpoint` converted to a `URLRequest` if valid. Throws an error otherwise.
+ public func urlRequest() throws -> URLRequest {
+ guard let requestURL = Foundation.URL(string: url) else {
+ throw MoyaError.requestMapping(url)
+ }
+
+ var request = URLRequest(url: requestURL)
+ request.httpMethod = method.rawValue
+ request.allHTTPHeaderFields = httpHeaderFields
+
+ switch task {
+ case .requestPlain, .uploadFile, .uploadMultipart, .downloadDestination:
+ return request
+ case .requestData(let data):
+ request.httpBody = data
+ return request
+ case let .requestJSONEncodable(encodable):
+ return try request.encoded(encodable: encodable)
+ case let .requestCustomJSONEncodable(encodable, encoder: encoder):
+ return try request.encoded(encodable: encodable, encoder: encoder)
+ case let .requestParameters(parameters, parameterEncoding):
+ return try request.encoded(parameters: parameters, parameterEncoding: parameterEncoding)
+ case let .uploadCompositeMultipart(_, urlParameters):
+ let parameterEncoding = URLEncoding(destination: .queryString)
+ return try request.encoded(parameters: urlParameters, parameterEncoding: parameterEncoding)
+ case let .downloadParameters(parameters, parameterEncoding, _):
+ return try request.encoded(parameters: parameters, parameterEncoding: parameterEncoding)
+ case let .requestCompositeData(bodyData: bodyData, urlParameters: urlParameters):
+ request.httpBody = bodyData
+ let parameterEncoding = URLEncoding(destination: .queryString)
+ return try request.encoded(parameters: urlParameters, parameterEncoding: parameterEncoding)
+ case let .requestCompositeParameters(bodyParameters: bodyParameters, bodyEncoding: bodyParameterEncoding, urlParameters: urlParameters):
+ if let bodyParameterEncoding = bodyParameterEncoding as? URLEncoding, bodyParameterEncoding.destination != .httpBody {
+ fatalError("Only URLEncoding that `bodyEncoding` accepts is URLEncoding.httpBody. Others like `default`, `queryString` or `methodDependent` are prohibited - if you want to use them, add your parameters to `urlParameters` instead.")
+ }
+ let bodyfulRequest = try request.encoded(parameters: bodyParameters, parameterEncoding: bodyParameterEncoding)
+ let urlEncoding = URLEncoding(destination: .queryString)
+ return try bodyfulRequest.encoded(parameters: urlParameters, parameterEncoding: urlEncoding)
+ }
+ }
+ // swiftlint:enable cyclomatic_complexity
+}
+
+/// Required for using `Endpoint` as a key type in a `Dictionary`.
+extension Endpoint: Equatable, Hashable {
+ public var hashValue: Int {
+ let request = try? urlRequest()
+ return request?.hashValue ?? url.hashValue
+ }
+
+ /// Note: If both Endpoints fail to produce a URLRequest the comparison will
+ /// fall back to comparing each Endpoint's hashValue.
+ public static func == (lhs: Endpoint, rhs: Endpoint) -> Bool {
+ let lhsRequest = try? lhs.urlRequest()
+ let rhsRequest = try? rhs.urlRequest()
+ if lhsRequest != nil, rhsRequest == nil { return false }
+ if lhsRequest == nil, rhsRequest != nil { return false }
+ if lhsRequest == nil, rhsRequest == nil { return lhs.hashValue == rhs.hashValue }
+ return (lhsRequest == rhsRequest)
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Image.swift b/Santander-Test/Pods/Moya/Sources/Moya/Image.swift
new file mode 100644
index 00000000..233be5f2
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Image.swift
@@ -0,0 +1,10 @@
+#if os(iOS) || os(watchOS) || os(tvOS)
+ import UIKit.UIImage
+ public typealias ImageType = UIImage
+#elseif os(macOS)
+ import AppKit.NSImage
+ public typealias ImageType = NSImage
+#endif
+
+/// An alias for the SDK's image type.
+public typealias Image = ImageType
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Moya+Alamofire.swift b/Santander-Test/Pods/Moya/Sources/Moya/Moya+Alamofire.swift
new file mode 100644
index 00000000..8d4cd4a7
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Moya+Alamofire.swift
@@ -0,0 +1,90 @@
+import Foundation
+import Alamofire
+
+public typealias Manager = Alamofire.SessionManager
+internal typealias Request = Alamofire.Request
+internal typealias DownloadRequest = Alamofire.DownloadRequest
+internal typealias UploadRequest = Alamofire.UploadRequest
+internal typealias DataRequest = Alamofire.DataRequest
+
+internal typealias URLRequestConvertible = Alamofire.URLRequestConvertible
+
+/// Represents an HTTP method.
+public typealias Method = Alamofire.HTTPMethod
+
+/// Choice of parameter encoding.
+public typealias ParameterEncoding = Alamofire.ParameterEncoding
+public typealias JSONEncoding = Alamofire.JSONEncoding
+public typealias URLEncoding = Alamofire.URLEncoding
+public typealias PropertyListEncoding = Alamofire.PropertyListEncoding
+
+/// Multipart form.
+public typealias RequestMultipartFormData = Alamofire.MultipartFormData
+
+/// Multipart form data encoding result.
+public typealias MultipartFormDataEncodingResult = Manager.MultipartFormDataEncodingResult
+public typealias DownloadDestination = Alamofire.DownloadRequest.DownloadFileDestination
+
+/// Make the Alamofire Request type conform to our type, to prevent leaking Alamofire to plugins.
+extension Request: RequestType { }
+
+/// Internal token that can be used to cancel requests
+public final class CancellableToken: Cancellable, CustomDebugStringConvertible {
+ let cancelAction: () -> Void
+ let request: Request?
+
+ public fileprivate(set) var isCancelled = false
+
+ fileprivate var lock: DispatchSemaphore = DispatchSemaphore(value: 1)
+
+ public func cancel() {
+ _ = lock.wait(timeout: DispatchTime.distantFuture)
+ defer { lock.signal() }
+ guard !isCancelled else { return }
+ isCancelled = true
+ cancelAction()
+ }
+
+ public init(action: @escaping () -> Void) {
+ self.cancelAction = action
+ self.request = nil
+ }
+
+ init(request: Request) {
+ self.request = request
+ self.cancelAction = {
+ request.cancel()
+ }
+ }
+
+ /// A textual representation of this instance, suitable for debugging.
+ public var debugDescription: String {
+ guard let request = self.request else {
+ return "Empty Request"
+ }
+ return request.debugDescription
+ }
+
+}
+
+internal typealias RequestableCompletion = (HTTPURLResponse?, URLRequest?, Data?, Swift.Error?) -> Void
+
+internal protocol Requestable {
+ func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self
+}
+
+extension DataRequest: Requestable {
+ internal func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self {
+ return response(queue: callbackQueue) { handler in
+ completionHandler(handler.response, handler.request, handler.data, handler.error)
+ }
+ }
+}
+
+extension DownloadRequest: Requestable {
+ internal func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self {
+ return response(queue: callbackQueue) { handler in
+ completionHandler(handler.response, handler.request, nil, handler.error)
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MoyaError.swift b/Santander-Test/Pods/Moya/Sources/Moya/MoyaError.swift
new file mode 100644
index 00000000..472026cd
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MoyaError.swift
@@ -0,0 +1,76 @@
+import Foundation
+
+/// A type representing possible errors Moya can throw.
+public enum MoyaError: Swift.Error {
+
+ /// Indicates a response failed to map to an image.
+ case imageMapping(Response)
+
+ /// Indicates a response failed to map to a JSON structure.
+ case jsonMapping(Response)
+
+ /// Indicates a response failed to map to a String.
+ case stringMapping(Response)
+
+ /// Indicates a response failed to map to a Decodable object.
+ case objectMapping(Swift.Error, Response)
+
+ /// Indicates that Encodable couldn't be encoded into Data
+ case encodableMapping(Swift.Error)
+
+ /// Indicates a response failed with an invalid HTTP status code.
+ case statusCode(Response)
+
+ /// Indicates a response failed due to an underlying `Error`.
+ case underlying(Swift.Error, Response?)
+
+ /// Indicates that an `Endpoint` failed to map to a `URLRequest`.
+ case requestMapping(String)
+
+ /// Indicates that an `Endpoint` failed to encode the parameters for the `URLRequest`.
+ case parameterEncoding(Swift.Error)
+}
+
+public extension MoyaError {
+ /// Depending on error type, returns a `Response` object.
+ var response: Moya.Response? {
+ switch self {
+ case .imageMapping(let response): return response
+ case .jsonMapping(let response): return response
+ case .stringMapping(let response): return response
+ case .objectMapping(_, let response): return response
+ case .statusCode(let response): return response
+ case .underlying(_, let response): return response
+ case .encodableMapping: return nil
+ case .requestMapping: return nil
+ case .parameterEncoding: return nil
+ }
+ }
+}
+
+// MARK: - Error Descriptions
+
+extension MoyaError: LocalizedError {
+ public var errorDescription: String? {
+ switch self {
+ case .imageMapping:
+ return "Failed to map data to an Image."
+ case .jsonMapping:
+ return "Failed to map data to JSON."
+ case .stringMapping:
+ return "Failed to map data to a String."
+ case .objectMapping:
+ return "Failed to map data to a Decodable object."
+ case .encodableMapping:
+ return "Failed to encode Encodable object into data."
+ case .statusCode:
+ return "Status code didn't fall within the given range."
+ case .requestMapping:
+ return "Failed to map Endpoint to a URLRequest."
+ case .parameterEncoding(let error):
+ return "Failed to encode parameters for URLRequest. \(error.localizedDescription)"
+ case .underlying(let error, _):
+ return error.localizedDescription
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Defaults.swift b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Defaults.swift
new file mode 100644
index 00000000..7f39824c
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Defaults.swift
@@ -0,0 +1,36 @@
+import Foundation
+
+/// These functions are default mappings to `MoyaProvider`'s properties: endpoints, requests, manager, etc.
+public extension MoyaProvider {
+ public final class func defaultEndpointMapping(for target: Target) -> Endpoint {
+ return Endpoint(
+ url: URL(target: target).absoluteString,
+ sampleResponseClosure: { .networkResponse(200, target.sampleData) },
+ method: target.method,
+ task: target.task,
+ httpHeaderFields: target.headers
+ )
+ }
+
+ public final class func defaultRequestMapping(for endpoint: Endpoint, closure: RequestResultClosure) {
+ do {
+ let urlRequest = try endpoint.urlRequest()
+ closure(.success(urlRequest))
+ } catch MoyaError.requestMapping(let url) {
+ closure(.failure(MoyaError.requestMapping(url)))
+ } catch MoyaError.parameterEncoding(let error) {
+ closure(.failure(MoyaError.parameterEncoding(error)))
+ } catch {
+ closure(.failure(MoyaError.underlying(error, nil)))
+ }
+ }
+
+ public final class func defaultAlamofireManager() -> Manager {
+ let configuration = URLSessionConfiguration.default
+ configuration.httpAdditionalHeaders = Manager.defaultHTTPHeaders
+
+ let manager = Manager(configuration: configuration)
+ manager.startRequestsImmediately = false
+ return manager
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Internal.swift b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Internal.swift
new file mode 100644
index 00000000..e8bb4d21
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider+Internal.swift
@@ -0,0 +1,274 @@
+import Foundation
+import Result
+
+// MARK: - Method
+
+extension Method {
+ /// A Boolean value determining whether the request supports multipart.
+ public var supportsMultipart: Bool {
+ switch self {
+ case .post, .put, .patch, .connect:
+ return true
+ case .get, .delete, .head, .options, .trace:
+ return false
+ }
+ }
+}
+
+// MARK: - MoyaProvider
+
+/// Internal extension to keep the inner-workings outside the main Moya.swift file.
+public extension MoyaProvider {
+ /// Performs normal requests.
+ func requestNormal(_ target: Target, callbackQueue: DispatchQueue?, progress: Moya.ProgressBlock?, completion: @escaping Moya.Completion) -> Cancellable {
+ let endpoint = self.endpoint(target)
+ let stubBehavior = self.stubClosure(target)
+ let cancellableToken = CancellableWrapper()
+
+ // Allow plugins to modify response
+ let pluginsWithCompletion: Moya.Completion = { result in
+ let processedResult = self.plugins.reduce(result) { $1.process($0, target: target) }
+ completion(processedResult)
+ }
+
+ if trackInflights {
+ objc_sync_enter(self)
+ var inflightCompletionBlocks = self.inflightRequests[endpoint]
+ inflightCompletionBlocks?.append(pluginsWithCompletion)
+ self.inflightRequests[endpoint] = inflightCompletionBlocks
+ objc_sync_exit(self)
+
+ if inflightCompletionBlocks != nil {
+ return cancellableToken
+ } else {
+ objc_sync_enter(self)
+ self.inflightRequests[endpoint] = [pluginsWithCompletion]
+ objc_sync_exit(self)
+ }
+ }
+
+ let performNetworking = { (requestResult: Result) in
+ if cancellableToken.isCancelled {
+ self.cancelCompletion(pluginsWithCompletion, target: target)
+ return
+ }
+
+ var request: URLRequest!
+
+ switch requestResult {
+ case .success(let urlRequest):
+ request = urlRequest
+ case .failure(let error):
+ pluginsWithCompletion(.failure(error))
+ return
+ }
+
+ // Allow plugins to modify request
+ let preparedRequest = self.plugins.reduce(request) { $1.prepare($0, target: target) }
+
+ let networkCompletion: Moya.Completion = { result in
+ if self.trackInflights {
+ self.inflightRequests[endpoint]?.forEach { $0(result) }
+
+ objc_sync_enter(self)
+ self.inflightRequests.removeValue(forKey: endpoint)
+ objc_sync_exit(self)
+ } else {
+ pluginsWithCompletion(result)
+ }
+ }
+
+ cancellableToken.innerCancellable = self.performRequest(target, request: preparedRequest, callbackQueue: callbackQueue, progress: progress, completion: networkCompletion, endpoint: endpoint, stubBehavior: stubBehavior)
+ }
+
+ requestClosure(endpoint, performNetworking)
+
+ return cancellableToken
+ }
+
+ // swiftlint:disable:next function_parameter_count
+ private func performRequest(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, progress: Moya.ProgressBlock?, completion: @escaping Moya.Completion, endpoint: Endpoint, stubBehavior: Moya.StubBehavior) -> Cancellable {
+ switch stubBehavior {
+ case .never:
+ switch endpoint.task {
+ case .requestPlain, .requestData, .requestJSONEncodable, .requestCustomJSONEncodable, .requestParameters, .requestCompositeData, .requestCompositeParameters:
+ return self.sendRequest(target, request: request, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ case .uploadFile(let file):
+ return self.sendUploadFile(target, request: request, callbackQueue: callbackQueue, file: file, progress: progress, completion: completion)
+ case .uploadMultipart(let multipartBody), .uploadCompositeMultipart(let multipartBody, _):
+ guard !multipartBody.isEmpty && endpoint.method.supportsMultipart else {
+ fatalError("\(target) is not a multipart upload target.")
+ }
+ return self.sendUploadMultipart(target, request: request, callbackQueue: callbackQueue, multipartBody: multipartBody, progress: progress, completion: completion)
+ case .downloadDestination(let destination), .downloadParameters(_, _, let destination):
+ return self.sendDownloadRequest(target, request: request, callbackQueue: callbackQueue, destination: destination, progress: progress, completion: completion)
+ }
+ default:
+ return self.stubRequest(target, request: request, callbackQueue: callbackQueue, completion: completion, endpoint: endpoint, stubBehavior: stubBehavior)
+ }
+ }
+
+ func cancelCompletion(_ completion: Moya.Completion, target: Target) {
+ let error = MoyaError.underlying(NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled, userInfo: nil), nil)
+ plugins.forEach { $0.didReceive(.failure(error), target: target) }
+ completion(.failure(error))
+ }
+
+ /// Creates a function which, when called, executes the appropriate stubbing behavior for the given parameters.
+ public final func createStubFunction(_ token: CancellableToken, forTarget target: Target, withCompletion completion: @escaping Moya.Completion, endpoint: Endpoint, plugins: [PluginType], request: URLRequest) -> (() -> Void) { // swiftlint:disable:this function_parameter_count
+ return {
+ if token.isCancelled {
+ self.cancelCompletion(completion, target: target)
+ return
+ }
+
+ let validate = { (response: Moya.Response) -> Result in
+ let validCodes = target.validationType.statusCodes
+ guard !validCodes.isEmpty else { return .success(response) }
+ if validCodes.contains(response.statusCode) {
+ return .success(response)
+ } else {
+ let statusError = MoyaError.statusCode(response)
+ let error = MoyaError.underlying(statusError, response)
+ return .failure(error)
+ }
+ }
+
+ switch endpoint.sampleResponseClosure() {
+ case .networkResponse(let statusCode, let data):
+ let response = Moya.Response(statusCode: statusCode, data: data, request: request, response: nil)
+ let result = validate(response)
+ plugins.forEach { $0.didReceive(result, target: target) }
+ completion(result)
+ case .response(let customResponse, let data):
+ let response = Moya.Response(statusCode: customResponse.statusCode, data: data, request: request, response: customResponse)
+ let result = validate(response)
+ plugins.forEach { $0.didReceive(result, target: target) }
+ completion(result)
+ case .networkError(let error):
+ let error = MoyaError.underlying(error, nil)
+ plugins.forEach { $0.didReceive(.failure(error), target: target) }
+ completion(.failure(error))
+ }
+ }
+ }
+
+ /// Notify all plugins that a stub is about to be performed. You must call this if overriding `stubRequest`.
+ final func notifyPluginsOfImpendingStub(for request: URLRequest, target: Target) {
+ let alamoRequest = manager.request(request as URLRequestConvertible)
+ plugins.forEach { $0.willSend(alamoRequest, target: target) }
+ alamoRequest.cancel()
+ }
+}
+
+private extension MoyaProvider {
+ func sendUploadMultipart(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, multipartBody: [MultipartFormData], progress: Moya.ProgressBlock? = nil, completion: @escaping Moya.Completion) -> CancellableWrapper {
+ let cancellable = CancellableWrapper()
+
+ let multipartFormData: (RequestMultipartFormData) -> Void = { form in
+ form.applyMoyaMultipartFormData(multipartBody)
+ }
+
+ manager.upload(multipartFormData: multipartFormData, with: request) { result in
+ switch result {
+ case .success(let alamoRequest, _, _):
+ if cancellable.isCancelled {
+ self.cancelCompletion(completion, target: target)
+ return
+ }
+ let validationCodes = target.validationType.statusCodes
+ let validatedRequest = validationCodes.isEmpty ? alamoRequest : alamoRequest.validate(statusCode: validationCodes)
+ cancellable.innerCancellable = self.sendAlamofireRequest(validatedRequest, target: target, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ case .failure(let error):
+ completion(.failure(MoyaError.underlying(error as NSError, nil)))
+ }
+ }
+
+ return cancellable
+ }
+
+ func sendUploadFile(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, file: URL, progress: ProgressBlock? = nil, completion: @escaping Completion) -> CancellableToken {
+ let uploadRequest = manager.upload(file, with: request)
+ let validationCodes = target.validationType.statusCodes
+ let alamoRequest = validationCodes.isEmpty ? uploadRequest : uploadRequest.validate(statusCode: validationCodes)
+ return self.sendAlamofireRequest(alamoRequest, target: target, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ }
+
+ func sendDownloadRequest(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, destination: @escaping DownloadDestination, progress: ProgressBlock? = nil, completion: @escaping Completion) -> CancellableToken {
+ let downloadRequest = manager.download(request, to: destination)
+ let validationCodes = target.validationType.statusCodes
+ let alamoRequest = validationCodes.isEmpty ? downloadRequest : downloadRequest.validate(statusCode: validationCodes)
+ return self.sendAlamofireRequest(alamoRequest, target: target, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ }
+
+ func sendRequest(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, progress: Moya.ProgressBlock?, completion: @escaping Moya.Completion) -> CancellableToken {
+ let initialRequest = manager.request(request as URLRequestConvertible)
+ let validationCodes = target.validationType.statusCodes
+ let alamoRequest = validationCodes.isEmpty ? initialRequest : initialRequest.validate(statusCode: validationCodes)
+ return sendAlamofireRequest(alamoRequest, target: target, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ }
+
+ // swiftlint:disable:next cyclomatic_complexity
+ func sendAlamofireRequest(_ alamoRequest: T, target: Target, callbackQueue: DispatchQueue?, progress progressCompletion: Moya.ProgressBlock?, completion: @escaping Moya.Completion) -> CancellableToken where T: Requestable, T: Request {
+ // Give plugins the chance to alter the outgoing request
+ let plugins = self.plugins
+ plugins.forEach { $0.willSend(alamoRequest, target: target) }
+
+ var progressAlamoRequest = alamoRequest
+ let progressClosure: (Progress) -> Void = { progress in
+ let sendProgress: () -> Void = {
+ progressCompletion?(ProgressResponse(progress: progress))
+ }
+
+ if let callbackQueue = callbackQueue {
+ callbackQueue.async(execute: sendProgress)
+ } else {
+ sendProgress()
+ }
+ }
+
+ // Perform the actual request
+ if progressCompletion != nil {
+ switch progressAlamoRequest {
+ case let downloadRequest as DownloadRequest:
+ if let downloadRequest = downloadRequest.downloadProgress(closure: progressClosure) as? T {
+ progressAlamoRequest = downloadRequest
+ }
+ case let uploadRequest as UploadRequest:
+ if let uploadRequest = uploadRequest.uploadProgress(closure: progressClosure) as? T {
+ progressAlamoRequest = uploadRequest
+ }
+ case let dataRequest as DataRequest:
+ if let dataRequest = dataRequest.downloadProgress(closure: progressClosure) as? T {
+ progressAlamoRequest = dataRequest
+ }
+ default: break
+ }
+ }
+
+ let completionHandler: RequestableCompletion = { response, request, data, error in
+ let result = convertResponseToResult(response, request: request, data: data, error: error)
+ // Inform all plugins about the response
+ plugins.forEach { $0.didReceive(result, target: target) }
+ if let progressCompletion = progressCompletion {
+ switch progressAlamoRequest {
+ case let downloadRequest as DownloadRequest:
+ progressCompletion(ProgressResponse(progress: downloadRequest.progress, response: result.value))
+ case let uploadRequest as UploadRequest:
+ progressCompletion(ProgressResponse(progress: uploadRequest.uploadProgress, response: result.value))
+ case let dataRequest as DataRequest:
+ progressCompletion(ProgressResponse(progress: dataRequest.progress, response: result.value))
+ default:
+ progressCompletion(ProgressResponse(response: result.value))
+ }
+ }
+ completion(result)
+ }
+
+ progressAlamoRequest = progressAlamoRequest.response(callbackQueue: callbackQueue, completionHandler: completionHandler)
+
+ progressAlamoRequest.resume()
+
+ return CancellableToken(request: progressAlamoRequest)
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider.swift b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider.swift
new file mode 100755
index 00000000..4bced8b9
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MoyaProvider.swift
@@ -0,0 +1,206 @@
+import Foundation
+import Result
+
+/// Closure to be executed when a request has completed.
+public typealias Completion = (_ result: Result) -> Void
+
+/// Closure to be executed when progress changes.
+public typealias ProgressBlock = (_ progress: ProgressResponse) -> Void
+
+/// A type representing the progress of a request.
+public struct ProgressResponse {
+
+ /// The optional response of the request.
+ public let response: Response?
+
+ /// An object that conveys ongoing progress for a given request.
+ public let progressObject: Progress?
+
+ /// Initializes a `ProgressResponse`.
+ public init(progress: Progress? = nil, response: Response? = nil) {
+ self.progressObject = progress
+ self.response = response
+ }
+
+ /// The fraction of the overall work completed by the progress object.
+ public var progress: Double {
+ return progressObject?.fractionCompleted ?? 1.0
+ }
+
+ /// A Boolean value stating whether the request is completed.
+ public var completed: Bool {
+ return progress == 1.0 && response != nil
+ }
+}
+
+/// A protocol representing a minimal interface for a MoyaProvider.
+/// Used by the reactive provider extensions.
+public protocol MoyaProviderType: AnyObject {
+
+ associatedtype Target: TargetType
+
+ /// Designated request-making method. Returns a `Cancellable` token to cancel the request later.
+ func request(_ target: Target, callbackQueue: DispatchQueue?, progress: Moya.ProgressBlock?, completion: @escaping Moya.Completion) -> Cancellable
+}
+
+/// Request provider class. Requests should be made through this class only.
+open class MoyaProvider: MoyaProviderType {
+
+ /// Closure that defines the endpoints for the provider.
+ public typealias EndpointClosure = (Target) -> Endpoint
+
+ /// Closure that decides if and what request should be performed.
+ public typealias RequestResultClosure = (Result) -> Void
+
+ /// Closure that resolves an `Endpoint` into a `RequestResult`.
+ public typealias RequestClosure = (Endpoint, @escaping RequestResultClosure) -> Void
+
+ /// Closure that decides if/how a request should be stubbed.
+ public typealias StubClosure = (Target) -> Moya.StubBehavior
+
+ /// A closure responsible for mapping a `TargetType` to an `EndPoint`.
+ public let endpointClosure: EndpointClosure
+
+ /// A closure deciding if and what request should be performed.
+ public let requestClosure: RequestClosure
+
+ /// A closure responsible for determining the stubbing behavior
+ /// of a request for a given `TargetType`.
+ public let stubClosure: StubClosure
+
+ /// The manager for the session.
+ public let manager: Manager
+
+ /// A list of plugins.
+ /// e.g. for logging, network activity indicator or credentials.
+ public let plugins: [PluginType]
+
+ public let trackInflights: Bool
+
+ open internal(set) var inflightRequests: [Endpoint: [Moya.Completion]] = [:]
+
+ /// Propagated to Alamofire as callback queue. If nil - the Alamofire default (as of their API in 2017 - the main queue) will be used.
+ let callbackQueue: DispatchQueue?
+
+ /// Initializes a provider.
+ public init(endpointClosure: @escaping EndpointClosure = MoyaProvider.defaultEndpointMapping,
+ requestClosure: @escaping RequestClosure = MoyaProvider.defaultRequestMapping,
+ stubClosure: @escaping StubClosure = MoyaProvider.neverStub,
+ callbackQueue: DispatchQueue? = nil,
+ manager: Manager = MoyaProvider.defaultAlamofireManager(),
+ plugins: [PluginType] = [],
+ trackInflights: Bool = false) {
+
+ self.endpointClosure = endpointClosure
+ self.requestClosure = requestClosure
+ self.stubClosure = stubClosure
+ self.manager = manager
+ self.plugins = plugins
+ self.trackInflights = trackInflights
+ self.callbackQueue = callbackQueue
+ }
+
+ /// Returns an `Endpoint` based on the token, method, and parameters by invoking the `endpointClosure`.
+ open func endpoint(_ token: Target) -> Endpoint {
+ return endpointClosure(token)
+ }
+
+ /// Designated request-making method. Returns a `Cancellable` token to cancel the request later.
+ @discardableResult
+ open func request(_ target: Target,
+ callbackQueue: DispatchQueue? = .none,
+ progress: ProgressBlock? = .none,
+ completion: @escaping Completion) -> Cancellable {
+
+ let callbackQueue = callbackQueue ?? self.callbackQueue
+ return requestNormal(target, callbackQueue: callbackQueue, progress: progress, completion: completion)
+ }
+
+ // swiftlint:disable function_parameter_count
+ /// When overriding this method, take care to `notifyPluginsOfImpendingStub` and to perform the stub using the `createStubFunction` method.
+ /// Note: this was previously in an extension, however it must be in the original class declaration to allow subclasses to override.
+ @discardableResult
+ open func stubRequest(_ target: Target, request: URLRequest, callbackQueue: DispatchQueue?, completion: @escaping Moya.Completion, endpoint: Endpoint, stubBehavior: Moya.StubBehavior) -> CancellableToken {
+ let callbackQueue = callbackQueue ?? self.callbackQueue
+ let cancellableToken = CancellableToken { }
+ notifyPluginsOfImpendingStub(for: request, target: target)
+ let plugins = self.plugins
+ let stub: () -> Void = createStubFunction(cancellableToken, forTarget: target, withCompletion: completion, endpoint: endpoint, plugins: plugins, request: request)
+ switch stubBehavior {
+ case .immediate:
+ switch callbackQueue {
+ case .none:
+ stub()
+ case .some(let callbackQueue):
+ callbackQueue.async(execute: stub)
+ }
+ case .delayed(let delay):
+ let killTimeOffset = Int64(CDouble(delay) * CDouble(NSEC_PER_SEC))
+ let killTime = DispatchTime.now() + Double(killTimeOffset) / Double(NSEC_PER_SEC)
+ (callbackQueue ?? DispatchQueue.main).asyncAfter(deadline: killTime) {
+ stub()
+ }
+ case .never:
+ fatalError("Method called to stub request when stubbing is disabled.")
+ }
+
+ return cancellableToken
+ }
+ // swiftlint:enable function_parameter_count
+}
+
+/// Mark: Stubbing
+
+/// Controls how stub responses are returned.
+public enum StubBehavior {
+
+ /// Do not stub.
+ case never
+
+ /// Return a response immediately.
+ case immediate
+
+ /// Return a response after a delay.
+ case delayed(seconds: TimeInterval)
+}
+
+public extension MoyaProvider {
+
+ // Swift won't let us put the StubBehavior enum inside the provider class, so we'll
+ // at least add some class functions to allow easy access to common stubbing closures.
+
+ /// Do not stub.
+ public final class func neverStub(_: Target) -> Moya.StubBehavior {
+ return .never
+ }
+
+ /// Return a response immediately.
+ public final class func immediatelyStub(_: Target) -> Moya.StubBehavior {
+ return .immediate
+ }
+
+ /// Return a response after a delay.
+ public final class func delayedStub(_ seconds: TimeInterval) -> (Target) -> Moya.StubBehavior {
+ return { _ in return .delayed(seconds: seconds) }
+ }
+}
+
+/// A public function responsible for converting the result of a `URLRequest` to a Result.
+public func convertResponseToResult(_ response: HTTPURLResponse?, request: URLRequest?, data: Data?, error: Swift.Error?) ->
+ Result {
+ switch (response, data, error) {
+ case let (.some(response), data, .none):
+ let response = Moya.Response(statusCode: response.statusCode, data: data ?? Data(), request: request, response: response)
+ return .success(response)
+ case let (.some(response), _, .some(error)):
+ let response = Moya.Response(statusCode: response.statusCode, data: data ?? Data(), request: request, response: response)
+ let error = MoyaError.underlying(error, response)
+ return .failure(error)
+ case let (_, _, .some(error)):
+ let error = MoyaError.underlying(error, nil)
+ return .failure(error)
+ default:
+ let error = MoyaError.underlying(NSError(domain: NSURLErrorDomain, code: NSURLErrorUnknown, userInfo: nil), nil)
+ return .failure(error)
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MultiTarget.swift b/Santander-Test/Pods/Moya/Sources/Moya/MultiTarget.swift
new file mode 100644
index 00000000..7b813e4e
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MultiTarget.swift
@@ -0,0 +1,54 @@
+import Foundation
+
+/// A `TargetType` used to enable `MoyaProvider` to process multiple `TargetType`s.
+public enum MultiTarget: TargetType {
+ /// The embedded `TargetType`.
+ case target(TargetType)
+
+ /// Initializes a `MultiTarget`.
+ public init(_ target: TargetType) {
+ self = MultiTarget.target(target)
+ }
+
+ /// The embedded target's base `URL`.
+ public var path: String {
+ return target.path
+ }
+
+ /// The baseURL of the embedded target.
+ public var baseURL: URL {
+ return target.baseURL
+ }
+
+ /// The HTTP method of the embedded target.
+ public var method: Moya.Method {
+ return target.method
+ }
+
+ /// The sampleData of the embedded target.
+ public var sampleData: Data {
+ return target.sampleData
+ }
+
+ /// The `Task` of the embedded target.
+ public var task: Task {
+ return target.task
+ }
+
+ /// The `ValidationType` of the embedded target.
+ public var validationType: ValidationType {
+ return target.validationType
+ }
+
+ /// The headers of the embedded target.
+ public var headers: [String: String]? {
+ return target.headers
+ }
+
+ /// The embedded `TargetType`.
+ public var target: TargetType {
+ switch self {
+ case .target(let target): return target
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/MultipartFormData.swift b/Santander-Test/Pods/Moya/Sources/Moya/MultipartFormData.swift
new file mode 100644
index 00000000..418cae21
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/MultipartFormData.swift
@@ -0,0 +1,73 @@
+import Foundation
+import Alamofire
+
+/// Represents "multipart/form-data" for an upload.
+public struct MultipartFormData {
+
+ /// Method to provide the form data.
+ public enum FormDataProvider {
+ case data(Foundation.Data)
+ case file(URL)
+ case stream(InputStream, UInt64)
+ }
+
+ public init(provider: FormDataProvider, name: String, fileName: String? = nil, mimeType: String? = nil) {
+ self.provider = provider
+ self.name = name
+ self.fileName = fileName
+ self.mimeType = mimeType
+ }
+
+ /// The method being used for providing form data.
+ public let provider: FormDataProvider
+
+ /// The name.
+ public let name: String
+
+ /// The file name.
+ public let fileName: String?
+
+ /// The MIME type
+ public let mimeType: String?
+
+}
+
+// MARK: RequestMultipartFormData appending
+internal extension RequestMultipartFormData {
+ func append(data: Data, bodyPart: MultipartFormData) {
+ if let mimeType = bodyPart.mimeType {
+ if let fileName = bodyPart.fileName {
+ append(data, withName: bodyPart.name, fileName: fileName, mimeType: mimeType)
+ } else {
+ append(data, withName: bodyPart.name, mimeType: mimeType)
+ }
+ } else {
+ append(data, withName: bodyPart.name)
+ }
+ }
+
+ func append(fileURL url: URL, bodyPart: MultipartFormData) {
+ if let fileName = bodyPart.fileName, let mimeType = bodyPart.mimeType {
+ append(url, withName: bodyPart.name, fileName: fileName, mimeType: mimeType)
+ } else {
+ append(url, withName: bodyPart.name)
+ }
+ }
+
+ func append(stream: InputStream, length: UInt64, bodyPart: MultipartFormData) {
+ append(stream, withLength: length, name: bodyPart.name, fileName: bodyPart.fileName ?? "", mimeType: bodyPart.mimeType ?? "")
+ }
+
+ func applyMoyaMultipartFormData(_ multipartBody: [Moya.MultipartFormData]) {
+ for bodyPart in multipartBody {
+ switch bodyPart.provider {
+ case .data(let data):
+ append(data: data, bodyPart: bodyPart)
+ case .file(let url):
+ append(fileURL: url, bodyPart: bodyPart)
+ case .stream(let stream, let length):
+ append(stream: stream, length: length, bodyPart: bodyPart)
+ }
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Plugin.swift b/Santander-Test/Pods/Moya/Sources/Moya/Plugin.swift
new file mode 100644
index 00000000..3f5bd6c1
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Plugin.swift
@@ -0,0 +1,47 @@
+import Foundation
+import Result
+
+/// A Moya Plugin receives callbacks to perform side effects wherever a request is sent or received.
+///
+/// for example, a plugin may be used to
+/// - log network requests
+/// - hide and show a network activity indicator
+/// - inject additional information into a request
+public protocol PluginType {
+ /// Called to modify a request before sending.
+ func prepare(_ request: URLRequest, target: TargetType) -> URLRequest
+
+ /// Called immediately before a request is sent over the network (or stubbed).
+ func willSend(_ request: RequestType, target: TargetType)
+
+ /// Called after a response has been received, but before the MoyaProvider has invoked its completion handler.
+ func didReceive(_ result: Result, target: TargetType)
+
+ /// Called to modify a result before completion.
+ func process(_ result: Result, target: TargetType) -> Result
+}
+
+public extension PluginType {
+ func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { return request }
+ func willSend(_ request: RequestType, target: TargetType) { }
+ func didReceive(_ result: Result, target: TargetType) { }
+ func process(_ result: Result, target: TargetType) -> Result { return result }
+}
+
+/// Request type used by `willSend` plugin function.
+public protocol RequestType {
+
+ // Note:
+ //
+ // We use this protocol instead of the Alamofire request to avoid leaking that abstraction.
+ // A plugin should not know about Alamofire at all.
+
+ /// Retrieve an `NSURLRequest` representation.
+ var request: URLRequest? { get }
+
+ /// Authenticates the request with a username and password.
+ func authenticate(user: String, password: String, persistence: URLCredential.Persistence) -> Self
+
+ /// Authenticates the request with an `NSURLCredential` instance.
+ func authenticate(usingCredential credential: URLCredential) -> Self
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Plugins/AccessTokenPlugin.swift b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/AccessTokenPlugin.swift
new file mode 100644
index 00000000..e1234e22
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/AccessTokenPlugin.swift
@@ -0,0 +1,93 @@
+import Foundation
+import Result
+
+// MARK: - AccessTokenAuthorizable
+
+/// A protocol for controlling the behavior of `AccessTokenPlugin`.
+public protocol AccessTokenAuthorizable {
+
+ /// Represents the authorization header to use for requests.
+ var authorizationType: AuthorizationType { get }
+}
+
+// MARK: - AuthorizationType
+
+/// An enum representing the header to use with an `AccessTokenPlugin`
+public enum AuthorizationType {
+ /// No header.
+ case none
+
+ /// The `"Basic"` header.
+ case basic
+
+ /// The `"Bearer"` header.
+ case bearer
+
+ /// Custom header implementation.
+ case custom(String)
+
+ public var value: String? {
+ switch self {
+ case .none: return nil
+ case .basic: return "Basic"
+ case .bearer: return "Bearer"
+ case .custom(let customValue): return customValue
+ }
+ }
+}
+
+// MARK: - AccessTokenPlugin
+
+/**
+ A plugin for adding basic or bearer-type authorization headers to requests. Example:
+
+ ```
+ Authorization: Basic
+ Authorization: Bearer
+ Authorization: <Сustom>
+ ```
+
+*/
+public struct AccessTokenPlugin: PluginType {
+
+ /// A closure returning the access token to be applied in the header.
+ public let tokenClosure: () -> String
+
+ /**
+ Initialize a new `AccessTokenPlugin`.
+
+ - parameters:
+ - tokenClosure: A closure returning the token to be applied in the pattern `Authorization: `
+ */
+ public init(tokenClosure: @escaping () -> String) {
+ self.tokenClosure = tokenClosure
+ }
+
+ /**
+ Prepare a request by adding an authorization header if necessary.
+
+ - parameters:
+ - request: The request to modify.
+ - target: The target of the request.
+ - returns: The modified `URLRequest`.
+ */
+ public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
+
+ guard let authorizable = target as? AccessTokenAuthorizable else { return request }
+
+ let authorizationType = authorizable.authorizationType
+ var request = request
+
+ switch authorizationType {
+ case .basic, .bearer, .custom:
+ if let value = authorizationType.value {
+ let authValue = value + " " + tokenClosure()
+ request.addValue(authValue, forHTTPHeaderField: "Authorization")
+ }
+ case .none:
+ break
+ }
+
+ return request
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Plugins/CredentialsPlugin.swift b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/CredentialsPlugin.swift
new file mode 100644
index 00000000..5f22aab8
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/CredentialsPlugin.swift
@@ -0,0 +1,22 @@
+import Foundation
+import Result
+
+/// Provides each request with optional URLCredentials.
+public final class CredentialsPlugin: PluginType {
+
+ public typealias CredentialClosure = (TargetType) -> URLCredential?
+ let credentialsClosure: CredentialClosure
+
+ /// Initializes a CredentialsPlugin.
+ public init(credentialsClosure: @escaping CredentialClosure) {
+ self.credentialsClosure = credentialsClosure
+ }
+
+ // MARK: Plugin
+
+ public func willSend(_ request: RequestType, target: TargetType) {
+ if let credentials = credentialsClosure(target) {
+ _ = request.authenticate(usingCredential: credentials)
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkActivityPlugin.swift b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkActivityPlugin.swift
new file mode 100644
index 00000000..c9001051
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkActivityPlugin.swift
@@ -0,0 +1,31 @@
+import Foundation
+import Result
+
+/// Network activity change notification type.
+public enum NetworkActivityChangeType {
+ case began, ended
+}
+
+/// Notify a request's network activity changes (request begins or ends).
+public final class NetworkActivityPlugin: PluginType {
+
+ public typealias NetworkActivityClosure = (_ change: NetworkActivityChangeType, _ target: TargetType) -> Void
+ let networkActivityClosure: NetworkActivityClosure
+
+ /// Initializes a NetworkActivityPlugin.
+ public init(networkActivityClosure: @escaping NetworkActivityClosure) {
+ self.networkActivityClosure = networkActivityClosure
+ }
+
+ // MARK: Plugin
+
+ /// Called by the provider as soon as the request is about to start
+ public func willSend(_ request: RequestType, target: TargetType) {
+ networkActivityClosure(.began, target)
+ }
+
+ /// Called by the provider as soon as a response arrives, even if the request is canceled.
+ public func didReceive(_ result: Result, target: TargetType) {
+ networkActivityClosure(.ended, target)
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkLoggerPlugin.swift b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkLoggerPlugin.swift
new file mode 100644
index 00000000..cc91afe8
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Plugins/NetworkLoggerPlugin.swift
@@ -0,0 +1,114 @@
+import Foundation
+import Result
+
+/// Logs network activity (outgoing requests and incoming responses).
+public final class NetworkLoggerPlugin: PluginType {
+ fileprivate let loggerId = "Moya_Logger"
+ fileprivate let dateFormatString = "dd/MM/yyyy HH:mm:ss"
+ fileprivate let dateFormatter = DateFormatter()
+ fileprivate let separator = ", "
+ fileprivate let terminator = "\n"
+ fileprivate let cURLTerminator = "\\\n"
+ fileprivate let output: (_ separator: String, _ terminator: String, _ items: Any...) -> Void
+ fileprivate let requestDataFormatter: ((Data) -> (String))?
+ fileprivate let responseDataFormatter: ((Data) -> (Data))?
+
+ /// A Boolean value determing whether response body data should be logged.
+ public let isVerbose: Bool
+ public let cURL: Bool
+
+ /// Initializes a NetworkLoggerPlugin.
+ public init(verbose: Bool = false, cURL: Bool = false, output: ((_ separator: String, _ terminator: String, _ items: Any...) -> Void)? = nil, requestDataFormatter: ((Data) -> (String))? = nil, responseDataFormatter: ((Data) -> (Data))? = nil) {
+ self.cURL = cURL
+ self.isVerbose = verbose
+ self.output = output ?? NetworkLoggerPlugin.reversedPrint
+ self.requestDataFormatter = requestDataFormatter
+ self.responseDataFormatter = responseDataFormatter
+ }
+
+ public func willSend(_ request: RequestType, target: TargetType) {
+ if let request = request as? CustomDebugStringConvertible, cURL {
+ output(separator, terminator, request.debugDescription)
+ return
+ }
+ outputItems(logNetworkRequest(request.request as URLRequest?))
+ }
+
+ public func didReceive(_ result: Result, target: TargetType) {
+ if case .success(let response) = result {
+ outputItems(logNetworkResponse(response.response, data: response.data, target: target))
+ } else {
+ outputItems(logNetworkResponse(nil, data: nil, target: target))
+ }
+ }
+
+ fileprivate func outputItems(_ items: [String]) {
+ if isVerbose {
+ items.forEach { output(separator, terminator, $0) }
+ } else {
+ output(separator, terminator, items)
+ }
+ }
+}
+
+private extension NetworkLoggerPlugin {
+
+ var date: String {
+ dateFormatter.dateFormat = dateFormatString
+ dateFormatter.locale = Locale(identifier: "en_US_POSIX")
+ return dateFormatter.string(from: Date())
+ }
+
+ func format(_ loggerId: String, date: String, identifier: String, message: String) -> String {
+ return "\(loggerId): [\(date)] \(identifier): \(message)"
+ }
+
+ func logNetworkRequest(_ request: URLRequest?) -> [String] {
+
+ var output = [String]()
+
+ output += [format(loggerId, date: date, identifier: "Request", message: request?.description ?? "(invalid request)")]
+
+ if let headers = request?.allHTTPHeaderFields {
+ output += [format(loggerId, date: date, identifier: "Request Headers", message: headers.description)]
+ }
+
+ if let bodyStream = request?.httpBodyStream {
+ output += [format(loggerId, date: date, identifier: "Request Body Stream", message: bodyStream.description)]
+ }
+
+ if let httpMethod = request?.httpMethod {
+ output += [format(loggerId, date: date, identifier: "HTTP Request Method", message: httpMethod)]
+ }
+
+ if let body = request?.httpBody, let stringOutput = requestDataFormatter?(body) ?? String(data: body, encoding: .utf8), isVerbose {
+ output += [format(loggerId, date: date, identifier: "Request Body", message: stringOutput)]
+ }
+
+ return output
+ }
+
+ func logNetworkResponse(_ response: HTTPURLResponse?, data: Data?, target: TargetType) -> [String] {
+ guard let response = response else {
+ return [format(loggerId, date: date, identifier: "Response", message: "Received empty network response for \(target).")]
+ }
+
+ var output = [String]()
+
+ output += [format(loggerId, date: date, identifier: "Response", message: response.description)]
+
+ if let data = data, let stringData = String(data: responseDataFormatter?(data) ?? data, encoding: String.Encoding.utf8), isVerbose {
+ output += [stringData]
+ }
+
+ return output
+ }
+}
+
+fileprivate extension NetworkLoggerPlugin {
+ static func reversedPrint(_ separator: String, terminator: String, items: Any...) {
+ for item in items {
+ print(item, separator: separator, terminator: terminator)
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Response.swift b/Santander-Test/Pods/Moya/Sources/Moya/Response.swift
new file mode 100644
index 00000000..42567ccc
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Response.swift
@@ -0,0 +1,192 @@
+import Foundation
+
+/// Represents a response to a `MoyaProvider.request`.
+public final class Response: CustomDebugStringConvertible, Equatable {
+
+ /// The status code of the response.
+ public let statusCode: Int
+
+ /// The response data.
+ public let data: Data
+
+ /// The original URLRequest for the response.
+ public let request: URLRequest?
+
+ /// The HTTPURLResponse object.
+ public let response: HTTPURLResponse?
+
+ public init(statusCode: Int, data: Data, request: URLRequest? = nil, response: HTTPURLResponse? = nil) {
+ self.statusCode = statusCode
+ self.data = data
+ self.request = request
+ self.response = response
+ }
+
+ /// A text description of the `Response`.
+ public var description: String {
+ return "Status Code: \(statusCode), Data Length: \(data.count)"
+ }
+
+ /// A text description of the `Response`. Suitable for debugging.
+ public var debugDescription: String {
+ return description
+ }
+
+ public static func == (lhs: Response, rhs: Response) -> Bool {
+ return lhs.statusCode == rhs.statusCode
+ && lhs.data == rhs.data
+ && lhs.response == rhs.response
+ }
+}
+
+public extension Response {
+
+ /**
+ Returns the `Response` if the `statusCode` falls within the specified range.
+
+ - parameters:
+ - statusCodes: The range of acceptable status codes.
+ - throws: `MoyaError.statusCode` when others are encountered.
+ */
+ public func filter(statusCodes: R) throws -> Response where R.Bound == Int {
+ guard statusCodes.contains(statusCode) else {
+ throw MoyaError.statusCode(self)
+ }
+ return self
+ }
+
+ /**
+ Returns the `Response` if it has the specified `statusCode`.
+
+ - parameters:
+ - statusCode: The acceptable status code.
+ - throws: `MoyaError.statusCode` when others are encountered.
+ */
+ public func filter(statusCode: Int) throws -> Response {
+ return try filter(statusCodes: statusCode...statusCode)
+ }
+
+ /**
+ Returns the `Response` if the `statusCode` falls within the range 200 - 299.
+
+ - throws: `MoyaError.statusCode` when others are encountered.
+ */
+ public func filterSuccessfulStatusCodes() throws -> Response {
+ return try filter(statusCodes: 200...299)
+ }
+
+ /**
+ Returns the `Response` if the `statusCode` falls within the range 200 - 399.
+
+ - throws: `MoyaError.statusCode` when others are encountered.
+ */
+ public func filterSuccessfulStatusAndRedirectCodes() throws -> Response {
+ return try filter(statusCodes: 200...399)
+ }
+
+ /// Maps data received from the signal into an Image.
+ func mapImage() throws -> Image {
+ guard let image = Image(data: data) else {
+ throw MoyaError.imageMapping(self)
+ }
+ return image
+ }
+
+ /// Maps data received from the signal into a JSON object.
+ ///
+ /// - parameter failsOnEmptyData: A Boolean value determining
+ /// whether the mapping should fail if the data is empty.
+ func mapJSON(failsOnEmptyData: Bool = true) throws -> Any {
+ do {
+ return try JSONSerialization.jsonObject(with: data, options: .allowFragments)
+ } catch {
+ if data.count < 1 && !failsOnEmptyData {
+ return NSNull()
+ }
+ throw MoyaError.jsonMapping(self)
+ }
+ }
+
+ /// Maps data received from the signal into a String.
+ ///
+ /// - parameter atKeyPath: Optional key path at which to parse string.
+ public func mapString(atKeyPath keyPath: String? = nil) throws -> String {
+ if let keyPath = keyPath {
+ // Key path was provided, try to parse string at key path
+ guard let jsonDictionary = try mapJSON() as? NSDictionary,
+ let string = jsonDictionary.value(forKeyPath: keyPath) as? String else {
+ throw MoyaError.stringMapping(self)
+ }
+ return string
+ } else {
+ // Key path was not provided, parse entire response as string
+ guard let string = String(data: data, encoding: .utf8) else {
+ throw MoyaError.stringMapping(self)
+ }
+ return string
+ }
+ }
+
+ /// Maps data received from the signal into a Decodable object.
+ ///
+ /// - parameter atKeyPath: Optional key path at which to parse object.
+ /// - parameter using: A `JSONDecoder` instance which is used to decode data to an object.
+ func map(_ type: D.Type, atKeyPath keyPath: String? = nil, using decoder: JSONDecoder = JSONDecoder(), failsOnEmptyData: Bool = true) throws -> D {
+ let serializeToData: (Any) throws -> Data? = { (jsonObject) in
+ guard JSONSerialization.isValidJSONObject(jsonObject) else {
+ return nil
+ }
+ do {
+ return try JSONSerialization.data(withJSONObject: jsonObject)
+ } catch {
+ throw MoyaError.jsonMapping(self)
+ }
+ }
+ let jsonData: Data
+ keyPathCheck: if let keyPath = keyPath {
+ guard let jsonObject = (try mapJSON(failsOnEmptyData: failsOnEmptyData) as? NSDictionary)?.value(forKeyPath: keyPath) else {
+ if failsOnEmptyData {
+ throw MoyaError.jsonMapping(self)
+ } else {
+ jsonData = data
+ break keyPathCheck
+ }
+ }
+
+ if let data = try serializeToData(jsonObject) {
+ jsonData = data
+ } else {
+ let wrappedJsonObject = ["value": jsonObject]
+ let wrappedJsonData: Data
+ if let data = try serializeToData(wrappedJsonObject) {
+ wrappedJsonData = data
+ } else {
+ throw MoyaError.jsonMapping(self)
+ }
+ do {
+ return try decoder.decode(DecodableWrapper.self, from: wrappedJsonData).value
+ } catch let error {
+ throw MoyaError.objectMapping(error, self)
+ }
+ }
+ } else {
+ jsonData = data
+ }
+ do {
+ if jsonData.count < 1 && !failsOnEmptyData {
+ if let emptyJSONObjectData = "{}".data(using: .utf8), let emptyDecodableValue = try? decoder.decode(D.self, from: emptyJSONObjectData) {
+ return emptyDecodableValue
+ } else if let emptyJSONArrayData = "[{}]".data(using: .utf8), let emptyDecodableValue = try? decoder.decode(D.self, from: emptyJSONArrayData) {
+ return emptyDecodableValue
+ }
+ }
+ return try decoder.decode(D.self, from: jsonData)
+ } catch let error {
+ throw MoyaError.objectMapping(error, self)
+ }
+ }
+}
+
+private struct DecodableWrapper: Decodable {
+ let value: T
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/TargetType.swift b/Santander-Test/Pods/Moya/Sources/Moya/TargetType.swift
new file mode 100644
index 00000000..48c77a00
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/TargetType.swift
@@ -0,0 +1,44 @@
+import Foundation
+
+/// The protocol used to define the specifications necessary for a `MoyaProvider`.
+public protocol TargetType {
+
+ /// The target's base `URL`.
+ var baseURL: URL { get }
+
+ /// The path to be appended to `baseURL` to form the full `URL`.
+ var path: String { get }
+
+ /// The HTTP method used in the request.
+ var method: Moya.Method { get }
+
+ /// Provides stub data for use in testing.
+ var sampleData: Data { get }
+
+ /// The type of HTTP task to be performed.
+ var task: Task { get }
+
+ /// The type of validation to perform on the request. Default is `.none`.
+ var validationType: ValidationType { get }
+
+ /// The headers to be used in the request.
+ var headers: [String: String]? { get }
+}
+
+public extension TargetType {
+
+ /// The type of validation to perform on the request. Default is `.none`.
+ var validationType: ValidationType {
+ return .none
+ }
+}
+
+// MARK: - Deprecated
+
+extension TargetType {
+ @available(*, deprecated: 11.0, message:
+ "TargetType's validate property has been deprecated in 11.0. Please use validationType: ValidationType.")
+ var validate: Bool {
+ return false
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/Task.swift b/Santander-Test/Pods/Moya/Sources/Moya/Task.swift
new file mode 100644
index 00000000..191e2593
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/Task.swift
@@ -0,0 +1,41 @@
+import Foundation
+
+/// Represents an HTTP task.
+public enum Task {
+
+ /// A request with no additional data.
+ case requestPlain
+
+ /// A requests body set with data.
+ case requestData(Data)
+
+ /// A request body set with `Encodable` type
+ case requestJSONEncodable(Encodable)
+
+ /// A request body set with `Encodable` type and custom encoder
+ case requestCustomJSONEncodable(Encodable, encoder: JSONEncoder)
+
+ /// A requests body set with encoded parameters.
+ case requestParameters(parameters: [String: Any], encoding: ParameterEncoding)
+
+ /// A requests body set with data, combined with url parameters.
+ case requestCompositeData(bodyData: Data, urlParameters: [String: Any])
+
+ /// A requests body set with encoded parameters combined with url parameters.
+ case requestCompositeParameters(bodyParameters: [String: Any], bodyEncoding: ParameterEncoding, urlParameters: [String: Any])
+
+ /// A file upload task.
+ case uploadFile(URL)
+
+ /// A "multipart/form-data" upload task.
+ case uploadMultipart([MultipartFormData])
+
+ /// A "multipart/form-data" upload task combined with url parameters.
+ case uploadCompositeMultipart([MultipartFormData], urlParameters: [String: Any])
+
+ /// A file download task to a destination.
+ case downloadDestination(DownloadDestination)
+
+ /// A file download task to a destination with extra parameters using the given encoding.
+ case downloadParameters(parameters: [String: Any], encoding: ParameterEncoding, destination: DownloadDestination)
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/URL+Moya.swift b/Santander-Test/Pods/Moya/Sources/Moya/URL+Moya.swift
new file mode 100644
index 00000000..9351fa43
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/URL+Moya.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+public extension URL {
+
+ /// Initialize URL from Moya's `TargetType`.
+ init(target: T) {
+ // When a TargetType's path is empty, URL.appendingPathComponent may introduce trailing /, which may not be wanted in some cases
+ // See: https://github.com/Moya/Moya/pull/1053
+ // And: https://github.com/Moya/Moya/issues/1049
+ if target.path.isEmpty {
+ self = target.baseURL
+ } else {
+ self = target.baseURL.appendingPathComponent(target.path)
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/URLRequest+Encoding.swift b/Santander-Test/Pods/Moya/Sources/Moya/URLRequest+Encoding.swift
new file mode 100644
index 00000000..232d86df
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/URLRequest+Encoding.swift
@@ -0,0 +1,28 @@
+import Foundation
+
+internal extension URLRequest {
+
+ mutating func encoded(encodable: Encodable, encoder: JSONEncoder = JSONEncoder()) throws -> URLRequest {
+ do {
+ let encodable = AnyEncodable(encodable)
+ httpBody = try encoder.encode(encodable)
+
+ let contentTypeHeaderName = "Content-Type"
+ if value(forHTTPHeaderField: contentTypeHeaderName) == nil {
+ setValue("application/json", forHTTPHeaderField: contentTypeHeaderName)
+ }
+
+ return self
+ } catch {
+ throw MoyaError.encodableMapping(error)
+ }
+ }
+
+ func encoded(parameters: [String: Any], parameterEncoding: ParameterEncoding) throws -> URLRequest {
+ do {
+ return try parameterEncoding.encode(self, with: parameters)
+ } catch {
+ throw MoyaError.parameterEncoding(error)
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Moya/Sources/Moya/ValidationType.swift b/Santander-Test/Pods/Moya/Sources/Moya/ValidationType.swift
new file mode 100644
index 00000000..ffc8d8f2
--- /dev/null
+++ b/Santander-Test/Pods/Moya/Sources/Moya/ValidationType.swift
@@ -0,0 +1,47 @@
+import Foundation
+
+/// Represents the status codes to validate through Alamofire.
+public enum ValidationType {
+
+ /// No validation.
+ case none
+
+ /// Validate success codes (only 2xx).
+ case successCodes
+
+ /// Validate success codes and redirection codes (only 2xx and 3xx).
+ case successAndRedirectCodes
+
+ /// Validate only the given status codes.
+ case customCodes([Int])
+
+ /// The list of HTTP status codes to validate.
+ var statusCodes: [Int] {
+ switch self {
+ case .successCodes:
+ return Array(200..<300)
+ case .successAndRedirectCodes:
+ return Array(200..<400)
+ case .customCodes(let codes):
+ return codes
+ case .none:
+ return []
+ }
+ }
+}
+
+extension ValidationType: Equatable {
+
+ public static func == (lhs: ValidationType, rhs: ValidationType) -> Bool {
+ switch (lhs, rhs) {
+ case (.none, .none),
+ (.successCodes, .successCodes),
+ (.successAndRedirectCodes, .successAndRedirectCodes):
+ return true
+ case (.customCodes(let code1), .customCodes(let code2)):
+ return code1 == code2
+ default:
+ return false
+ }
+ }
+}
diff --git a/Santander-Test/Pods/Pods.xcodeproj/project.pbxproj b/Santander-Test/Pods/Pods.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..6575d7f9
--- /dev/null
+++ b/Santander-Test/Pods/Pods.xcodeproj/project.pbxproj
@@ -0,0 +1,2188 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 02FB225950EEA73C12B14A3D74A2096E /* IQUIView+IQKeyboardToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82C69D1A74C5F456C4A803DFAC82CE09 /* IQUIView+IQKeyboardToolbar.swift */; };
+ 059D92B7BBFBEC53E9A3B6E11C5C3B3A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05EA68EF87A95B537922D70C6DC0427 /* Response.swift */; };
+ 077FC20E6644D0CC24318906467DB4EA /* StatusAlertUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D88DA44C23CFA4142EBCFF9B27EFF5 /* StatusAlertUtils.swift */; };
+ 09067C2692931E434234858ADBC4C6D6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 09F37003965A0689DCDB98EEBF35988A /* PopTip+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED4C8B5361C64793391D06271956C190 /* PopTip+Transitions.swift */; };
+ 0A39AF55285A3A4F7CBABB6D822FA4A3 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 364E4A632F5EC247E27102522F340CDD /* Alamofire.swift */; };
+ 117A9A7A12D6466C58337E512984EA09 /* AMPopTip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9B159763A6EABA1D15D3D6E8BB8EE3 /* AMPopTip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 11F309B46EE6B36CB281409A579996C0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 1B131595178FA51FC0B7C2FB12ED5ADB /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D55C096C7852AD0FD5900FFDEC056A7 /* Endpoint.swift */; };
+ 1C496E2C46E94DECD60F0B1C7CA511E4 /* NetworkLoggerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BBA6A8B1542C5036781E5CB1AD15100 /* NetworkLoggerPlugin.swift */; };
+ 1D29D2ACADF961F69D32B06FA6A09E28 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71C48AA44E7FE6CA667F2F4956309ED0 /* Notifications.swift */; };
+ 225E880F1459B17432E7DF840D03A3E7 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1271F76A652701E7081E1256BCEA38D5 /* Task.swift */; };
+ 2F0E58380E710D15560B27A683FB6FE3 /* PopTip+Draw.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9DFC3190B2000CE552C11328102AD09 /* PopTip+Draw.swift */; };
+ 3005629E42A84DED8C68F0C783DEE3A6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 30C07F53D870FC78B292E0E4F91FEE9E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 86F84942F79C4255F7497FC979196A65 /* QuartzCore.framework */; };
+ 313895F247F6C04661152D6D4948C100 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7905351DDA208FF2BCDDDB073F863EA1 /* Image.swift */; };
+ 314B8AD1268E89278CCE47BFEA79C43F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 31895E3CF848D69123E3A6DDEDBBF86F /* URL+Moya.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C902A8CC69883010175615A839CBCD /* URL+Moya.swift */; };
+ 32083CD40AE0F52B9C5EE6520F51D866 /* AMPopTip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1299D2802DF81035888B1EF8BD097426 /* AMPopTip-dummy.m */; };
+ 329BBBB341642193502FA0DF77C011FA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EFB6498CD7E9F2FB9A16399EB90D28B7 /* UIKit.framework */; };
+ 355C18EEC82624A06A6CC93965258E33 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58D219C426FD2752002E027A43233F2 /* Request.swift */; };
+ 36DD0B1007BF3C7BFE352704D5C415F7 /* IQTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6C381B71ED17C8633C06674859A450 /* IQTextView.swift */; };
+ 3BD1DAFE1F3E6C9E4EB0F2099B6D6FA2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 3E0749AF6C51BCF0E4A41CF1D6A76FED /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00DACC21DA90E8AA013FAE6339E6E285 /* DispatchQueue+Alamofire.swift */; };
+ 4467D1C8AABFA6FC321AC7CD6F327B48 /* IQUITextFieldView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB4BE60C2E697DB2B80B3F13833F5E8 /* IQUITextFieldView+Additions.swift */; };
+ 4A3294F2FCFF96D15DA6FD2D5D839788 /* IQUIView+Hierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FD9D3900B13A0C0C03E7343CB19EF /* IQUIView+Hierarchy.swift */; };
+ 4A42935426AB30760B47ADDE1BB1C39D /* NoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC703355C70EAC3B48FF2F65BEF1DAB /* NoError.swift */; };
+ 4D3F118DF9909DFF62FD2453B5EED984 /* StatusAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793D9BD7B815AAF1CE1A5BC097261E71 /* StatusAlert.swift */; };
+ 4E3E6EC07A4F261D041BA0C4CA258260 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1829CB35B6E3E9121C9CF36E8FCDBAE6 /* CoreGraphics.framework */; };
+ 5677C54BF14ABA45675F2DEB98AFD0D1 /* IQKeyboardManagerSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C6D9AAE7AFB1D510907D85B8CAC6B6 /* IQKeyboardManagerSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 58DAB19CBEC891D2FC9C085735782F33 /* StatusAlert-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BC9DAF4C343EFAC7BEC0603F45F19B3 /* StatusAlert-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5A18281634C290F12C5ABF249DEE9564 /* UIDevice+Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83455889E13854AD8ABDD99CD2CC39DA /* UIDevice+Platform.swift */; };
+ 5D53EA65636A0B296726611E3C491CF7 /* Result-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FA89BCF8A139DFA2E60DDAB8DC3BDFE1 /* Result-dummy.m */; };
+ 5D97ACC58BF197F2426B2C6853142DF5 /* NetworkActivityPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26A8905411437A4096352B51EC87710 /* NetworkActivityPlugin.swift */; };
+ 60B6C2A003864AAD3A426448152F67BE /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED490BFE696CCBB0DFAA6B89FB2ACBF /* Timeline.swift */; };
+ 633A43974DB81C2CCB1A2C3A7B1BFB37 /* IQKeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DECA3076074BA79EE14747097FA4232 /* IQKeyboardManager.swift */; };
+ 6499810827FC895E23B2E30263617389 /* Plugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C7B2747A259463EF9F583ED0735FFF /* Plugin.swift */; };
+ 64C35953B1CEDA2F929331C7626611CC /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C381BBCB0AA8AFC6E94A60990BF256E /* MultipartFormData.swift */; };
+ 68BB9452F3012913BABE12BE69C74785 /* AnyEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47CDDA230D44A9D90E4E680D0F704ECA /* AnyEncodable.swift */; };
+ 6AAA002A59C5011CB71E9B83E6803C6D /* ResultProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E07512BEE542791831615B14890629F /* ResultProtocol.swift */; };
+ 6CA1BEBC175680F7D37A9C47917203B1 /* Pods-Santander-TestUITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1410754A2D8AEF29CBAD3CF4DC4714BB /* Pods-Santander-TestUITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 6D5139BE6172B47602185037BB82DF47 /* PopTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9505602C5BF594EAAC4A87E55F2C370A /* PopTip.swift */; };
+ 6E04C92190FD45451E6690122ABF62E9 /* Moya-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A64D86776CE0A15D579A12A1E3435FC /* Moya-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 6E64C6F2AF1EBF3B28AD5CC90D8D3E2F /* AnyError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8821CC7B10075A400D45D7905D391703 /* AnyError.swift */; };
+ 6EFD003458AE7F689DEA720A2030C261 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CF22CDAC0AC4795D80AD5F6585FDCB2 /* ResponseSerialization.swift */; };
+ 700D3D95AF9520CB227846DFD943A2DA /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD6CDA7D7EAF4FC3809223A51A3B6520 /* ParameterEncoding.swift */; };
+ 73AB05789A4982944AF68DBD013E3EB7 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F4581CF8577E41F9E26140B86166D4 /* NetworkReachabilityManager.swift */; };
+ 772911DA6E33D1CBBC30131B7C8BDBB3 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DD6D83DD5AE4B9C0CA1C80B73978D5F /* Alamofire-dummy.m */; };
+ 778F9B551E5A346DA84BC46CBFFA1B22 /* CredentialsPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EB06C4313AEB9EB7D11D7BC4AC79893 /* CredentialsPlugin.swift */; };
+ 77E8F0EB9FFBE2E3EB0C77095C644606 /* TaskDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756857999614F2D10AB3F2D2085DB1A7 /* TaskDelegate.swift */; };
+ 7A6FFEFDCF07683D5E2976077212FD27 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 7BEFFCD672FD28B3D77927E392412FB9 /* Result-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 11E428322B8F20B4BD04558E00C12301 /* Result-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7E3538A6992A38276764936A9733493D /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5BE578C477043FD77994721DF2CF79 /* AFError.swift */; };
+ 80111F83B0BCA39D24985D0F122F0001 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7C27ADB3CDDE59F459AB5DF4B23583F /* Result.swift */; };
+ 88AE9E6392539A558E0F4417775EEA91 /* URLRequest+Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BF013BC64BC6FEC0A17E5BB75E959F7 /* URLRequest+Encoding.swift */; };
+ 88D92EDE37F1B362ECB8A6F8911DAC6E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ 8C7CD095FC0252C2920A4204819AF718 /* Pods-Santander-Test-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FAA9914E2184A41D32A3A311B1860 /* Pods-Santander-Test-dummy.m */; };
+ 8D2A6A90A6DDAF75EA52D471258545CC /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F87DA44039A5D2EC5DB495708C0AB39 /* ServerTrustPolicy.swift */; };
+ 92E9BD908B71CFA1C6EDA2FA86BF1635 /* IQKeyboardManagerSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A5271583821AE646F1015B53E4B0D22C /* IQKeyboardManagerSwift-dummy.m */; };
+ 9774AB3F3E8B65D7F1A644CCA6254D03 /* Pods-Santander-TestTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 638AF6E4AD3D6CF6AED6C2F601C4A809 /* Pods-Santander-TestTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 986EF56798DE2C7C65737AD9334E517D /* IQNSArray+Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CA6ADC7C7F6B367BAD8CBEBF1343A6 /* IQNSArray+Sort.swift */; };
+ 9EBD0113F23A6FBB0CDC07F66E77ED81 /* AccessTokenPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82244C246EAA54475DC81632EA200415 /* AccessTokenPlugin.swift */; };
+ A1EC41966B261DCE460BCDE5124A1DBE /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94FBF4B876049E18090503AA42985DEC /* SessionDelegate.swift */; };
+ A266363126A240900FCC5CCFE1EDB8BE /* Moya+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4B95F0E633A9A9A8873BF0C4903533 /* Moya+Alamofire.swift */; };
+ A380ABE3F1AF1CA7A14F9449BDC0B73F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ AA56769D8733D3F3E7976742D5ABA998 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821A0250D510FC0475D60FCF6CA59F8 /* Validation.swift */; };
+ AB037232146E78285C5B8F6394D1A658 /* MultiTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F01307A1F45845DBA269F14D919F08 /* MultiTarget.swift */; };
+ AEA829AB1A8AF2AD077A808AED6B178A /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19C5155BECC982BA93863CCE6A88B01 /* MultipartFormData.swift */; };
+ B178B38FCD7F99B07422484FC7FD6861 /* IQKeyboardManager.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4E6702644CDF6D2BB61A66FB6113E484 /* IQKeyboardManager.bundle */; };
+ B1EB1CD6804A333102774EA1DE9F1B94 /* TargetType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7896B8BF68E862E13985590C6A5FA5E3 /* TargetType.swift */; };
+ B277AE2A50A7C5F6B1BB9EDA5E1A97B8 /* Pods-Santander-TestTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E349DAE1260294B909EE4EF74E1CEE /* Pods-Santander-TestTests-dummy.m */; };
+ B2A4A7D1BD7C4D59EA0FF0A49163A387 /* IQBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F79064F1A379876B04975C47909474E /* IQBarButtonItem.swift */; };
+ B642F75A16A71ED991DB8A9DA65AD439 /* ValidationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3AC696856747E97BB0C7036CC738F0 /* ValidationType.swift */; };
+ B6F6E4CC26451E91B59FAE0F6841DC1F /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9007EDEB45A2B5EBA58AEBA614715C01 /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ B71861435CE67838D5C615C7BF529F8D /* StatusAlert-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F52E478305B403B1169C3B03E7EBC07F /* StatusAlert-dummy.m */; };
+ B888C49BC46C9A62CBF03A8FAD7126F1 /* IQInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C23191AA0D756503E4C42654D277AE58 /* IQInvocation.swift */; };
+ B8FBCA47A659B360E2684C44D970F107 /* Pods-Santander-Test-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 064B8C62456DB7AEFF1AEFF7FC9E39F7 /* Pods-Santander-Test-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ BA61F495C0E45AA2A88D21D51575FF02 /* IQKeyboardReturnKeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F1E014D4F06349619A808BCC3D021A /* IQKeyboardReturnKeyHandler.swift */; };
+ C089BCD74D2A26B10186867D672DA506 /* UIDevice+Blur.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE397110EB17007AD8326CD6E6A3C67E /* UIDevice+Blur.swift */; };
+ C5A49CAAB41E281C266C192EADBE4EB7 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45C4ABEAFCB4FA284808F5DBE887B20D /* Alamofire.framework */; };
+ CD321D15156EF51F506D6183152B0E1C /* MoyaProvider+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 291574678DD74D639BB420782B57ECFC /* MoyaProvider+Internal.swift */; };
+ D0D3B6F6481841FB0B0DC61653217179 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 731A83702890AE7019DC4C29DB8E4EC9 /* Response.swift */; };
+ D348D88FE7939869DE08BC623976B321 /* Moya-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F7B15147E249F80E5874E77D31A450C /* Moya-dummy.m */; };
+ D3A177F9BCAD7042B46E0A36CEDDBF8E /* IQTitleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 157AB990513DA582CA4369A962E2F52F /* IQTitleBarButtonItem.swift */; };
+ D3FA0AA634AAEA99AB3FABC36BB4958C /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF6CAF521EED88DF2040CD240D5F4C3A /* SessionManager.swift */; };
+ D7D49BAE6EAAD5EC2DAF370BCDE783A2 /* IQToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 214339B9ACA04BC4CA6C980F9545E964 /* IQToolbar.swift */; };
+ D8F4B5841E455F5170B1C2FC30863B05 /* IQKeyboardManagerConstantsInternal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3007389BFB5C400ADA99640D19484908 /* IQKeyboardManagerConstantsInternal.swift */; };
+ DD420F096096C518F8E6B44583BF6521 /* IQKeyboardManagerConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE087567C6073974F01DC1BAA34DE25C /* IQKeyboardManagerConstants.swift */; };
+ DD90258D5667ACC775417DE0E6EE6E77 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C283542EF8EEF865485C078FFAAD4FCC /* Result.framework */; };
+ DDAC963022C8D96EBAAD2284780E0276 /* IQUIScrollView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13E4593C0360CBA8031C9DC2E64BEBC1 /* IQUIScrollView+Additions.swift */; };
+ DE6AC2459484032563903F1BFCCD3756 /* MoyaProvider+Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = A621FA60DF20FE1423923BA34B6029F1 /* MoyaProvider+Defaults.swift */; };
+ E15EA05765812FBDA4F4428F7B6BBF6D /* Pods-Santander-TestUITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CD5133133E24C110EF3769A9D93DE159 /* Pods-Santander-TestUITests-dummy.m */; };
+ E3334CC660C4BD5E41C1061B9DC56FF6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EFB6498CD7E9F2FB9A16399EB90D28B7 /* UIKit.framework */; };
+ E7E895502A83EDA1534DC002A0267D8D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */; };
+ EB0DD8CEA1A69867A30267439C970440 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C43DAE9908ABB7744297D7506D770A /* Result.swift */; };
+ EB65CF8FE56C314DBAF088FE713C9F88 /* MoyaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05C078CAC67FA75DFA89DF555E04156A /* MoyaProvider.swift */; };
+ F0A9F7366B446EDAE4716768BCCADE6C /* IQPreviousNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B079EB42F083C7BEE0CFAE9F9CBBE17 /* IQPreviousNextView.swift */; };
+ F44AA7A6E15EFE1927FC41B447D6EFD1 /* Cancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9BF101351D627A2889DC5AC3F84506 /* Cancellable.swift */; };
+ F852C0100AB6D9D2CE3E28FCA487C67E /* IQUIViewController+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A45FB62426083CE495268BAF39405DFD /* IQUIViewController+Additions.swift */; };
+ FF38A3D897A7C4228CAA5CCA71401376 /* MoyaError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF38D7A18F03C664EC6EE0C9B22A7CE4 /* MoyaError.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 394DD8541DDFF77A28FBB238EEF723A3 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 692F870FA017FAB61B5C3290C3BC5F54;
+ remoteInfo = AMPopTip;
+ };
+ 49600E263670D867E35C1B1E918A2EEF /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EFF87187B46551C36797F2B899C54212;
+ remoteInfo = IQKeyboardManagerSwift;
+ };
+ 6A4EDBBF08D44260DF0148CD85CDDA29 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4B0183450F95394DC0C49E326A20B42D;
+ remoteInfo = Result;
+ };
+ 7D231DD4F66D54D4FD7A2F8FEBEF1FCC /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4B0183450F95394DC0C49E326A20B42D;
+ remoteInfo = Result;
+ };
+ 89B7C1F59BE279B9AC2C2AEA832F837B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 3383968E74B5371B20BB519B170DC7FD;
+ remoteInfo = Alamofire;
+ };
+ 969DCCA076A9B9D70065EA7CB5DB6A86 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F6743F51E8DAAB9AB7DB29A84A37F017;
+ remoteInfo = "Pods-Santander-Test";
+ };
+ A7BE02881176372328240EA60252BB3A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = BAAB01D1BA82ABAE2B535579B77ED0CB;
+ remoteInfo = Moya;
+ };
+ BE2FE96C842D970D743B817C3C29C800 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F6743F51E8DAAB9AB7DB29A84A37F017;
+ remoteInfo = "Pods-Santander-Test";
+ };
+ C2484FBCD16255B9BC841E5263AE7033 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 3383968E74B5371B20BB519B170DC7FD;
+ remoteInfo = Alamofire;
+ };
+ CB56E2428B8E2A6752A736019B630B48 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F6CF1E66B5C83639563339131FB4A512;
+ remoteInfo = StatusAlert;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 00DACC21DA90E8AA013FAE6339E6E285 /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; };
+ 01B4720D4F3A72FEF3A1525F6D268E7A /* Pods-Santander-Test-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Santander-Test-frameworks.sh"; sourceTree = ""; };
+ 05C078CAC67FA75DFA89DF555E04156A /* MoyaProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MoyaProvider.swift; path = Sources/Moya/MoyaProvider.swift; sourceTree = ""; };
+ 05E349DAE1260294B909EE4EF74E1CEE /* Pods-Santander-TestTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Santander-TestTests-dummy.m"; sourceTree = ""; };
+ 064B8C62456DB7AEFF1AEFF7FC9E39F7 /* Pods-Santander-Test-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Santander-Test-umbrella.h"; sourceTree = ""; };
+ 08A81152EC75BCA30190A6265734A2E9 /* Pods-Santander-Test-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Santander-Test-acknowledgements.markdown"; sourceTree = ""; };
+ 0A64D86776CE0A15D579A12A1E3435FC /* Moya-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Moya-umbrella.h"; sourceTree = ""; };
+ 0A9370C1B5A38F7E656EE5FAB9855D66 /* AMPopTip.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = AMPopTip.xcconfig; sourceTree = ""; };
+ 0ED490BFE696CCBB0DFAA6B89FB2ACBF /* Timeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeline.swift; path = Source/Timeline.swift; sourceTree = ""; };
+ 1101C4E2CAB959A7BFD21FE75E332005 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Alamofire.framework; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1112BA5594638444A8463D9E6BD25F8C /* Pods-Santander-Test.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-Test.debug.xcconfig"; sourceTree = ""; };
+ 11E428322B8F20B4BD04558E00C12301 /* Result-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Result-umbrella.h"; sourceTree = ""; };
+ 1271F76A652701E7081E1256BCEA38D5 /* Task.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Task.swift; path = Sources/Moya/Task.swift; sourceTree = ""; };
+ 1299D2802DF81035888B1EF8BD097426 /* AMPopTip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "AMPopTip-dummy.m"; sourceTree = ""; };
+ 13E4593C0360CBA8031C9DC2E64BEBC1 /* IQUIScrollView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIScrollView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift"; sourceTree = ""; };
+ 1410754A2D8AEF29CBAD3CF4DC4714BB /* Pods-Santander-TestUITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Santander-TestUITests-umbrella.h"; sourceTree = ""; };
+ 145218CC34A5DEC0A2852C9D9724C4EB /* AMPopTip-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AMPopTip-prefix.pch"; sourceTree = ""; };
+ 157AB990513DA582CA4369A962E2F52F /* IQTitleBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTitleBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift; sourceTree = ""; };
+ 15C6D9AAE7AFB1D510907D85B8CAC6B6 /* IQKeyboardManagerSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-umbrella.h"; sourceTree = ""; };
+ 17F4B87CA0F449904B527F31FA799551 /* IQKeyboardManagerSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = IQKeyboardManagerSwift.modulemap; sourceTree = ""; };
+ 1829CB35B6E3E9121C9CF36E8FCDBAE6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
+ 18C43DAE9908ABB7744297D7506D770A /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Source/Result.swift; sourceTree = ""; };
+ 1DD6D83DD5AE4B9C0CA1C80B73978D5F /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; };
+ 1EB06C4313AEB9EB7D11D7BC4AC79893 /* CredentialsPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CredentialsPlugin.swift; path = Sources/Moya/Plugins/CredentialsPlugin.swift; sourceTree = ""; };
+ 1FA9ACAB0572FE18DB0EFC4D0D489C7B /* Pods-Santander-TestTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Santander-TestTests-acknowledgements.markdown"; sourceTree = ""; };
+ 214339B9ACA04BC4CA6C980F9545E964 /* IQToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbar.swift; path = IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift; sourceTree = ""; };
+ 27E2BB89559B46B7D51C7E161F1DE20E /* Pods-Santander-TestUITests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-TestUITests-Info.plist"; sourceTree = ""; };
+ 27F1E014D4F06349619A808BCC3D021A /* IQKeyboardReturnKeyHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardReturnKeyHandler.swift; path = IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift; sourceTree = ""; };
+ 291574678DD74D639BB420782B57ECFC /* MoyaProvider+Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "MoyaProvider+Internal.swift"; path = "Sources/Moya/MoyaProvider+Internal.swift"; sourceTree = ""; };
+ 2C381BBCB0AA8AFC6E94A60990BF256E /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Sources/Moya/MultipartFormData.swift; sourceTree = ""; };
+ 2F309854407F224D9C16B2A9333BDADE /* IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "IQKeyboardManagerSwift-Info.plist"; sourceTree = ""; };
+ 3007389BFB5C400ADA99640D19484908 /* IQKeyboardManagerConstantsInternal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstantsInternal.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift; sourceTree = ""; };
+ 3177B689266F9D9900310F56859F5DB2 /* Pods-Santander-TestTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Santander-TestTests.modulemap"; sourceTree = ""; };
+ 322053D9E9993C774F41A2AA6CB500A7 /* Pods-Santander-Test-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-Test-acknowledgements.plist"; sourceTree = ""; };
+ 34718F3B9548C70AF0984731DDCA7580 /* Pods-Santander-TestUITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Santander-TestUITests-acknowledgements.markdown"; sourceTree = ""; };
+ 364E4A632F5EC247E27102522F340CDD /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; };
+ 3A7155821E550BB48423DD1D5A915B48 /* StatusAlert.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = StatusAlert.xcconfig; sourceTree = ""; };
+ 3CF22CDAC0AC4795D80AD5F6585FDCB2 /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; };
+ 3D55C096C7852AD0FD5900FFDEC056A7 /* Endpoint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Endpoint.swift; path = Sources/Moya/Endpoint.swift; sourceTree = ""; };
+ 40F4581CF8577E41F9E26140B86166D4 /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; };
+ 45C4ABEAFCB4FA284808F5DBE887B20D /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 47CDDA230D44A9D90E4E680D0F704ECA /* AnyEncodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyEncodable.swift; path = Sources/Moya/AnyEncodable.swift; sourceTree = ""; };
+ 4A815150FE659B719E0E5ECD4EC715BA /* Moya.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Moya.xcconfig; sourceTree = ""; };
+ 4E07512BEE542791831615B14890629F /* ResultProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResultProtocol.swift; path = Result/ResultProtocol.swift; sourceTree = ""; };
+ 4E6702644CDF6D2BB61A66FB6113E484 /* IQKeyboardManager.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = IQKeyboardManager.bundle; path = IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle; sourceTree = ""; };
+ 4E8913DBA190C8B315A24290438509E2 /* IQKeyboardManagerSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-prefix.pch"; sourceTree = ""; };
+ 500A039A12C1D4FC4DD1BA43A9523E91 /* Pods-Santander-Test.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-Test.release.xcconfig"; sourceTree = ""; };
+ 52A7962BA43F6C95A0167DE119923864 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; };
+ 54A5B4CE524043844F286D1E6867FD30 /* Moya.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Moya.modulemap; sourceTree = ""; };
+ 555CDDB61EE2030B6AA753AE6C16F884 /* IQKeyboardManagerSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = IQKeyboardManagerSwift.framework; path = IQKeyboardManagerSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5D9FAA9914E2184A41D32A3A311B1860 /* Pods-Santander-Test-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Santander-Test-dummy.m"; sourceTree = ""; };
+ 5E1CF47F8BD0FE48ABCF46917BFDB639 /* Pods-Santander-Test-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-Test-Info.plist"; sourceTree = ""; };
+ 5EDE2F0D0D20F8B9666B15E4E4980ABA /* AMPopTip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "AMPopTip-Info.plist"; sourceTree = ""; };
+ 5F87DA44039A5D2EC5DB495708C0AB39 /* ServerTrustPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustPolicy.swift; path = Source/ServerTrustPolicy.swift; sourceTree = ""; };
+ 6009D670E92930F3D826B7B232BAE2DE /* Pods-Santander-TestTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-TestTests.debug.xcconfig"; sourceTree = ""; };
+ 61C7B2747A259463EF9F583ED0735FFF /* Plugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Plugin.swift; path = Sources/Moya/Plugin.swift; sourceTree = ""; };
+ 62D8E1A78982244825E42655DEF31E2B /* AMPopTip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = AMPopTip.framework; path = AMPopTip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 638AF6E4AD3D6CF6AED6C2F601C4A809 /* Pods-Santander-TestTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Santander-TestTests-umbrella.h"; sourceTree = ""; };
+ 6778F6C5A30EF7507D609F04AA77C837 /* StatusAlert-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "StatusAlert-Info.plist"; sourceTree = ""; };
+ 6896D29C611F9F43AB11277DBED46F8C /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; };
+ 6B0D3C25CAABB853B0E1562B0AB04773 /* Alamofire.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.xcconfig; sourceTree = ""; };
+ 6BBA6A8B1542C5036781E5CB1AD15100 /* NetworkLoggerPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkLoggerPlugin.swift; path = Sources/Moya/Plugins/NetworkLoggerPlugin.swift; sourceTree = ""; };
+ 6BF013BC64BC6FEC0A17E5BB75E959F7 /* URLRequest+Encoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Encoding.swift"; path = "Sources/Moya/URLRequest+Encoding.swift"; sourceTree = ""; };
+ 6DECA3076074BA79EE14747097FA4232 /* IQKeyboardManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManager.swift; path = IQKeyboardManagerSwift/IQKeyboardManager.swift; sourceTree = ""; };
+ 6E6C381B71ED17C8633C06674859A450 /* IQTextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextView.swift; path = IQKeyboardManagerSwift/IQTextView/IQTextView.swift; sourceTree = ""; };
+ 6F7B15147E249F80E5874E77D31A450C /* Moya-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Moya-dummy.m"; sourceTree = ""; };
+ 71C48AA44E7FE6CA667F2F4956309ED0 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; };
+ 72E40C3B6E66E684514A3B0403D07BFE /* Pods-Santander-TestUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-TestUITests.debug.xcconfig"; sourceTree = ""; };
+ 731A83702890AE7019DC4C29DB8E4EC9 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Sources/Moya/Response.swift; sourceTree = ""; };
+ 756857999614F2D10AB3F2D2085DB1A7 /* TaskDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TaskDelegate.swift; path = Source/TaskDelegate.swift; sourceTree = ""; };
+ 7896B8BF68E862E13985590C6A5FA5E3 /* TargetType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TargetType.swift; path = Sources/Moya/TargetType.swift; sourceTree = ""; };
+ 7905351DDA208FF2BCDDDB073F863EA1 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Moya/Image.swift; sourceTree = ""; };
+ 793D9BD7B815AAF1CE1A5BC097261E71 /* StatusAlert.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StatusAlert.swift; path = Sources/StatusAlert/StatusAlert.swift; sourceTree = ""; };
+ 7A8D526CFB9CE5AE19261B6D3A1AA350 /* Pods-Santander-TestUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-TestUITests.release.xcconfig"; sourceTree = ""; };
+ 7B079EB42F083C7BEE0CFAE9F9CBBE17 /* IQPreviousNextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPreviousNextView.swift; path = IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift; sourceTree = ""; };
+ 7BB4646A4AE5EDF356A6C99B24EE2022 /* StatusAlert-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StatusAlert-prefix.pch"; sourceTree = ""; };
+ 82244C246EAA54475DC81632EA200415 /* AccessTokenPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccessTokenPlugin.swift; path = Sources/Moya/Plugins/AccessTokenPlugin.swift; sourceTree = ""; };
+ 82C69D1A74C5F456C4A803DFAC82CE09 /* IQUIView+IQKeyboardToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbar.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift"; sourceTree = ""; };
+ 83455889E13854AD8ABDD99CD2CC39DA /* UIDevice+Platform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDevice+Platform.swift"; path = "Sources/StatusAlert/Extensions/UIDevice+Platform.swift"; sourceTree = ""; };
+ 86F84942F79C4255F7497FC979196A65 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+ 8754AA9A73992CC94C22AC805D068C94 /* IQKeyboardManagerSwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.xcconfig; sourceTree = ""; };
+ 8821CC7B10075A400D45D7905D391703 /* AnyError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyError.swift; path = Result/AnyError.swift; sourceTree = ""; };
+ 8BE8F1E8D7017DC3790579A436C90309 /* Moya-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Moya-Info.plist"; sourceTree = ""; };
+ 8F79064F1A379876B04975C47909474E /* IQBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift; sourceTree = ""; };
+ 9007EDEB45A2B5EBA58AEBA614715C01 /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; };
+ 94EA58095938F9B3C04D77F29F66A5D0 /* Pods_Santander_TestUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Santander_TestUITests.framework; path = "Pods-Santander-TestUITests.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 94FBF4B876049E18090503AA42985DEC /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; };
+ 9505602C5BF594EAAC4A87E55F2C370A /* PopTip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopTip.swift; path = Source/PopTip.swift; sourceTree = ""; };
+ 9549855D3684432FAA2479D3F48F8D39 /* Result.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Result.framework; path = Result.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 955E3FDCA8BA841ACF0A01EFD5D71CE5 /* Result-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Result-Info.plist"; sourceTree = ""; };
+ 95F01307A1F45845DBA269F14D919F08 /* MultiTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultiTarget.swift; path = Sources/Moya/MultiTarget.swift; sourceTree = ""; };
+ 97D88DA44C23CFA4142EBCFF9B27EFF5 /* StatusAlertUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StatusAlertUtils.swift; path = Sources/StatusAlert/StatusAlertUtils.swift; sourceTree = ""; };
+ 98EE8FF0327A2617229C1DCBE5E3BB81 /* Result.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Result.modulemap; sourceTree = ""; };
+ 9BC9DAF4C343EFAC7BEC0603F45F19B3 /* StatusAlert-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StatusAlert-umbrella.h"; sourceTree = ""; };
+ 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
+ 9E3AC696856747E97BB0C7036CC738F0 /* ValidationType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ValidationType.swift; path = Sources/Moya/ValidationType.swift; sourceTree = ""; };
+ A45FB62426083CE495268BAF39405DFD /* IQUIViewController+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIViewController+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift"; sourceTree = ""; };
+ A5271583821AE646F1015B53E4B0D22C /* IQKeyboardManagerSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IQKeyboardManagerSwift-dummy.m"; sourceTree = ""; };
+ A621FA60DF20FE1423923BA34B6029F1 /* MoyaProvider+Defaults.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "MoyaProvider+Defaults.swift"; path = "Sources/Moya/MoyaProvider+Defaults.swift"; sourceTree = ""; };
+ AA2C7453145C44C27B00E2138508290D /* Pods-Santander-Test.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Santander-Test.modulemap"; sourceTree = ""; };
+ B19C5155BECC982BA93863CCE6A88B01 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; };
+ B2D49289BFD83B3A1582148FE3B1FBCD /* Pods-Santander-TestUITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-TestUITests-acknowledgements.plist"; sourceTree = ""; };
+ B59FD9D3900B13A0C0C03E7343CB19EF /* IQUIView+Hierarchy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+Hierarchy.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift"; sourceTree = ""; };
+ B821A0250D510FC0475D60FCF6CA59F8 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; };
+ B9DFC3190B2000CE552C11328102AD09 /* PopTip+Draw.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PopTip+Draw.swift"; path = "Source/PopTip+Draw.swift"; sourceTree = ""; };
+ BF38D7A18F03C664EC6EE0C9B22A7CE4 /* MoyaError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MoyaError.swift; path = Sources/Moya/MoyaError.swift; sourceTree = ""; };
+ BF7E09A17DBD8AB26665BBCDBC2CDFEA /* Moya-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Moya-prefix.pch"; sourceTree = ""; };
+ BFB4BE60C2E697DB2B80B3F13833F5E8 /* IQUITextFieldView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITextFieldView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift"; sourceTree = ""; };
+ C23191AA0D756503E4C42654D277AE58 /* IQInvocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQInvocation.swift; path = IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift; sourceTree = ""; };
+ C283542EF8EEF865485C078FFAAD4FCC /* Result.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Result.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ C4F3617A6AD2DA24CB5D716B779284F8 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; };
+ C7C27ADB3CDDE59F459AB5DF4B23583F /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Result/Result.swift; sourceTree = ""; };
+ CD5133133E24C110EF3769A9D93DE159 /* Pods-Santander-TestUITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Santander-TestUITests-dummy.m"; sourceTree = ""; };
+ CD7B595FE6596FB636EB30207B2F428A /* Pods-Santander-TestUITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Santander-TestUITests.modulemap"; sourceTree = ""; };
+ D02D3D21156144D3F4B936265D29A56A /* Pods-Santander-TestTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-TestTests-acknowledgements.plist"; sourceTree = ""; };
+ D05EA68EF87A95B537922D70C6DC0427 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; };
+ D1CB1588C635AF0E142CA79C1D791345 /* Result.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Result.xcconfig; sourceTree = ""; };
+ D26A8905411437A4096352B51EC87710 /* NetworkActivityPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkActivityPlugin.swift; path = Sources/Moya/Plugins/NetworkActivityPlugin.swift; sourceTree = ""; };
+ D90FE54F5D11CC69794D8BED8AA7D675 /* Pods-Santander-TestTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Santander-TestTests-Info.plist"; sourceTree = ""; };
+ DA5BE578C477043FD77994721DF2CF79 /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; };
+ DC70403EFC8F9FE430904EE770C96364 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+ DF6CAF521EED88DF2040CD240D5F4C3A /* SessionManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionManager.swift; path = Source/SessionManager.swift; sourceTree = ""; };
+ E088536B128E3AB516E66A17708F6322 /* StatusAlert.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = StatusAlert.modulemap; sourceTree = ""; };
+ E1C2681F4C36A1893AAE9A6548862463 /* Pods_Santander_Test.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Santander_Test.framework; path = "Pods-Santander-Test.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E58D219C426FD2752002E027A43233F2 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; };
+ E819577D2B1029AE4C9270C33FFFE71E /* Result-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Result-prefix.pch"; sourceTree = ""; };
+ E91E237C060ECC2B4366CA83D0CC2C5E /* Pods_Santander_TestTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Santander_TestTests.framework; path = "Pods-Santander-TestTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E98DD21778D48883FC8AFC80B446C777 /* AMPopTip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = AMPopTip.modulemap; sourceTree = ""; };
+ ED4C8B5361C64793391D06271956C190 /* PopTip+Transitions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PopTip+Transitions.swift"; path = "Source/PopTip+Transitions.swift"; sourceTree = ""; };
+ EE397110EB17007AD8326CD6E6A3C67E /* UIDevice+Blur.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDevice+Blur.swift"; path = "Sources/StatusAlert/Extensions/UIDevice+Blur.swift"; sourceTree = ""; };
+ EFB6498CD7E9F2FB9A16399EB90D28B7 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ F001F52BA7BA1ED9D50942621A44C511 /* StatusAlert.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = StatusAlert.framework; path = StatusAlert.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F3708A4B829835EBC49B784D84968130 /* Pods-Santander-TestTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Santander-TestTests.release.xcconfig"; sourceTree = ""; };
+ F52E478305B403B1169C3B03E7EBC07F /* StatusAlert-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "StatusAlert-dummy.m"; sourceTree = ""; };
+ F7EF57EFB1DD70A9C3098E6C3F95C151 /* Moya.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Moya.framework; path = Moya.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F8C902A8CC69883010175615A839CBCD /* URL+Moya.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URL+Moya.swift"; path = "Sources/Moya/URL+Moya.swift"; sourceTree = ""; };
+ F8CA6ADC7C7F6B367BAD8CBEBF1343A6 /* IQNSArray+Sort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQNSArray+Sort.swift"; path = "IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift"; sourceTree = ""; };
+ FA4B95F0E633A9A9A8873BF0C4903533 /* Moya+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Moya+Alamofire.swift"; path = "Sources/Moya/Moya+Alamofire.swift"; sourceTree = ""; };
+ FA89BCF8A139DFA2E60DDAB8DC3BDFE1 /* Result-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Result-dummy.m"; sourceTree = ""; };
+ FA9B159763A6EABA1D15D3D6E8BB8EE3 /* AMPopTip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AMPopTip-umbrella.h"; sourceTree = ""; };
+ FAC703355C70EAC3B48FF2F65BEF1DAB /* NoError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NoError.swift; path = Result/NoError.swift; sourceTree = "