diff --git a/.gitignore b/.gitignore index a0d4524..1278906 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .DS_Store -*.xcuserstate \ No newline at end of file +*.xcuserstate diff --git a/Bunjang.xcodeproj/project.pbxproj b/Bunjang.xcodeproj/project.pbxproj deleted file mode 100644 index b3f577a..0000000 --- a/Bunjang.xcodeproj/project.pbxproj +++ /dev/null @@ -1,525 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 55; - objects = { - -/* Begin PBXBuildFile section */ - 38D8301551DA56E55E012A2F /* Pods_Bunjang.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B062CB3D3363D57E3E774095 /* Pods_Bunjang.framework */; }; - D463D46C2A419E4B00E37898 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46B2A419E4B00E37898 /* AppDelegate.swift */; }; - D463D46E2A419E4B00E37898 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46D2A419E4B00E37898 /* SceneDelegate.swift */; }; - D463D4702A419E4B00E37898 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46F2A419E4B00E37898 /* ViewController.swift */; }; - D463D4752A419E4C00E37898 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D463D4742A419E4C00E37898 /* Assets.xcassets */; }; - D463D4782A419E4C00E37898 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 2478FB750B117ADCE77B7F61 /* Pods-Bunjang.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bunjang.debug.xcconfig"; path = "Target Support Files/Pods-Bunjang/Pods-Bunjang.debug.xcconfig"; sourceTree = ""; }; - B062CB3D3363D57E3E774095 /* Pods_Bunjang.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Bunjang.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D463D4682A419E4B00E37898 /* Bunjang.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Bunjang.app; sourceTree = BUILT_PRODUCTS_DIR; }; - D463D46B2A419E4B00E37898 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - D463D46D2A419E4B00E37898 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - D463D46F2A419E4B00E37898 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - D463D4742A419E4C00E37898 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - D463D4772A419E4C00E37898 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - D463D4792A419E4C00E37898 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - EBEE1FCA5068951E473C2627 /* Pods-Bunjang.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bunjang.release.xcconfig"; path = "Target Support Files/Pods-Bunjang/Pods-Bunjang.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D463D4652A419E4B00E37898 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 38D8301551DA56E55E012A2F /* Pods_Bunjang.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 8A6A71B79F4EC25E9C547810 /* Frameworks */ = { - isa = PBXGroup; - children = ( - B062CB3D3363D57E3E774095 /* Pods_Bunjang.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 944B0BEDCF8FDE9E511A0618 /* Pods */ = { - isa = PBXGroup; - children = ( - 2478FB750B117ADCE77B7F61 /* Pods-Bunjang.debug.xcconfig */, - EBEE1FCA5068951E473C2627 /* Pods-Bunjang.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - D404F5FB2A429BAD0065E095 /* ViewModels */ = { - isa = PBXGroup; - children = ( - ); - path = ViewModels; - sourceTree = ""; - }; - D404F5FC2A429BB30065E095 /* Data */ = { - isa = PBXGroup; - children = ( - D404F5FD2A429BBF0065E095 /* Repositories */, - ); - path = Data; - sourceTree = ""; - }; - D404F5FD2A429BBF0065E095 /* Repositories */ = { - isa = PBXGroup; - children = ( - ); - path = Repositories; - sourceTree = ""; - }; - D404F5FE2A429BC80065E095 /* Infrastructure */ = { - isa = PBXGroup; - children = ( - D404F5FF2A429BCD0065E095 /* Networks */, - ); - path = Infrastructure; - sourceTree = ""; - }; - D404F5FF2A429BCD0065E095 /* Networks */ = { - isa = PBXGroup; - children = ( - ); - path = Networks; - sourceTree = ""; - }; - D463D45F2A419E4B00E37898 = { - isa = PBXGroup; - children = ( - D463D46A2A419E4B00E37898 /* Bunjang */, - D463D4692A419E4B00E37898 /* Products */, - 944B0BEDCF8FDE9E511A0618 /* Pods */, - 8A6A71B79F4EC25E9C547810 /* Frameworks */, - ); - sourceTree = ""; - }; - D463D4692A419E4B00E37898 /* Products */ = { - isa = PBXGroup; - children = ( - D463D4682A419E4B00E37898 /* Bunjang.app */, - ); - name = Products; - sourceTree = ""; - }; - D463D46A2A419E4B00E37898 /* Bunjang */ = { - isa = PBXGroup; - children = ( - D463D47F2A41A29F00E37898 /* Application */, - D463D4802A41A91F00E37898 /* Presentation */, - D463D49B2A4296A700E37898 /* Domain */, - D404F5FC2A429BB30065E095 /* Data */, - D404F5FE2A429BC80065E095 /* Infrastructure */, - D463D4742A419E4C00E37898 /* Assets.xcassets */, - D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */, - D463D4792A419E4C00E37898 /* Info.plist */, - ); - path = Bunjang; - sourceTree = ""; - }; - D463D47F2A41A29F00E37898 /* Application */ = { - isa = PBXGroup; - children = ( - D463D46B2A419E4B00E37898 /* AppDelegate.swift */, - D463D46D2A419E4B00E37898 /* SceneDelegate.swift */, - ); - path = Application; - sourceTree = ""; - }; - D463D4802A41A91F00E37898 /* Presentation */ = { - isa = PBXGroup; - children = ( - D404F5FB2A429BAD0065E095 /* ViewModels */, - D463D48C2A41B7B500E37898 /* Protocols */, - D463D4842A41A95D00E37898 /* Views */, - ); - path = Presentation; - sourceTree = ""; - }; - D463D4842A41A95D00E37898 /* Views */ = { - isa = PBXGroup; - children = ( - D463D46F2A419E4B00E37898 /* ViewController.swift */, - ); - path = Views; - sourceTree = ""; - }; - D463D48C2A41B7B500E37898 /* Protocols */ = { - isa = PBXGroup; - children = ( - ); - path = Protocols; - sourceTree = ""; - }; - D463D49B2A4296A700E37898 /* Domain */ = { - isa = PBXGroup; - children = ( - D463D49C2A4296AB00E37898 /* Repositories */, - D463D49D2A4296B500E37898 /* Usecases */, - D463D49E2A4296BA00E37898 /* Entities */, - ); - path = Domain; - sourceTree = ""; - }; - D463D49C2A4296AB00E37898 /* Repositories */ = { - isa = PBXGroup; - children = ( - ); - path = Repositories; - sourceTree = ""; - }; - D463D49D2A4296B500E37898 /* Usecases */ = { - isa = PBXGroup; - children = ( - ); - path = Usecases; - sourceTree = ""; - }; - D463D49E2A4296BA00E37898 /* Entities */ = { - isa = PBXGroup; - children = ( - ); - path = Entities; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - D463D4672A419E4B00E37898 /* Bunjang */ = { - isa = PBXNativeTarget; - buildConfigurationList = D463D47C2A419E4C00E37898 /* Build configuration list for PBXNativeTarget "Bunjang" */; - buildPhases = ( - 84D919033D6CE62475CF011E /* [CP] Check Pods Manifest.lock */, - D463D4642A419E4B00E37898 /* Sources */, - D463D4652A419E4B00E37898 /* Frameworks */, - D463D4662A419E4B00E37898 /* Resources */, - 4F7637DC6C551E8E7AD1EAF1 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Bunjang; - productName = Bunjang; - productReference = D463D4682A419E4B00E37898 /* Bunjang.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - D463D4602A419E4B00E37898 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1430; - TargetAttributes = { - D463D4672A419E4B00E37898 = { - CreatedOnToolsVersion = 14.3; - }; - }; - }; - buildConfigurationList = D463D4632A419E4B00E37898 /* Build configuration list for PBXProject "Bunjang" */; - compatibilityVersion = "Xcode 13.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = D463D45F2A419E4B00E37898; - productRefGroup = D463D4692A419E4B00E37898 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D463D4672A419E4B00E37898 /* Bunjang */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - D463D4662A419E4B00E37898 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D463D4782A419E4C00E37898 /* LaunchScreen.storyboard in Resources */, - D463D4752A419E4C00E37898 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 4F7637DC6C551E8E7AD1EAF1 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 84D919033D6CE62475CF011E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Bunjang-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - D463D4642A419E4B00E37898 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D463D4702A419E4B00E37898 /* ViewController.swift in Sources */, - D463D46C2A419E4B00E37898 /* AppDelegate.swift in Sources */, - D463D46E2A419E4B00E37898 /* SceneDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - D463D4772A419E4C00E37898 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - D463D47A2A419E4C00E37898 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.4; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - D463D47B2A419E4C00E37898 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.4; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - D463D47D2A419E4C00E37898 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2478FB750B117ADCE77B7F61 /* Pods-Bunjang.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4MNTP64Q22; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = Bunjang/Info.plist; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ronick.Bunjang; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - D463D47E2A419E4C00E37898 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = EBEE1FCA5068951E473C2627 /* Pods-Bunjang.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4MNTP64Q22; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = Bunjang/Info.plist; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ronick.Bunjang; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - D463D4632A419E4B00E37898 /* Build configuration list for PBXProject "Bunjang" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D463D47A2A419E4C00E37898 /* Debug */, - D463D47B2A419E4C00E37898 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D463D47C2A419E4C00E37898 /* Build configuration list for PBXNativeTarget "Bunjang" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D463D47D2A419E4C00E37898 /* Debug */, - D463D47E2A419E4C00E37898 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = D463D4602A419E4B00E37898 /* Project object */; -} diff --git a/Bunjang/Application/SceneDelegate.swift b/Bunjang/Application/SceneDelegate.swift deleted file mode 100644 index 27a99db..0000000 --- a/Bunjang/Application/SceneDelegate.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// SceneDelegate.swift -// Bunjang -// -// Created by Ronick on 6/20/23. -// - -import UIKit - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - - var window: UIWindow? - - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - guard let windowScene = (scene as? UIWindowScene) else { return } - window = UIWindow(windowScene: windowScene) - - let mainViewController = ViewController() - - let nav = UINavigationController(rootViewController: mainViewController) - nav.navigationBar.backgroundColor = .clear - - window?.rootViewController = nav - window?.backgroundColor = .systemBackground - - window?.makeKeyAndVisible() - - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - -} - diff --git a/Bunjang/Presentation/Views/ViewController.swift b/Bunjang/Presentation/Views/ViewController.swift deleted file mode 100644 index 0a17ae5..0000000 --- a/Bunjang/Presentation/Views/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// Bunjang -// -// Created by Ronick on 6/20/23. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/GenderList.xcodeproj/project.pbxproj b/GenderList.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d6839e4 --- /dev/null +++ b/GenderList.xcodeproj/project.pbxproj @@ -0,0 +1,789 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + A0EF7FDC7088D090209205AE /* Pods_GenderList.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D32AC6CA104B652FD3E72A9A /* Pods_GenderList.framework */; }; + D404F6012A429CA40065E095 /* TabCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6002A429CA40065E095 /* TabCollectionView.swift */; }; + D404F6032A429D5B0065E095 /* TabCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6022A429D5B0065E095 /* TabCollectionViewCell.swift */; }; + D404F6082A42F65C0065E095 /* TabPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6072A42F65C0065E095 /* TabPageView.swift */; }; + D404F60A2A42FAF70065E095 /* PageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6092A42FAF70065E095 /* PageCollectionView.swift */; }; + D404F6122A4302CC0065E095 /* PageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6112A4302CC0065E095 /* PageCollectionViewCell.swift */; }; + D404F6152A432C130065E095 /* ListCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6142A432C130065E095 /* ListCollectionView.swift */; }; + D404F6172A432C1D0065E095 /* ListCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D404F6162A432C1D0065E095 /* ListCollectionViewCell.swift */; }; + D41D7C0E2A5D573E00F46AAC /* AppFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41D7C0D2A5D573E00F46AAC /* AppFlowCoordinator.swift */; }; + D41D7C112A5D5A9300F46AAC /* AppDIContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41D7C102A5D5A9300F46AAC /* AppDIContainer.swift */; }; + D41D7C132A5D5C6C00F46AAC /* GenderListSceneDIContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41D7C122A5D5C6C00F46AAC /* GenderListSceneDIContainer.swift */; }; + D41D7C162A5D5F7500F46AAC /* GenderListFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41D7C152A5D5F7500F46AAC /* GenderListFlowCoordinator.swift */; }; + D463D46C2A419E4B00E37898 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46B2A419E4B00E37898 /* AppDelegate.swift */; }; + D463D46E2A419E4B00E37898 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46D2A419E4B00E37898 /* SceneDelegate.swift */; }; + D463D4702A419E4B00E37898 /* GenderListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D463D46F2A419E4B00E37898 /* GenderListViewController.swift */; }; + D463D4752A419E4C00E37898 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D463D4742A419E4C00E37898 /* Assets.xcassets */; }; + D463D4782A419E4C00E37898 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */; }; + D480D3E92A5D02DE00AD0C26 /* GenderProfileItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D480D3E82A5D02DE00AD0C26 /* GenderProfileItemViewModel.swift */; }; + D485DC222A57ECE400243487 /* ListViewOutputHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D485DC212A57ECE400243487 /* ListViewOutputHelper.swift */; }; + D485DC252A57ED9A00243487 /* ListViewOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = D485DC242A57ED9A00243487 /* ListViewOutput.swift */; }; + D49B50E82A53F8C70081FF9D /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49B50E72A53F8C70081FF9D /* UIView+Extension.swift */; }; + D4B062D62A5A97A700E6B374 /* GenderProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B062D52A5A97A700E6B374 /* GenderProfile.swift */; }; + D4DEA80D2A448396006FB3DF /* Bindable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA80C2A448396006FB3DF /* Bindable.swift */; }; + D4DEA80F2A4483AC006FB3DF /* ViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA80E2A4483AC006FB3DF /* ViewModelType.swift */; }; + D4DEA8122A4485D1006FB3DF /* UICollectionView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8112A4485D1006FB3DF /* UICollectionView+Extension.swift */; }; + D4DEA8142A44933D006FB3DF /* ListPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8132A44933D006FB3DF /* ListPageViewModel.swift */; }; + D4DEA8162A456E08006FB3DF /* TabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8152A456E08006FB3DF /* TabViewModel.swift */; }; + D4DEA8182A45AFD2006FB3DF /* TabListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8172A45AFD2006FB3DF /* TabListViewModel.swift */; }; + D4DEA81A2A45FB10006FB3DF /* ListPageView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8192A45FB10006FB3DF /* ListPageView+Rx.swift */; }; + D4DEA81C2A46802E006FB3DF /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA81B2A46802E006FB3DF /* DetailViewController.swift */; }; + D4DEA81E2A46BD37006FB3DF /* ColumnStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA81D2A46BD37006FB3DF /* ColumnStyle.swift */; }; + D4DEA8202A46C182006FB3DF /* ListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA81F2A46C182006FB3DF /* ListViewModel.swift */; }; + D4DEA8222A46C330006FB3DF /* GenderListResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8212A46C330006FB3DF /* GenderListResponseDTO+Mapping.swift */; }; + D4DEA8242A46C5A6006FB3DF /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8232A46C5A6006FB3DF /* NetworkService.swift */; }; + D4DEA82A2A46C9BA006FB3DF /* GenderListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8292A46C9BA006FB3DF /* GenderListRepository.swift */; }; + D4DEA82D2A46CB8A006FB3DF /* GenderListQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA82C2A46CB8A006FB3DF /* GenderListQuery.swift */; }; + D4DEA82F2A46CBDD006FB3DF /* DefaultGenderListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA82E2A46CBDD006FB3DF /* DefaultGenderListRepository.swift */; }; + D4DEA8312A46F34F006FB3DF /* GenderListUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8302A46F34F006FB3DF /* GenderListUsecase.swift */; }; + D4DEA8362A4725AD006FB3DF /* DetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8352A4725AD006FB3DF /* DetailView.swift */; }; + D4DEA8382A482FBB006FB3DF /* PagenationGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8372A482FBB006FB3DF /* PagenationGenerator.swift */; }; + D4DEA83A2A483120006FB3DF /* DefaultPagenationGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8392A483120006FB3DF /* DefaultPagenationGenerator.swift */; }; + D4DEA83D2A484397006FB3DF /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA83C2A484397006FB3DF /* UICollectionView+Rx.swift */; }; + D4DEA83F2A48D413006FB3DF /* FetchStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA83E2A48D413006FB3DF /* FetchStatus.swift */; }; + D4DEA8412A48D5F4006FB3DF /* GenderListFetchHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8402A48D5F4006FB3DF /* GenderListFetchHelper.swift */; }; + D4DEA8432A48F046006FB3DF /* TabView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DEA8422A48F046006FB3DF /* TabView+Rx.swift */; }; + D4E244A92A5FEF9B004E0167 /* GenderListDetailDIContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4E244A82A5FEF9B004E0167 /* GenderListDetailDIContainer.swift */; }; + D4E244AB2A5FF01F004E0167 /* GenderListDetailFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4E244AA2A5FF01F004E0167 /* GenderListDetailFlowCoordinator.swift */; }; + D4FCE4792A55229100D60C20 /* InitialViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4FCE4782A55229100D60C20 /* InitialViewModel.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 452EB8A8D971E7BD7183B125 /* Pods-GenderList.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GenderList.debug.xcconfig"; path = "Target Support Files/Pods-GenderList/Pods-GenderList.debug.xcconfig"; sourceTree = ""; }; + CF03917F3E07BA67B3825C05 /* Pods-GenderList.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GenderList.release.xcconfig"; path = "Target Support Files/Pods-GenderList/Pods-GenderList.release.xcconfig"; sourceTree = ""; }; + D32AC6CA104B652FD3E72A9A /* Pods_GenderList.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GenderList.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D404F6002A429CA40065E095 /* TabCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabCollectionView.swift; sourceTree = ""; }; + D404F6022A429D5B0065E095 /* TabCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabCollectionViewCell.swift; sourceTree = ""; }; + D404F6072A42F65C0065E095 /* TabPageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabPageView.swift; sourceTree = ""; }; + D404F6092A42FAF70065E095 /* PageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageCollectionView.swift; sourceTree = ""; }; + D404F6112A4302CC0065E095 /* PageCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageCollectionViewCell.swift; sourceTree = ""; }; + D404F6142A432C130065E095 /* ListCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCollectionView.swift; sourceTree = ""; }; + D404F6162A432C1D0065E095 /* ListCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCollectionViewCell.swift; sourceTree = ""; }; + D41D7C0D2A5D573E00F46AAC /* AppFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppFlowCoordinator.swift; sourceTree = ""; }; + D41D7C102A5D5A9300F46AAC /* AppDIContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDIContainer.swift; sourceTree = ""; }; + D41D7C122A5D5C6C00F46AAC /* GenderListSceneDIContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListSceneDIContainer.swift; sourceTree = ""; }; + D41D7C152A5D5F7500F46AAC /* GenderListFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListFlowCoordinator.swift; sourceTree = ""; }; + D463D4682A419E4B00E37898 /* GenderList.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenderList.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D463D46B2A419E4B00E37898 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + D463D46D2A419E4B00E37898 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + D463D46F2A419E4B00E37898 /* GenderListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListViewController.swift; sourceTree = ""; }; + D463D4742A419E4C00E37898 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + D463D4772A419E4C00E37898 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + D463D4792A419E4C00E37898 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D480D3E82A5D02DE00AD0C26 /* GenderProfileItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderProfileItemViewModel.swift; sourceTree = ""; }; + D485DC212A57ECE400243487 /* ListViewOutputHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewOutputHelper.swift; sourceTree = ""; }; + D485DC242A57ED9A00243487 /* ListViewOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewOutput.swift; sourceTree = ""; }; + D49B50E72A53F8C70081FF9D /* UIView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; }; + D4B062D52A5A97A700E6B374 /* GenderProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderProfile.swift; sourceTree = ""; }; + D4DEA80C2A448396006FB3DF /* Bindable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bindable.swift; sourceTree = ""; }; + D4DEA80E2A4483AC006FB3DF /* ViewModelType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModelType.swift; sourceTree = ""; }; + D4DEA8112A4485D1006FB3DF /* UICollectionView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Extension.swift"; sourceTree = ""; }; + D4DEA8132A44933D006FB3DF /* ListPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListPageViewModel.swift; sourceTree = ""; }; + D4DEA8152A456E08006FB3DF /* TabViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewModel.swift; sourceTree = ""; }; + D4DEA8172A45AFD2006FB3DF /* TabListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabListViewModel.swift; sourceTree = ""; }; + D4DEA8192A45FB10006FB3DF /* ListPageView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ListPageView+Rx.swift"; sourceTree = ""; }; + D4DEA81B2A46802E006FB3DF /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; + D4DEA81D2A46BD37006FB3DF /* ColumnStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColumnStyle.swift; sourceTree = ""; }; + D4DEA81F2A46C182006FB3DF /* ListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewModel.swift; sourceTree = ""; }; + D4DEA8212A46C330006FB3DF /* GenderListResponseDTO+Mapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GenderListResponseDTO+Mapping.swift"; sourceTree = ""; }; + D4DEA8232A46C5A6006FB3DF /* NetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = ""; }; + D4DEA8292A46C9BA006FB3DF /* GenderListRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListRepository.swift; sourceTree = ""; }; + D4DEA82C2A46CB8A006FB3DF /* GenderListQuery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListQuery.swift; sourceTree = ""; }; + D4DEA82E2A46CBDD006FB3DF /* DefaultGenderListRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultGenderListRepository.swift; sourceTree = ""; }; + D4DEA8302A46F34F006FB3DF /* GenderListUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListUsecase.swift; sourceTree = ""; }; + D4DEA8352A4725AD006FB3DF /* DetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = ""; }; + D4DEA8372A482FBB006FB3DF /* PagenationGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagenationGenerator.swift; sourceTree = ""; }; + D4DEA8392A483120006FB3DF /* DefaultPagenationGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultPagenationGenerator.swift; sourceTree = ""; }; + D4DEA83C2A484397006FB3DF /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Rx.swift"; sourceTree = ""; }; + D4DEA83E2A48D413006FB3DF /* FetchStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchStatus.swift; sourceTree = ""; }; + D4DEA8402A48D5F4006FB3DF /* GenderListFetchHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListFetchHelper.swift; sourceTree = ""; }; + D4DEA8422A48F046006FB3DF /* TabView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TabView+Rx.swift"; sourceTree = ""; }; + D4E244A82A5FEF9B004E0167 /* GenderListDetailDIContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListDetailDIContainer.swift; sourceTree = ""; }; + D4E244AA2A5FF01F004E0167 /* GenderListDetailFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderListDetailFlowCoordinator.swift; sourceTree = ""; }; + D4FCE4782A55229100D60C20 /* InitialViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialViewModel.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D463D4652A419E4B00E37898 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A0EF7FDC7088D090209205AE /* Pods_GenderList.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8A6A71B79F4EC25E9C547810 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D32AC6CA104B652FD3E72A9A /* Pods_GenderList.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 944B0BEDCF8FDE9E511A0618 /* Pods */ = { + isa = PBXGroup; + children = ( + 452EB8A8D971E7BD7183B125 /* Pods-GenderList.debug.xcconfig */, + CF03917F3E07BA67B3825C05 /* Pods-GenderList.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + D404F5FB2A429BAD0065E095 /* ViewModels */ = { + isa = PBXGroup; + children = ( + D485DC202A57ECBF00243487 /* OutputHelpers */, + D4FCE4782A55229100D60C20 /* InitialViewModel.swift */, + D4DEA8172A45AFD2006FB3DF /* TabListViewModel.swift */, + D4DEA8132A44933D006FB3DF /* ListPageViewModel.swift */, + D4DEA8152A456E08006FB3DF /* TabViewModel.swift */, + D4DEA81F2A46C182006FB3DF /* ListViewModel.swift */, + D480D3E82A5D02DE00AD0C26 /* GenderProfileItemViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + D404F5FC2A429BB30065E095 /* Data */ = { + isa = PBXGroup; + children = ( + D4B062D42A5A93C500E6B374 /* Network */, + D404F5FD2A429BBF0065E095 /* Repositories */, + ); + path = Data; + sourceTree = ""; + }; + D404F5FD2A429BBF0065E095 /* Repositories */ = { + isa = PBXGroup; + children = ( + D4DEA82E2A46CBDD006FB3DF /* DefaultGenderListRepository.swift */, + ); + path = Repositories; + sourceTree = ""; + }; + D404F5FE2A429BC80065E095 /* Infrastructure */ = { + isa = PBXGroup; + children = ( + D404F5FF2A429BCD0065E095 /* Network */, + ); + path = Infrastructure; + sourceTree = ""; + }; + D404F5FF2A429BCD0065E095 /* Network */ = { + isa = PBXGroup; + children = ( + D4DEA8232A46C5A6006FB3DF /* NetworkService.swift */, + ); + path = Network; + sourceTree = ""; + }; + D404F6042A42F63B0065E095 /* Tab */ = { + isa = PBXGroup; + children = ( + D404F6002A429CA40065E095 /* TabCollectionView.swift */, + D404F6022A429D5B0065E095 /* TabCollectionViewCell.swift */, + ); + path = Tab; + sourceTree = ""; + }; + D404F6052A42F6480065E095 /* List */ = { + isa = PBXGroup; + children = ( + D404F6072A42F65C0065E095 /* TabPageView.swift */, + D404F6092A42FAF70065E095 /* PageCollectionView.swift */, + D404F6112A4302CC0065E095 /* PageCollectionViewCell.swift */, + D404F6142A432C130065E095 /* ListCollectionView.swift */, + D404F6162A432C1D0065E095 /* ListCollectionViewCell.swift */, + ); + path = List; + sourceTree = ""; + }; + D404F60C2A4301440065E095 /* ListScene */ = { + isa = PBXGroup; + children = ( + D41D7C142A5D5F6100F46AAC /* Flow */, + D404F5FB2A429BAD0065E095 /* ViewModels */, + D463D4842A41A95D00E37898 /* Views */, + ); + path = ListScene; + sourceTree = ""; + }; + D404F60D2A43015F0065E095 /* Utils */ = { + isa = PBXGroup; + children = ( + D4DEA8102A4485AC006FB3DF /* Extensions */, + D4DEA81D2A46BD37006FB3DF /* ColumnStyle.swift */, + D4DEA83E2A48D413006FB3DF /* FetchStatus.swift */, + D4DEA8392A483120006FB3DF /* DefaultPagenationGenerator.swift */, + D4DEA8402A48D5F4006FB3DF /* GenderListFetchHelper.swift */, + ); + path = Utils; + sourceTree = ""; + }; + D41D7C0F2A5D5A7B00F46AAC /* DIContainer */ = { + isa = PBXGroup; + children = ( + D41D7C102A5D5A9300F46AAC /* AppDIContainer.swift */, + D41D7C122A5D5C6C00F46AAC /* GenderListSceneDIContainer.swift */, + D4E244A82A5FEF9B004E0167 /* GenderListDetailDIContainer.swift */, + ); + path = DIContainer; + sourceTree = ""; + }; + D41D7C142A5D5F6100F46AAC /* Flow */ = { + isa = PBXGroup; + children = ( + D41D7C152A5D5F7500F46AAC /* GenderListFlowCoordinator.swift */, + D4E244AA2A5FF01F004E0167 /* GenderListDetailFlowCoordinator.swift */, + ); + path = Flow; + sourceTree = ""; + }; + D463D45F2A419E4B00E37898 = { + isa = PBXGroup; + children = ( + D463D46A2A419E4B00E37898 /* GenderList */, + D463D4692A419E4B00E37898 /* Products */, + 944B0BEDCF8FDE9E511A0618 /* Pods */, + 8A6A71B79F4EC25E9C547810 /* Frameworks */, + ); + sourceTree = ""; + }; + D463D4692A419E4B00E37898 /* Products */ = { + isa = PBXGroup; + children = ( + D463D4682A419E4B00E37898 /* GenderList.app */, + ); + name = Products; + sourceTree = ""; + }; + D463D46A2A419E4B00E37898 /* GenderList */ = { + isa = PBXGroup; + children = ( + D463D47F2A41A29F00E37898 /* Application */, + D463D4802A41A91F00E37898 /* Presentation */, + D463D49B2A4296A700E37898 /* Domain */, + D404F5FC2A429BB30065E095 /* Data */, + D404F5FE2A429BC80065E095 /* Infrastructure */, + D463D4742A419E4C00E37898 /* Assets.xcassets */, + D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */, + D463D4792A419E4C00E37898 /* Info.plist */, + ); + path = GenderList; + sourceTree = ""; + }; + D463D47F2A41A29F00E37898 /* Application */ = { + isa = PBXGroup; + children = ( + D463D46B2A419E4B00E37898 /* AppDelegate.swift */, + D463D46D2A419E4B00E37898 /* SceneDelegate.swift */, + D41D7C0D2A5D573E00F46AAC /* AppFlowCoordinator.swift */, + D41D7C0F2A5D5A7B00F46AAC /* DIContainer */, + ); + path = Application; + sourceTree = ""; + }; + D463D4802A41A91F00E37898 /* Presentation */ = { + isa = PBXGroup; + children = ( + D463D48C2A41B7B500E37898 /* Protocols */, + D404F60C2A4301440065E095 /* ListScene */, + D404F60D2A43015F0065E095 /* Utils */, + ); + path = Presentation; + sourceTree = ""; + }; + D463D4842A41A95D00E37898 /* Views */ = { + isa = PBXGroup; + children = ( + D404F6052A42F6480065E095 /* List */, + D404F6042A42F63B0065E095 /* Tab */, + D4DEA8442A48F9D9006FB3DF /* Detail */, + D463D46F2A419E4B00E37898 /* GenderListViewController.swift */, + ); + path = Views; + sourceTree = ""; + }; + D463D48C2A41B7B500E37898 /* Protocols */ = { + isa = PBXGroup; + children = ( + D485DC232A57ED2A00243487 /* OutputProtocols */, + D4DEA80C2A448396006FB3DF /* Bindable.swift */, + D4DEA80E2A4483AC006FB3DF /* ViewModelType.swift */, + D4DEA8372A482FBB006FB3DF /* PagenationGenerator.swift */, + ); + path = Protocols; + sourceTree = ""; + }; + D463D49B2A4296A700E37898 /* Domain */ = { + isa = PBXGroup; + children = ( + D463D49E2A4296BA00E37898 /* Entities */, + D463D49D2A4296B500E37898 /* Usecases */, + D4DEA8282A46C954006FB3DF /* Interfaces */, + ); + path = Domain; + sourceTree = ""; + }; + D463D49C2A4296AB00E37898 /* Repositories */ = { + isa = PBXGroup; + children = ( + D4DEA8292A46C9BA006FB3DF /* GenderListRepository.swift */, + ); + path = Repositories; + sourceTree = ""; + }; + D463D49D2A4296B500E37898 /* Usecases */ = { + isa = PBXGroup; + children = ( + D4DEA8302A46F34F006FB3DF /* GenderListUsecase.swift */, + ); + path = Usecases; + sourceTree = ""; + }; + D463D49E2A4296BA00E37898 /* Entities */ = { + isa = PBXGroup; + children = ( + D4B062D52A5A97A700E6B374 /* GenderProfile.swift */, + ); + path = Entities; + sourceTree = ""; + }; + D485DC202A57ECBF00243487 /* OutputHelpers */ = { + isa = PBXGroup; + children = ( + D485DC212A57ECE400243487 /* ListViewOutputHelper.swift */, + ); + path = OutputHelpers; + sourceTree = ""; + }; + D485DC232A57ED2A00243487 /* OutputProtocols */ = { + isa = PBXGroup; + children = ( + D485DC242A57ED9A00243487 /* ListViewOutput.swift */, + ); + path = OutputProtocols; + sourceTree = ""; + }; + D4B062D42A5A93C500E6B374 /* Network */ = { + isa = PBXGroup; + children = ( + D4DEA8212A46C330006FB3DF /* GenderListResponseDTO+Mapping.swift */, + D4DEA82C2A46CB8A006FB3DF /* GenderListQuery.swift */, + ); + path = Network; + sourceTree = ""; + }; + D4DEA8102A4485AC006FB3DF /* Extensions */ = { + isa = PBXGroup; + children = ( + D4DEA8112A4485D1006FB3DF /* UICollectionView+Extension.swift */, + D4DEA8192A45FB10006FB3DF /* ListPageView+Rx.swift */, + D4DEA83C2A484397006FB3DF /* UICollectionView+Rx.swift */, + D4DEA8422A48F046006FB3DF /* TabView+Rx.swift */, + D49B50E72A53F8C70081FF9D /* UIView+Extension.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + D4DEA8282A46C954006FB3DF /* Interfaces */ = { + isa = PBXGroup; + children = ( + D463D49C2A4296AB00E37898 /* Repositories */, + ); + path = Interfaces; + sourceTree = ""; + }; + D4DEA8442A48F9D9006FB3DF /* Detail */ = { + isa = PBXGroup; + children = ( + D4DEA81B2A46802E006FB3DF /* DetailViewController.swift */, + D4DEA8352A4725AD006FB3DF /* DetailView.swift */, + ); + path = Detail; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + D463D4672A419E4B00E37898 /* GenderList */ = { + isa = PBXNativeTarget; + buildConfigurationList = D463D47C2A419E4C00E37898 /* Build configuration list for PBXNativeTarget "GenderList" */; + buildPhases = ( + 84D919033D6CE62475CF011E /* [CP] Check Pods Manifest.lock */, + D463D4642A419E4B00E37898 /* Sources */, + D463D4652A419E4B00E37898 /* Frameworks */, + D463D4662A419E4B00E37898 /* Resources */, + 4F7637DC6C551E8E7AD1EAF1 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GenderList; + productName = Bunjang; + productReference = D463D4682A419E4B00E37898 /* GenderList.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D463D4602A419E4B00E37898 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1430; + TargetAttributes = { + D463D4672A419E4B00E37898 = { + CreatedOnToolsVersion = 14.3; + }; + }; + }; + buildConfigurationList = D463D4632A419E4B00E37898 /* Build configuration list for PBXProject "GenderList" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = D463D45F2A419E4B00E37898; + productRefGroup = D463D4692A419E4B00E37898 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D463D4672A419E4B00E37898 /* GenderList */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D463D4662A419E4B00E37898 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D463D4782A419E4C00E37898 /* LaunchScreen.storyboard in Resources */, + D463D4752A419E4C00E37898 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4F7637DC6C551E8E7AD1EAF1 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 84D919033D6CE62475CF011E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-GenderList-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D463D4642A419E4B00E37898 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D4FCE4792A55229100D60C20 /* InitialViewModel.swift in Sources */, + D4DEA82A2A46C9BA006FB3DF /* GenderListRepository.swift in Sources */, + D41D7C112A5D5A9300F46AAC /* AppDIContainer.swift in Sources */, + D4DEA8242A46C5A6006FB3DF /* NetworkService.swift in Sources */, + D485DC252A57ED9A00243487 /* ListViewOutput.swift in Sources */, + D4DEA8182A45AFD2006FB3DF /* TabListViewModel.swift in Sources */, + D4DEA8222A46C330006FB3DF /* GenderListResponseDTO+Mapping.swift in Sources */, + D404F6032A429D5B0065E095 /* TabCollectionViewCell.swift in Sources */, + D41D7C132A5D5C6C00F46AAC /* GenderListSceneDIContainer.swift in Sources */, + D404F6082A42F65C0065E095 /* TabPageView.swift in Sources */, + D49B50E82A53F8C70081FF9D /* UIView+Extension.swift in Sources */, + D4DEA8432A48F046006FB3DF /* TabView+Rx.swift in Sources */, + D404F6172A432C1D0065E095 /* ListCollectionViewCell.swift in Sources */, + D404F6012A429CA40065E095 /* TabCollectionView.swift in Sources */, + D4DEA8162A456E08006FB3DF /* TabViewModel.swift in Sources */, + D4DEA82F2A46CBDD006FB3DF /* DefaultGenderListRepository.swift in Sources */, + D4DEA80D2A448396006FB3DF /* Bindable.swift in Sources */, + D4DEA81E2A46BD37006FB3DF /* ColumnStyle.swift in Sources */, + D4DEA83D2A484397006FB3DF /* UICollectionView+Rx.swift in Sources */, + D463D4702A419E4B00E37898 /* GenderListViewController.swift in Sources */, + D4DEA8122A4485D1006FB3DF /* UICollectionView+Extension.swift in Sources */, + D4DEA8312A46F34F006FB3DF /* GenderListUsecase.swift in Sources */, + D4DEA8202A46C182006FB3DF /* ListViewModel.swift in Sources */, + D4DEA8412A48D5F4006FB3DF /* GenderListFetchHelper.swift in Sources */, + D41D7C162A5D5F7500F46AAC /* GenderListFlowCoordinator.swift in Sources */, + D4DEA8362A4725AD006FB3DF /* DetailView.swift in Sources */, + D480D3E92A5D02DE00AD0C26 /* GenderProfileItemViewModel.swift in Sources */, + D4DEA83A2A483120006FB3DF /* DefaultPagenationGenerator.swift in Sources */, + D4E244AB2A5FF01F004E0167 /* GenderListDetailFlowCoordinator.swift in Sources */, + D4DEA81C2A46802E006FB3DF /* DetailViewController.swift in Sources */, + D4B062D62A5A97A700E6B374 /* GenderProfile.swift in Sources */, + D4DEA8142A44933D006FB3DF /* ListPageViewModel.swift in Sources */, + D404F6122A4302CC0065E095 /* PageCollectionViewCell.swift in Sources */, + D4E244A92A5FEF9B004E0167 /* GenderListDetailDIContainer.swift in Sources */, + D4DEA83F2A48D413006FB3DF /* FetchStatus.swift in Sources */, + D463D46C2A419E4B00E37898 /* AppDelegate.swift in Sources */, + D4DEA80F2A4483AC006FB3DF /* ViewModelType.swift in Sources */, + D41D7C0E2A5D573E00F46AAC /* AppFlowCoordinator.swift in Sources */, + D485DC222A57ECE400243487 /* ListViewOutputHelper.swift in Sources */, + D4DEA81A2A45FB10006FB3DF /* ListPageView+Rx.swift in Sources */, + D463D46E2A419E4B00E37898 /* SceneDelegate.swift in Sources */, + D404F60A2A42FAF70065E095 /* PageCollectionView.swift in Sources */, + D4DEA8382A482FBB006FB3DF /* PagenationGenerator.swift in Sources */, + D404F6152A432C130065E095 /* ListCollectionView.swift in Sources */, + D4DEA82D2A46CB8A006FB3DF /* GenderListQuery.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + D463D4762A419E4C00E37898 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + D463D4772A419E4C00E37898 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + D463D47A2A419E4C00E37898 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + D463D47B2A419E4C00E37898 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + D463D47D2A419E4C00E37898 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 452EB8A8D971E7BD7183B125 /* Pods-GenderList.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4MNTP64Q22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = GenderList/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ronick.GenderList; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D463D47E2A419E4C00E37898 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CF03917F3E07BA67B3825C05 /* Pods-GenderList.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4MNTP64Q22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = GenderList/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ronick.GenderList; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D463D4632A419E4B00E37898 /* Build configuration list for PBXProject "GenderList" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D463D47A2A419E4C00E37898 /* Debug */, + D463D47B2A419E4C00E37898 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D463D47C2A419E4C00E37898 /* Build configuration list for PBXNativeTarget "GenderList" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D463D47D2A419E4C00E37898 /* Debug */, + D463D47E2A419E4C00E37898 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D463D4602A419E4B00E37898 /* Project object */; +} diff --git a/Bunjang.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/GenderList.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Bunjang.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to GenderList.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Bunjang.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/GenderList.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Bunjang.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to GenderList.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Bunjang.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist b/GenderList.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist similarity index 75% rename from Bunjang.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist rename to GenderList.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist index 4c4e70c..642feaa 100644 --- a/Bunjang.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/GenderList.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,6 +9,11 @@ orderHint 7 + GenderList.xcscheme_^#shared#^_ + + orderHint + 7 + diff --git a/Bunjang.xcworkspace/contents.xcworkspacedata b/GenderList.xcworkspace/contents.xcworkspacedata similarity index 79% rename from Bunjang.xcworkspace/contents.xcworkspacedata rename to GenderList.xcworkspace/contents.xcworkspacedata index e656f1c..1c0875e 100644 --- a/Bunjang.xcworkspace/contents.xcworkspacedata +++ b/GenderList.xcworkspace/contents.xcworkspacedata @@ -2,7 +2,7 @@ + location = "group:GenderList.xcodeproj"> diff --git a/Bunjang.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/GenderList.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from Bunjang.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to GenderList.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/IDEFindNavigatorScopes.plist b/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/IDEFindNavigatorScopes.plist new file mode 100644 index 0000000..5dd5da8 --- /dev/null +++ b/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/IDEFindNavigatorScopes.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..94dc32d --- /dev/null +++ b/GenderList.xcworkspace/xcuserdata/ronick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/Bunjang/Application/AppDelegate.swift b/GenderList/Application/AppDelegate.swift similarity index 95% rename from Bunjang/Application/AppDelegate.swift rename to GenderList/Application/AppDelegate.swift index 12e82aa..4d0dd60 100644 --- a/Bunjang/Application/AppDelegate.swift +++ b/GenderList/Application/AppDelegate.swift @@ -1,6 +1,6 @@ // // AppDelegate.swift -// Bunjang +// GenderList // // Created by Ronick on 6/20/23. // @@ -9,16 +9,11 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - // MARK: UISceneSession Lifecycle - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { // Called when a new scene session is being created. // Use this method to select a configuration to create the new scene with. @@ -30,7 +25,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } - - } diff --git a/GenderList/Application/AppFlowCoordinator.swift b/GenderList/Application/AppFlowCoordinator.swift new file mode 100644 index 0000000..aee595c --- /dev/null +++ b/GenderList/Application/AppFlowCoordinator.swift @@ -0,0 +1,39 @@ +// +// AppFlowCoordinator.swift +// GenderList +// +// Created by RONICK on 2023/07/11. +// + +import UIKit + +final class AppFlowCoordinator { + let navigationController: UINavigationController + private let appDIContainer: AppDIContainer + + init(navigationController: UINavigationController, appDIContainer: AppDIContainer) { + self.navigationController = navigationController + self.appDIContainer = appDIContainer + } + + func start() { + let genderListSceneDIContainer = appDIContainer.makeGenderListSceneDIContainer() + let flow = genderListSceneDIContainer.makeGenderListFlowCoordinator( + navigationController: navigationController, + parentCoordinator: self + ) + + flow.start() + } + + func startDetailsView(dependencies: GenderListDetailDIContainer.Dependencies) { + let genderListDetailDIContainer = appDIContainer.makeGenderListDetailDIContainer( + dependencies: dependencies + ) + let flow = genderListDetailDIContainer.makeGenderListDetailFlowCoordinator( + navigationController: navigationController, + parentCoordinator: self + ) + flow.start() + } +} diff --git a/GenderList/Application/DIContainer/AppDIContainer.swift b/GenderList/Application/DIContainer/AppDIContainer.swift new file mode 100644 index 0000000..59ac720 --- /dev/null +++ b/GenderList/Application/DIContainer/AppDIContainer.swift @@ -0,0 +1,18 @@ +// +// AppDIContainer.swift +// GenderList +// +// Created by RONICK on 2023/07/11. +// + +import UIKit + +final class AppDIContainer { + func makeGenderListSceneDIContainer() -> GenderListSceneDIContainer { + GenderListSceneDIContainer() + } + + func makeGenderListDetailDIContainer(dependencies: GenderListDetailDIContainer.Dependencies) -> GenderListDetailDIContainer { + GenderListDetailDIContainer(dependencies: dependencies) + } +} diff --git a/GenderList/Application/DIContainer/GenderListDetailDIContainer.swift b/GenderList/Application/DIContainer/GenderListDetailDIContainer.swift new file mode 100644 index 0000000..d33fd2e --- /dev/null +++ b/GenderList/Application/DIContainer/GenderListDetailDIContainer.swift @@ -0,0 +1,33 @@ +// +// GenderListDetailDIContainer.swift +// GenderList +// +// Created by RONICK on 2023/07/13. +// + +import UIKit + +final class GenderListDetailDIContainer: GenderListDetailFlowCoodinatorDependencies { + struct Dependencies { + let genderProfileItem: GenderProfileItemViewModel + } + + private let dependencies: Dependencies + + init(dependencies: Dependencies) { + self.dependencies = dependencies + } + + func makeGenderListDetailViewController() -> DetailViewController { + let detailView = DetailView(viewModel: dependencies.genderProfileItem) + return DetailViewController(detailView: detailView) + } + + func makeGenderListDetailFlowCoordinator(navigationController: UINavigationController, parentCoordinator: AppFlowCoordinator) -> GenderListDetailFlowCoordinator { + GenderListDetailFlowCoordinator( + navigationController: navigationController, + parentCoordinator: parentCoordinator, + dependencies: self + ) + } +} diff --git a/GenderList/Application/DIContainer/GenderListSceneDIContainer.swift b/GenderList/Application/DIContainer/GenderListSceneDIContainer.swift new file mode 100644 index 0000000..a7f5960 --- /dev/null +++ b/GenderList/Application/DIContainer/GenderListSceneDIContainer.swift @@ -0,0 +1,27 @@ +// +// GenderListSceneDIContainer.swift +// GenderList +// +// Created by RONICK on 2023/07/11. +// + +import UIKit + +final class GenderListSceneDIContainer: GenderListFlowCoodinatorDependencies { + func makeGenderDetailsViewController(genderProfileItem: GenderProfileItemViewModel) -> DetailViewController { + let detailView = DetailView(viewModel: genderProfileItem) + return DetailViewController(detailView: detailView) + } + + func makeGenderListViewController(showDetailList: (GenderProfileItemViewModel) -> Void) -> GenderListViewController { + GenderListViewController() + } + + func makeGenderListFlowCoordinator(navigationController: UINavigationController, parentCoordinator: AppFlowCoordinator) -> GenderListFlowCoordinator { + GenderListFlowCoordinator( + navigationController: navigationController, + parentCoordinator: parentCoordinator, + dependencies: self + ) + } +} diff --git a/GenderList/Application/SceneDelegate.swift b/GenderList/Application/SceneDelegate.swift new file mode 100644 index 0000000..ce3b5c0 --- /dev/null +++ b/GenderList/Application/SceneDelegate.swift @@ -0,0 +1,34 @@ +// +// SceneDelegate.swift +// GenderList +// +// Created by Ronick on 6/20/23. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + let appDIContainer = AppDIContainer() + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowScene) + + let navigationController = UINavigationController() + navigationController.navigationBar.backgroundColor = .clear + navigationController.navigationBar.isTranslucent = false + + window?.rootViewController = navigationController + let appFlowCoordinator = AppFlowCoordinator( + navigationController: navigationController, + appDIContainer: appDIContainer + ) + + appFlowCoordinator.start() + window?.backgroundColor = .systemBackground + window?.makeKeyAndVisible() + } + +} + diff --git a/Bunjang/Assets.xcassets/AccentColor.colorset/Contents.json b/GenderList/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Bunjang/Assets.xcassets/AccentColor.colorset/Contents.json rename to GenderList/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Bunjang/Assets.xcassets/AppIcon.appiconset/Contents.json b/GenderList/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Bunjang/Assets.xcassets/AppIcon.appiconset/Contents.json rename to GenderList/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Bunjang/Assets.xcassets/Contents.json b/GenderList/Assets.xcassets/Contents.json similarity index 100% rename from Bunjang/Assets.xcassets/Contents.json rename to GenderList/Assets.xcassets/Contents.json diff --git a/Bunjang/Base.lproj/LaunchScreen.storyboard b/GenderList/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from Bunjang/Base.lproj/LaunchScreen.storyboard rename to GenderList/Base.lproj/LaunchScreen.storyboard diff --git a/Bunjang/Base.lproj/Main.storyboard b/GenderList/Base.lproj/Main.storyboard similarity index 100% rename from Bunjang/Base.lproj/Main.storyboard rename to GenderList/Base.lproj/Main.storyboard diff --git a/GenderList/Data/Network/GenderListQuery.swift b/GenderList/Data/Network/GenderListQuery.swift new file mode 100644 index 0000000..03245d3 --- /dev/null +++ b/GenderList/Data/Network/GenderListQuery.swift @@ -0,0 +1,20 @@ +// +// GenderListQuery.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +struct GenderListQuery { + let page: Int + let results: Int + let seed: String + + var parameters: [String: Any] { + return [ + "page": page, + "results": results, + "seed": seed + ] + } +} diff --git a/GenderList/Data/Network/GenderListResponseDTO+Mapping.swift b/GenderList/Data/Network/GenderListResponseDTO+Mapping.swift new file mode 100644 index 0000000..03466d4 --- /dev/null +++ b/GenderList/Data/Network/GenderListResponseDTO+Mapping.swift @@ -0,0 +1,42 @@ +// +// GenderList.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +struct GenderList: Decodable { + let results: [Gender] +} + +struct Gender: Decodable { + let gender: String + let name: Name + let email: String + let picture: Picture +} + +struct Name: Decodable { + let title: String + let first: String + let last: String +} + +struct Picture: Decodable { + let large: String + let medium: String + let thumbnail: String +} + +extension GenderList { + func toDomain() -> [GenderProfile] { + results.map { + GenderProfile( + gender: $0.gender, + name: $0.name.first + " " + $0.name.last, + email: $0.email, + profileUrl: $0.picture.large + ) + } + } +} diff --git a/GenderList/Data/Repositories/DefaultGenderListRepository.swift b/GenderList/Data/Repositories/DefaultGenderListRepository.swift new file mode 100644 index 0000000..e6533ec --- /dev/null +++ b/GenderList/Data/Repositories/DefaultGenderListRepository.swift @@ -0,0 +1,33 @@ +// +// DefaultGenderListRepository.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import RxSwift + +final class DefaultGenderListRepository { + private let networkService: NetworkService + + init(service: NetworkService) { + networkService = service + } +} + +extension DefaultGenderListRepository: GenderListRepository { + func getGenderList(genderListQuery: GenderListQuery) async throws -> [GenderProfile] { + let page = genderListQuery.page + let results = genderListQuery.results + let seed = genderListQuery.seed + + // TODO: endpoint enum화 작업 + let response: GenderList = try await networkService + .request( + urlString: "https://randomuser.me/api/?page=\(page)&results=\(results)&seed=\(seed)&inc=gender,name,email,picture", + queryParameter: genderListQuery.parameters + ) + + return response.toDomain() + } +} diff --git a/GenderList/Domain/Entities/GenderProfile.swift b/GenderList/Domain/Entities/GenderProfile.swift new file mode 100644 index 0000000..651e3d3 --- /dev/null +++ b/GenderList/Domain/Entities/GenderProfile.swift @@ -0,0 +1,15 @@ +// +// Profile.swift +// GenderList +// +// Created by RONICK on 2023/07/09. +// + +import Foundation + +struct GenderProfile { + let gender: String + let name: String + let email: String + let profileUrl: String +} diff --git a/GenderList/Domain/Interfaces/Repositories/GenderListRepository.swift b/GenderList/Domain/Interfaces/Repositories/GenderListRepository.swift new file mode 100644 index 0000000..872695e --- /dev/null +++ b/GenderList/Domain/Interfaces/Repositories/GenderListRepository.swift @@ -0,0 +1,12 @@ +// +// GenderListRepository.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import RxSwift + +protocol GenderListRepository { + func getGenderList(genderListQuery: GenderListQuery) async throws -> [GenderProfile] +} diff --git a/GenderList/Domain/Usecases/GenderListUsecase.swift b/GenderList/Domain/Usecases/GenderListUsecase.swift new file mode 100644 index 0000000..f11ca8c --- /dev/null +++ b/GenderList/Domain/Usecases/GenderListUsecase.swift @@ -0,0 +1,31 @@ +// +// GenderListUsecase.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import RxSwift + +/// 성별 리스트 유즈케이스 +protocol GenderListUsecase { + + /// 성별 리스트 데이터를 가져옵니다 + /// - Parameter genderListQuery: 쿼리파라미터 + /// - Returns: 성별 리스트 데이터 + func get(genderListQuery: GenderListQuery) async throws -> [GenderProfileItemViewModel] +} + +final class DefaultGenderListUsecase: GenderListUsecase { + private let genderListRepository: GenderListRepository + + init(genderListRepository: GenderListRepository) { + self.genderListRepository = genderListRepository + } + + func get(genderListQuery: GenderListQuery) async throws -> [GenderProfileItemViewModel] { + return try await genderListRepository + .getGenderList(genderListQuery: genderListQuery) + .map(GenderProfileItemViewModel.init) + } +} diff --git a/Bunjang/Info.plist b/GenderList/Info.plist similarity index 100% rename from Bunjang/Info.plist rename to GenderList/Info.plist diff --git a/GenderList/Infrastructure/Network/NetworkService.swift b/GenderList/Infrastructure/Network/NetworkService.swift new file mode 100644 index 0000000..b77ae74 --- /dev/null +++ b/GenderList/Infrastructure/Network/NetworkService.swift @@ -0,0 +1,35 @@ +// +// NetworkService.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import RxSwift +import Alamofire + +protocol NetworkService { + func request(urlString: String, queryParameter: E?) async throws -> T + func request(urlString: String, parameter: E) async throws -> T +} + +final class DefaultNetworkService: NetworkService { + func request(urlString: String, queryParameter: E?) async throws -> T { + return try await AF + .request(urlString, + method: .get, + encoding: URLEncoding.queryString) + .serializingDecodable(T.self) + .value + } + + func request(urlString: String, parameter: E) async throws -> T { + return try await AF + .request(urlString, + method: .post, + parameters: parameter, + encoder: JSONParameterEncoder.default) + .serializingDecodable(T.self) + .value + } +} diff --git a/GenderList/Presentation/ListScene/Flow/GenderListDetailFlowCoordinator.swift b/GenderList/Presentation/ListScene/Flow/GenderListDetailFlowCoordinator.swift new file mode 100644 index 0000000..75e9540 --- /dev/null +++ b/GenderList/Presentation/ListScene/Flow/GenderListDetailFlowCoordinator.swift @@ -0,0 +1,32 @@ +// +// GenderListDetailFlowCoordinator.swift +// GenderList +// +// Created by RONICK on 2023/07/13. +// + +import Foundation + +import UIKit + +protocol GenderListDetailFlowCoodinatorDependencies { + func makeGenderListDetailViewController() -> DetailViewController +} + +final class GenderListDetailFlowCoordinator { + private weak var navigationController: UINavigationController? + private weak var parentCoordinator: AppFlowCoordinator? + + private let dependencies: GenderListDetailFlowCoodinatorDependencies + + init(navigationController: UINavigationController, parentCoordinator: AppFlowCoordinator, dependencies: GenderListDetailFlowCoodinatorDependencies) { + self.navigationController = navigationController + self.parentCoordinator = parentCoordinator + self.dependencies = dependencies + } + + func start() { + let vc = dependencies.makeGenderListDetailViewController() + navigationController?.pushViewController(vc, animated: true) + } +} diff --git a/GenderList/Presentation/ListScene/Flow/GenderListFlowCoordinator.swift b/GenderList/Presentation/ListScene/Flow/GenderListFlowCoordinator.swift new file mode 100644 index 0000000..48a7232 --- /dev/null +++ b/GenderList/Presentation/ListScene/Flow/GenderListFlowCoordinator.swift @@ -0,0 +1,42 @@ +// +// GenderListFlowCoordinator.swift +// GenderList +// +// Created by RONICK on 2023/07/11. +// + +import UIKit + +protocol GenderListFlowCoodinatorDependencies { + func makeGenderListViewController(showDetailList: (GenderProfileItemViewModel) -> Void) -> GenderListViewController + func makeGenderDetailsViewController(genderProfileItem: GenderProfileItemViewModel) -> DetailViewController +} + +final class GenderListFlowCoordinator { + private weak var navigationController: UINavigationController? + private weak var parentCoordinator: AppFlowCoordinator? + + private let dependencies: GenderListFlowCoodinatorDependencies + + private weak var GenderListVC: GenderListViewController? + + init(navigationController: UINavigationController, parentCoordinator: AppFlowCoordinator, dependencies: GenderListFlowCoodinatorDependencies) { + self.navigationController = navigationController + self.parentCoordinator = parentCoordinator + self.dependencies = dependencies + } + + func start() { + let vc = dependencies.makeGenderListViewController(showDetailList: showDetailList) + navigationController?.pushViewController(vc, animated: true) + GenderListVC = vc + } + + private func showDetailList(genderProfileItem: GenderProfileItemViewModel) { + parentCoordinator?.startDetailsView( + dependencies: GenderListDetailDIContainer.Dependencies( + genderProfileItem: genderProfileItem + ) + ) + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/GenderProfileItemViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/GenderProfileItemViewModel.swift new file mode 100644 index 0000000..a3cbfe1 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/GenderProfileItemViewModel.swift @@ -0,0 +1,24 @@ +// +// GenderProfileItemViewModel.swift +// GenderList +// +// Created by RONICK on 2023/07/11. +// + +import Foundation + +struct GenderProfileItemViewModel { + let gender: String + let name: String + let email: String + let profileUrl: String +} + +extension GenderProfileItemViewModel { + init(genderProfile: GenderProfile) { + self.gender = genderProfile.gender + self.name = genderProfile.name + self.email = genderProfile.email + self.profileUrl = genderProfile.profileUrl + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/InitialViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/InitialViewModel.swift new file mode 100644 index 0000000..c24d477 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/InitialViewModel.swift @@ -0,0 +1,35 @@ +// +// InitialViewModel.swift +// GenderList +// +// Created by RONICK on 2023/07/05. +// + +import Foundation +import RxSwift + +class InitialViewModel: ViewModelType { + struct Input { + let selectButtonTapped: Observable + } + + struct Output { + let selectButtonTitle: Observable + } + + struct Actions { + let showDetails: (GenderProfileItemViewModel) -> Void + } + + var disposeBag = DisposeBag() + + func transform(input: Input) -> Output { + + let selectButtonTitle = input.selectButtonTapped + .scan(true) { prev, _ in + !prev + }.map { $0 ? "선택" : "취소" } + + return Output(selectButtonTitle: selectButtonTitle) + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/ListPageViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/ListPageViewModel.swift new file mode 100644 index 0000000..6151ea0 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/ListPageViewModel.swift @@ -0,0 +1,34 @@ +// +// ListPageViewModel.swift +// GenderList +// +// Created by Ronick on 6/22/23. +// + +import RxSwift + +final class ListPageViewModel: ViewModelType { + struct Input { + /// 탭 화면(남자, 여자) 리스트 초기화 이벤트 + let tabsInitialized: Observable<[String]> + } + + struct Output { + /// 탭 타이틀 + let tabs: Observable<[String]> + } + + var pageInfo: PageInfo = (prev: 0, current: 0) + + var disposeBag = DisposeBag() + + var columnStyle = ColumnStyle.two + + func transform(input: Input) -> Output { + let tabs = input.tabsInitialized + + return Output( + tabs: tabs + ) + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/ListViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/ListViewModel.swift new file mode 100644 index 0000000..9abe052 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/ListViewModel.swift @@ -0,0 +1,79 @@ +// +// ListViewModel.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import RxSwift + +final class ListViewModel: ViewModelType { + struct Input { + /// 탭 화면(남자 or 여자) 리스트 초기화 이벤트 + let tabInitialized: PublishSubject + + /// 스크롤을 맨 밑으로 내렸을 때 발생하는 이벤트 + let scrolledToBottom: Observable + + /// 새로고침 이벤트 + let didPullToRefresh: PublishSubject + + /// 리스트 아이템 클릭 이벤트 + let itemTapped: Observable + + /// 선택 버튼 클릭 이벤트 + var selectButtonTapped: PublishSubject> + + /// 제거 버튼 클릭 이벤트 + var removeBarButtonTapped: PublishSubject> + } + + struct Output { + /// 성별 리스트 + let genderList: BehaviorSubject<[GenderProfileItemViewModel]> + + /// 성별 리스트 에러 + let genderListError: Observable + + /// 선택된 리스트 취소 + let cancelSelectedList: Observable + + /// 선택한 아이템 마킹 처리 + let markItem: Observable + + /// 선택한 아이템의 상세화면 이동 + let moveToDetail: Observable + } + + private let listViewOutputHelper: ListViewOutput + + var disposeBag = DisposeBag() + + init(outputHelper: ListViewOutput = ListViewOutputHelper()) { + listViewOutputHelper = outputHelper + } + + func transform(input: Input) -> Output { + let genderListOutput = listViewOutputHelper.createGenderListOutput(input: input) + let selectionEventOutput = listViewOutputHelper.createSelectionEventOutput( + input: input, + genderList: genderListOutput.genderList + ) + + return Output( + genderList: genderListOutput.genderList, + genderListError: genderListOutput.genderListError, + cancelSelectedList: selectionEventOutput.cancelSelectedList, + markItem: selectionEventOutput.markItem, + moveToDetail: selectionEventOutput.moveToDetail + ) + } + + func removeAllSelectedItems() { + listViewOutputHelper.removeAllSelectedItems() + } + + func isSelected(index: Int) -> Bool { + listViewOutputHelper.selectedItemIndexes.contains(index) + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/OutputHelpers/ListViewOutputHelper.swift b/GenderList/Presentation/ListScene/ViewModels/OutputHelpers/ListViewOutputHelper.swift new file mode 100644 index 0000000..335417a --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/OutputHelpers/ListViewOutputHelper.swift @@ -0,0 +1,102 @@ +// +// ListViewOutputHelper.swift +// GenderList +// +// Created by RONICK on 2023/07/07. +// + +import RxSwift + +class ListViewOutputHelper: ListViewOutput { + var disposeBag = DisposeBag() + var fetchHelper: DefaultGenderListFetchHelper + var selectedItemIndexes = [Int]() + + init(usecase: GenderListUsecase = DefaultGenderListUsecase( + genderListRepository: DefaultGenderListRepository(service: DefaultNetworkService())) + ) { + self.fetchHelper = DefaultGenderListFetchHelper(usecase: usecase) + } + + func createGenderListOutput(input: ListViewModel.Input) -> genderListOutput { + let genderList = BehaviorSubject<[GenderProfileItemViewModel]>.init(value: []) + let genderListError = PublishSubject() + + var genderType = "" + + input.tabInitialized + .flatMap { + genderType = $0 + return self.fetchHelper.fetch(genderType: $0) + }.subscribe(onNext: { list in + genderList.onNext(list) + }, onError: { + genderListError.onNext($0.localizedDescription) + }).disposed(by: disposeBag) + + input.scrolledToBottom + .filter { self.fetchHelper.fetchStatus == .ready } + .flatMap { self.fetchHelper.fetch(genderType: genderType) } + .subscribe(onNext: { list in + genderList.onNext(list) + }, onError: { + genderListError.onNext($0.localizedDescription) + }).disposed(by: disposeBag) + + input.didPullToRefresh + .flatMap { self.fetchHelper.reset(genderType: genderType) } + .subscribe(onNext: { list in + genderList.onNext(list) + }, onError: { + genderListError.onNext($0.localizedDescription) + }).disposed(by: disposeBag) + + input.removeBarButtonTapped + .flatMap { $0 } + .map { self.fetchHelper.remove(at: self.selectedItemIndexes) } + .subscribe(onNext: { list in + self.selectedItemIndexes.removeAll() + genderList.onNext(list) + }).disposed(by: disposeBag) + + return (genderList, genderListError) + } + + func createSelectionEventOutput(input: ListViewModel.Input, genderList: BehaviorSubject<[GenderProfileItemViewModel]>) -> selectionEventOutput { + var isSelectMode = false + let cancelSelectedList = PublishSubject() + + input.selectButtonTapped + .flatMap { $0 } + .subscribe(onNext: { + isSelectMode = $0 + if !$0 { + cancelSelectedList.onNext(Void()) + } + }).disposed(by: disposeBag) + + let markItem = PublishSubject() + let moveToDetail = PublishSubject() + input.itemTapped + .map { SelectedItemInfo(indexPath: $0, isSelectMode: isSelectMode) } + .subscribe(onNext: { itemInfo in + if itemInfo.isSelectMode { + if self.selectedItemIndexes.contains(itemInfo.indexPath.row) { + self.selectedItemIndexes.removeAll { $0 == itemInfo.indexPath.row } + } else { + self.selectedItemIndexes.append(itemInfo.indexPath.row) + } + markItem.onNext(itemInfo.indexPath) + } else { + let genderInfo = try? genderList.value()[itemInfo.indexPath.row] + moveToDetail.onNext(genderInfo) + } + }).disposed(by: disposeBag) + + return (cancelSelectedList, markItem, moveToDetail) + } + + func removeAllSelectedItems() { + selectedItemIndexes.removeAll() + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/TabListViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/TabListViewModel.swift new file mode 100644 index 0000000..c439912 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/TabListViewModel.swift @@ -0,0 +1,55 @@ +// +// TabListViewModel.swift +// GenderList +// +// Created by Ronick on 6/23/23. +// + +import RxSwift + +final class TabListViewModel: ViewModelType { + struct Input { + /// 성별 리스트 구성 전환 버튼 클릭 이벤트 + let columnStyleButtonTapped: Observable + + /// 성별 탭(남자 or 여자) 버튼 클릭 이벤트 + let tabButtonTapped: Observable + + /// 탭 화면 스와이프 이벤트 + let pageSwiped: Observable + } + + struct Output { + /// 성별 리스트 구성 전환 타입 + let columnStyle: Observable + + /// 선택된 탭(남자 or 여자) + let selectedTab: Observable + + /// 전환될 탭 페이지(화면 - 남자 탭화면 or 여자 탭화면) + let pageScrollTo: Observable + } + + var disposeBag = DisposeBag() + + func transform(input: Input) -> Output { + let columnStyle = input.columnStyleButtonTapped + .scan(ColumnStyle.two) { prev, _ in + switch prev { + case .one: return .two + case .two: return .one + } + } + + let selectedTab = input.pageSwiped + + let pageScrollTo = input.tabButtonTapped + .map { $0.current } + + return Output( + columnStyle: columnStyle, + selectedTab: selectedTab, + pageScrollTo: pageScrollTo + ) + } +} diff --git a/GenderList/Presentation/ListScene/ViewModels/TabViewModel.swift b/GenderList/Presentation/ListScene/ViewModels/TabViewModel.swift new file mode 100644 index 0000000..0fa2a44 --- /dev/null +++ b/GenderList/Presentation/ListScene/ViewModels/TabViewModel.swift @@ -0,0 +1,30 @@ +// +// TabViewModel.swift +// GenderList +// +// Created by Ronick on 6/23/23. +// + +import RxSwift + +final class TabViewModel: ViewModelType { + struct Input { + /// 탭 화면(남자, 여자) 리스트 초기화 이벤트 + let tabsInitialized: Observable<[String]> + } + + struct Output { + /// 탭 타이틀 + let tabs: Observable<[String]> + } + + var pageInfo: PageInfo = (prev: 0, current: 0) + + var disposeBag = DisposeBag() + + func transform(input: Input) -> Output { + let tabs = input.tabsInitialized + + return Output(tabs: tabs) + } +} diff --git a/GenderList/Presentation/ListScene/Views/Detail/DetailView.swift b/GenderList/Presentation/ListScene/Views/Detail/DetailView.swift new file mode 100644 index 0000000..ef5df37 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/Detail/DetailView.swift @@ -0,0 +1,113 @@ +// +// DetailView.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import UIKit + +final class DetailView: UIView { + private let scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.alwaysBounceVertical = false + scrollView.alwaysBounceHorizontal = false + + scrollView.zoomScale = 1.0 + scrollView.minimumZoomScale = 1.0 + scrollView.maximumZoomScale = 2.0 + return scrollView + }() + + private let profileImageView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(systemName: "person") + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + return imageView + }() + + private let nameLabel: UILabel = { + let label = UILabel() + label.text = "Ronick Kim" + label.font = UIFont.systemFont(ofSize: 13) + label.textColor = .black + + return label + }() + + private let emailLabel: UILabel = { + let label = UILabel() + label.text = "ronick@gmail.com" + label.font = UIFont.systemFont(ofSize: 13) + label.textColor = .black + + return label + }() + + private let viewModel: GenderProfileItemViewModel + + private var leadingSpace: Int { + 10 + } + + init(viewModel: GenderProfileItemViewModel) { + self.viewModel = viewModel + + super.init(frame: .zero) + + scrollView.delegate = self + setUp() + configure() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + addSubview(scrollView) + scrollView.snp.makeConstraints { + $0.leading.trailing.equalToSuperview() + $0.top.equalToSuperview().offset(100) + $0.height.equalTo(500) + } + + scrollView.addSubview(profileImageView) + profileImageView.snp.makeConstraints { + $0.width.equalTo(scrollView) + $0.height.equalTo(scrollView) + } + + addSubview(nameLabel) + nameLabel.snp.makeConstraints { + $0.top.equalTo(scrollView.snp.bottom).offset(20) + $0.leading.equalTo(scrollView).offset(leadingSpace) + } + + addSubview(emailLabel) + emailLabel.snp.makeConstraints { + $0.top.equalTo(nameLabel.snp.bottom) + $0.leading.equalTo(scrollView).offset(leadingSpace) + } + } + + func configure() { + let profileImageUrl = URL(string: viewModel.profileUrl) + profileImageView.kf.setImage(with: profileImageUrl) + nameLabel.text = viewModel.name + emailLabel.text = viewModel.email + } +} + +extension DetailView: UIScrollViewDelegate { + func viewForZooming(in scrollView: UIScrollView) -> UIView? { + return profileImageView + } + + func scrollViewDidZoom(_ scrollView: UIScrollView) { + if scrollView.zoomScale < scrollView.minimumZoomScale { + scrollView.zoomScale = scrollView.minimumZoomScale + } + } +} diff --git a/GenderList/Presentation/ListScene/Views/Detail/DetailViewController.swift b/GenderList/Presentation/ListScene/Views/Detail/DetailViewController.swift new file mode 100644 index 0000000..c8f2a14 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/Detail/DetailViewController.swift @@ -0,0 +1,35 @@ +// +// DetailViewController.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import UIKit +import RxSwift + +final class DetailViewController: UIViewController { + private let detailView: DetailView + + init(detailView: DetailView) { + self.detailView = detailView + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + view.backgroundColor = .white + setUp() + } + + private func setUp() { + view.addSubview(detailView) + detailView.snp.makeConstraints { + $0.edges.equalToSuperview() + $0.center.equalToSuperview() + } + } +} diff --git a/GenderList/Presentation/ListScene/Views/GenderListViewController.swift b/GenderList/Presentation/ListScene/Views/GenderListViewController.swift new file mode 100644 index 0000000..92cf7ff --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/GenderListViewController.swift @@ -0,0 +1,101 @@ +// +// GenderListViewController.swift +// GenderList +// +// Created by Ronick on 6/20/23. +// + +import UIKit +import SnapKit +import RxSwift + +final class GenderListViewController: UIViewController { + typealias ViewModel = InitialViewModel + + let viewModel = ViewModel() + + var disposeBag = DisposeBag() + + lazy var input = ViewModel.Input( + selectButtonTapped: selectBarButton.rx.tap.asObservable() + ) + + lazy var output = viewModel.transform(input: input) + + lazy var tabListView = TabPageView( + selectBarButtonTapped: selectBarButton.rx.tap + .scan(false, accumulator: { prev, _ in + !prev + }).share(replay: 1), + removeBarButtonTapped: removeBarButton.rx.tap.asObservable() + ) + + lazy var selectBarButton: UIBarButtonItem = { + let barButton = UIBarButtonItem( + title: "선택", + style: .plain, + target: self, + action: nil) + + return barButton + }() + + lazy var removeBarButton: UIBarButtonItem = { + let configuration = UIImage.SymbolConfiguration( + pointSize: 15, + weight: .bold, + scale: .large + ) + let image = UIImage(systemName: "trash", withConfiguration: configuration) + let barButton = UIBarButtonItem( + image: image, + style: .plain, + target: self, + action: nil + ) + + return barButton + }() + + init() { + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + + navigationController?.navigationBar.topItem?.title = "Gender List" + navigationItem.rightBarButtonItems = [selectBarButton, removeBarButton] + + tabListView.setListViewDelegate(listViewDelegate: self) + setUp() + bind() + } + + private func setUp() { + view.addSubview(tabListView) + + tabListView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + } +} + +extension GenderListViewController: Bindable { + func bind() { + output.selectButtonTitle + .bind(to: selectBarButton.rx.title) + .disposed(by: disposeBag) + } +} + +extension GenderListViewController: ListViewDelegate { + func pushDetailViewController(detailVC: DetailViewController) { + navigationController?.pushViewController(detailVC, animated: true) + } +} diff --git a/GenderList/Presentation/ListScene/Views/List/ListCollectionView.swift b/GenderList/Presentation/ListScene/Views/List/ListCollectionView.swift new file mode 100644 index 0000000..2b9c2f2 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/List/ListCollectionView.swift @@ -0,0 +1,143 @@ +// +// ListCollectionView.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import RxSwift + +protocol ListViewDelegate { + func pushDetailViewController(detailVC: DetailViewController) +} + +final class ListCollectionView: UICollectionView { + typealias ViewModel = ListViewModel + + private let cellIdentifier = "ListViewCell" + + let viewModel = ViewModel() + + lazy var input = ViewModel.Input( + tabInitialized: PublishSubject(), + scrolledToBottom: rx.scrolledToBottom, + didPullToRefresh: PublishSubject(), + itemTapped: rx.itemSelected.asObservable(), + selectButtonTapped: PublishSubject>(), + removeBarButtonTapped: PublishSubject>() + ) + + lazy var output = viewModel.transform(input: input) + + var disposeBag = DisposeBag() + + var listViewDelegate: ListViewDelegate? + + init() { + super.init(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + let refreshControl = UIRefreshControl() + refreshControl.addTarget(self, action: #selector(startRefresh), for: .valueChanged) + self.refreshControl = refreshControl + + setUp() + bind() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + setColumnStyle(columnStyle: .two) + + dataSource = nil + delegate = nil + + register(ListCollectionViewCell.self, forCellWithReuseIdentifier: cellIdentifier) + } + + func configure(columnStyle: ColumnStyle, tabName: String) { + input.tabInitialized.onNext(tabName) + setColumnStyle(columnStyle: columnStyle) + } + + func setColumnStyle(columnStyle: ColumnStyle) { + let layout = UICollectionViewFlowLayout() + + switch columnStyle { + case .one: + layout.itemSize = CGSize(width: UIWindow().screen.bounds.width - 20, height: 200) + layout.minimumLineSpacing = 10 + layout.minimumInteritemSpacing = 0 + layout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) + + case .two: + layout.itemSize = CGSize(width: UIWindow().screen.bounds.width / 2 - 15, height: 200) + layout.minimumLineSpacing = 10 + layout.minimumInteritemSpacing = 0 + layout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) + } + + self.collectionViewLayout = layout + } + + func setListViewDelegate(listViewDelegate: ListViewDelegate?) { + self.listViewDelegate = listViewDelegate + } + + func setSelectButtonTapped(selectButtonTapped: Observable) { + input.selectButtonTapped.onNext(selectButtonTapped) + } + + func setRemoveBarButtonTapped(removeBarButtonTapped: Observable) { + input.removeBarButtonTapped.onNext(removeBarButtonTapped) + } + + @objc func startRefresh() { + input.didPullToRefresh.onNext(Void()) + refreshControl?.endRefreshing() + } +} + +extension ListCollectionView: Bindable { + func bind() { + output.genderList + .bind(to: rx.items(cellIdentifier: cellIdentifier, cellType: ListCollectionViewCell.self)) + { index, item, cell in + cell.configure(profileItem: item, isSelected: self.viewModel.isSelected(index: index)) + }.disposed(by: disposeBag) + + output.genderListError + .observe(on: MainScheduler.instance) + .subscribe { [weak self] message in + self?.makeToast(" 리스트를 불러오는데 실패하였습니다. 다시 시도해 주세요 ", withDuration: 2, delay: 1.5) + }.disposed(by: disposeBag) + + // 선택한 리스트 마킹 처리 + output.markItem + .observe(on: MainScheduler.instance) + .subscribe(onNext: { indexPath in + let cell = self.cellForItem(at: indexPath) as! ListCollectionViewCell + cell.itemTapped() + }).disposed(by: disposeBag) + + // 디테일 성별 리스트 화면 이동 + output.moveToDetail + .observe(on: MainScheduler.instance) + .subscribe(onNext: { genderProfileItem in + guard let genderProfileItem = genderProfileItem else { return } + let detailView = DetailView(viewModel: genderProfileItem) + let detailVC = DetailViewController(detailView: detailView) + self.listViewDelegate?.pushDetailViewController(detailVC: detailVC) + }).disposed(by: disposeBag) + + output.cancelSelectedList + .observe(on: MainScheduler.instance) + .subscribe(onNext: { _ in + self.viewModel.removeAllSelectedItems() + self.reloadData() + }).disposed(by: disposeBag) + } +} diff --git a/GenderList/Presentation/ListScene/Views/List/ListCollectionViewCell.swift b/GenderList/Presentation/ListScene/Views/List/ListCollectionViewCell.swift new file mode 100644 index 0000000..d8f11ab --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/List/ListCollectionViewCell.swift @@ -0,0 +1,95 @@ +// +// ListCollectionViewCell.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import Kingfisher + +final class ListCollectionViewCell: UICollectionViewCell { + private let profileImageView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(systemName: "person") + imageView.contentMode = .scaleAspectFit + return imageView + }() + + private let nameLabel: UILabel = { + let label = UILabel() + label.text = "Ronick Kim" + label.font = UIFont.systemFont(ofSize: 13) + label.textColor = .black + + return label + }() + + private let emailLabel: UILabel = { + let label = UILabel() + label.text = "ronick@gmail.com" + label.font = UIFont.systemFont(ofSize: 13) + label.textColor = .black + + return label + }() + + private let checkImage: UIImageView = { + let imageView = UIImageView() + let configuration = UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .large) + imageView.image = UIImage(systemName: "checkmark.circle.fill", withConfiguration: configuration) + + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setUp() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + contentView.addSubview(profileImageView) + profileImageView.snp.makeConstraints { + $0.centerX.top.equalToSuperview() + $0.height.equalTo(125) + } + + contentView.addSubview(nameLabel) + nameLabel.snp.makeConstraints { + $0.top.equalTo(profileImageView.snp.bottom) + $0.centerX.equalTo(profileImageView) + } + + contentView.addSubview(emailLabel) + emailLabel.snp.makeConstraints { + $0.top.equalTo(nameLabel.snp.bottom) + $0.centerX.equalTo(profileImageView) + } + + contentView.addSubview(checkImage) + checkImage.snp.makeConstraints { + $0.top.trailing.equalTo(profileImageView) + } + + checkImage.isHidden = true + } + + func configure(profileItem: GenderProfileItemViewModel, isSelected: Bool) { + let profileImageUrl = URL(string: profileItem.profileUrl) + + profileImageView.kf.indicatorType = .activity + profileImageView.kf.setImage(with: profileImageUrl) + nameLabel.text = profileItem.name + emailLabel.text = profileItem.email + + checkImage.isHidden = !isSelected + } + + func itemTapped() { + checkImage.isHidden = !checkImage.isHidden + } +} diff --git a/GenderList/Presentation/ListScene/Views/List/PageCollectionView.swift b/GenderList/Presentation/ListScene/Views/List/PageCollectionView.swift new file mode 100644 index 0000000..fc27663 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/List/PageCollectionView.swift @@ -0,0 +1,80 @@ +// +// PageCollectionView.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import RxSwift +import RxCocoa + +typealias PageInfo = (prev: Int, current: Int) + +final class PageCollectionView: UICollectionView { + typealias ViewModel = ListPageViewModel + + let cellIdentifier = "ListPageViewCell" + + let viewModel = ViewModel() + let input: ViewModel.Input + let output: ViewModel.Output + + var disposeBag = DisposeBag() + var listViewDelegate: ListViewDelegate? + var selectBarButtonTapped: Observable + var removeBarButtonTapped: Observable + + init(optionButtonTapped: Observable, tabsInitialized: Observable<[String]>, selectBarButtonTapped: Observable, removeBarButtonTapped: Observable) { + + self.input = ViewModel.Input( + tabsInitialized: tabsInitialized + ) + + self.output = viewModel.transform(input: input) + self.selectBarButtonTapped = selectBarButtonTapped + self.removeBarButtonTapped = removeBarButtonTapped + + super.init(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + setUp() + bind() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + layout.minimumLineSpacing = 0 + + collectionViewLayout = layout + isPagingEnabled = true + dataSource = nil + delegate = self + + register(PageCollectionViewCell.self, forCellWithReuseIdentifier: cellIdentifier) + } +} + +extension PageCollectionView: Bindable { + + func bind() { + output.tabs + .bind(to: rx.items(cellIdentifier: cellIdentifier, cellType: PageCollectionViewCell.self)) + { _, item, cell in + cell.configure(columnStyle: self.viewModel.columnStyle, tabName: item) + cell.setListViewDelegate(listViewDelegate: self.listViewDelegate) + cell.setSelectButtonTapped(selectButtonTapped: self.selectBarButtonTapped) + cell.setRemoveBarButtonTapped(removeBarButtonTapped: self.removeBarButtonTapped) + }.disposed(by: disposeBag) + } +} + +extension PageCollectionView: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: UIWindow().screen.bounds.width, height: bounds.height) + } +} diff --git a/GenderList/Presentation/ListScene/Views/List/PageCollectionViewCell.swift b/GenderList/Presentation/ListScene/Views/List/PageCollectionViewCell.swift new file mode 100644 index 0000000..d3bd1e5 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/List/PageCollectionViewCell.swift @@ -0,0 +1,46 @@ +// +// ListPageCollectionViewCell.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import SnapKit +import RxSwift + +final class PageCollectionViewCell: UICollectionViewCell { + var listCollectionView = ListCollectionView() + + override init(frame: CGRect) { + super.init(frame: frame) + setUp() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + contentView.addSubview(listCollectionView) + listCollectionView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + } + + func configure(columnStyle: ColumnStyle, tabName: String) { + listCollectionView.configure(columnStyle: columnStyle, tabName: tabName) + } + + func setListViewDelegate(listViewDelegate: ListViewDelegate?) { + listCollectionView.setListViewDelegate(listViewDelegate: listViewDelegate) + } + + func setSelectButtonTapped(selectButtonTapped: Observable) { + listCollectionView.setSelectButtonTapped(selectButtonTapped: selectButtonTapped) + } + + func setRemoveBarButtonTapped(removeBarButtonTapped: Observable) { + listCollectionView.setRemoveBarButtonTapped(removeBarButtonTapped: removeBarButtonTapped) + } +} diff --git a/GenderList/Presentation/ListScene/Views/List/TabPageView.swift b/GenderList/Presentation/ListScene/Views/List/TabPageView.swift new file mode 100644 index 0000000..ea97ff6 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/List/TabPageView.swift @@ -0,0 +1,108 @@ +// +// TabPageView.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import RxSwift +import RxCocoa + +final class TabPageView: UIView { + private let tabCollectionView: TabCollectionView + private let pageCollectionView: PageCollectionView + + private let columnStyleButton: UIButton = { + let button = UIButton() + let config = UIImage.SymbolConfiguration(pointSize: 50, weight: .bold, scale: .large) + let image = UIImage(systemName: "square.grid.2x2", withConfiguration: config) + + button.setImage(image, for: .normal) + + return button + }() + + let input: ViewModel.Input + let output: ViewModel.Output + let disposeBag = DisposeBag() + + var viewModel = TabListViewModel() + + init(selectBarButtonTapped: Observable, removeBarButtonTapped: Observable) { + // TODO: Enum화 작업 + let tabInitialized = Observable<[String]>.just(["male", "female"]) + + pageCollectionView = PageCollectionView( + optionButtonTapped: columnStyleButton.rx.tap.asObservable(), + tabsInitialized: tabInitialized, + selectBarButtonTapped: selectBarButtonTapped, + removeBarButtonTapped: removeBarButtonTapped + ) + + tabCollectionView = TabCollectionView( + tabsInitialized: tabInitialized + ) + + input = ViewModel.Input( + columnStyleButtonTapped: columnStyleButton.rx.tap.asObservable(), + tabButtonTapped: tabCollectionView.rx.tabButtonTapped, + pageSwiped: pageCollectionView.rx.pageSwiped + ) + + output = viewModel.transform(input: input) + + super.init(frame: .zero) + + setUp() + bind() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + + addSubview(tabCollectionView) + tabCollectionView.snp.makeConstraints { + $0.leading.trailing.top.equalToSuperview() + $0.height.equalTo(70) + } + + addSubview(pageCollectionView) + pageCollectionView.snp.makeConstraints { + $0.leading.trailing.bottom.equalToSuperview() + $0.top.equalTo(tabCollectionView.snp.bottom).offset(30) + } + + addSubview(columnStyleButton) + columnStyleButton.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.bottom.equalToSuperview().inset(20) + } + } + + func setListViewDelegate(listViewDelegate: ListViewDelegate) { + pageCollectionView.listViewDelegate = listViewDelegate + } +} + +extension TabPageView: Bindable { + func bind() { + // 탭 리스트 화면 구성 + output.columnStyle + .bind(to: pageCollectionView.rx.columnStyle) + .disposed(by: disposeBag) + + // 스와이프한 방향의 탭 선택 + output.selectedTab + .bind(to: tabCollectionView.rx.selectedTab) + .disposed(by: disposeBag) + + // 탭 선택시 해당 리스트 화면으로 이동 + output.pageScrollTo + .bind(to: pageCollectionView.rx.selectedPage) + .disposed(by: disposeBag) + } +} diff --git a/GenderList/Presentation/ListScene/Views/Tab/TabCollectionView.swift b/GenderList/Presentation/ListScene/Views/Tab/TabCollectionView.swift new file mode 100644 index 0000000..db0cc42 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/Tab/TabCollectionView.swift @@ -0,0 +1,62 @@ +// +// TabView.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit +import RxSwift +import RxCocoa + +final class TabCollectionView: UICollectionView { + typealias ViewModel = TabViewModel + + let cellIdentifier = "TabViewCell" + + let viewModel = ViewModel() + let input: ViewModel.Input + let output: ViewModel.Output + + var disposeBag = DisposeBag() + + init(tabsInitialized: Observable<[String]>) { + input = ViewModel.Input(tabsInitialized: tabsInitialized) + output = viewModel.transform(input: input) + + super.init(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + setUp() + bind() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + + layout.itemSize = CGSize(width: UIWindow().screen.bounds.width / 2, height: 70) + layout.minimumLineSpacing = 0 + collectionViewLayout = layout + + isScrollEnabled = false + dataSource = nil + delegate = nil + + register(TabCollectionViewCell.self, forCellWithReuseIdentifier: cellIdentifier) + } +} + +extension TabCollectionView: Bindable { + + func bind() { + output.tabs + .bind(to: rx.items(cellIdentifier: cellIdentifier, cellType: TabCollectionViewCell.self)) + { index, item, cell in + cell.setTitle(item, isFirstTab: index == 0) + }.disposed(by: disposeBag) + } +} diff --git a/GenderList/Presentation/ListScene/Views/Tab/TabCollectionViewCell.swift b/GenderList/Presentation/ListScene/Views/Tab/TabCollectionViewCell.swift new file mode 100644 index 0000000..fa2c252 --- /dev/null +++ b/GenderList/Presentation/ListScene/Views/Tab/TabCollectionViewCell.swift @@ -0,0 +1,44 @@ +// +// TabViewCell.swift +// GenderList +// +// Created by Ronick on 6/21/23. +// + +import UIKit + +final class TabCollectionViewCell: UICollectionViewCell { + private let tabTitleLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 15) + label.textColor = .black + + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setUp() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUp() { + contentView.addSubview(tabTitleLabel) + tabTitleLabel.snp.makeConstraints { + $0.center.equalToSuperview() + } + } + + func setTitle(_ title: String, isFirstTab: Bool) { + tabTitleLabel.text = title + backgroundColor = .lightGray + changeTitleColor(to: isFirstTab ? .black : .gray) + } + + func changeTitleColor(to: UIColor) { + tabTitleLabel.textColor = to + } +} diff --git a/GenderList/Presentation/Protocols/Bindable.swift b/GenderList/Presentation/Protocols/Bindable.swift new file mode 100644 index 0000000..df192ce --- /dev/null +++ b/GenderList/Presentation/Protocols/Bindable.swift @@ -0,0 +1,29 @@ +// +// Bindable.swift +// GenderList +// +// Created by Ronick on 6/22/23. +// + +import UIKit +import RxSwift + +/// Rx 이벤트를 바인딩 하는 뷰컨트롤러 전용 프로토콜 +protocol Bindable { + + associatedtype ViewModel: ViewModelType + + /// 비즈니스 로직을 담을 뷰모델 + var viewModel: ViewModel { get } + + /// 입력 이벤트 + var input: ViewModel.Input { get } + + /// 출력 이벤트 + var output: ViewModel.Output { get } + + var disposeBag: DisposeBag { get } + + /// 이벤트를 바인딩합니다. + func bind() +} diff --git a/GenderList/Presentation/Protocols/OutputProtocols/ListViewOutput.swift b/GenderList/Presentation/Protocols/OutputProtocols/ListViewOutput.swift new file mode 100644 index 0000000..05e4acd --- /dev/null +++ b/GenderList/Presentation/Protocols/OutputProtocols/ListViewOutput.swift @@ -0,0 +1,38 @@ +// +// ListViewOutput.swift +// GenderList +// +// Created by RONICK on 2023/07/07. +// + +import RxSwift + +protocol ListViewOutput { + typealias SelectedItemInfo = ( + indexPath: IndexPath, + isSelectMode: Bool + ) + + typealias genderListOutput = ( + genderList: BehaviorSubject<[GenderProfileItemViewModel]>, + genderListError: PublishSubject + ) + + typealias selectionEventOutput = ( + cancelSelectedList: PublishSubject, + markItem: PublishSubject, + moveToDetail: PublishSubject + ) + + var disposeBag: DisposeBag { get } + + var fetchHelper: DefaultGenderListFetchHelper { set get } + + var selectedItemIndexes: [Int] { set get } + + func createGenderListOutput(input: ListViewModel.Input) -> genderListOutput + + func createSelectionEventOutput(input: ListViewModel.Input, genderList: BehaviorSubject<[GenderProfileItemViewModel]>) -> selectionEventOutput + + func removeAllSelectedItems() +} diff --git a/GenderList/Presentation/Protocols/PagenationGenerator.swift b/GenderList/Presentation/Protocols/PagenationGenerator.swift new file mode 100644 index 0000000..dbee7a7 --- /dev/null +++ b/GenderList/Presentation/Protocols/PagenationGenerator.swift @@ -0,0 +1,26 @@ +// +// PagenationGenerator.swift +// GenderList +// +// Created by Ronick on 6/25/23. +// + + +/// 페이지네이션 생성 프로토콜 +protocol PagenationGenerator { + associatedtype Element + associatedtype Fetch + + /// 현재 페이지네이션 상태 + var fetchStatus: FetchStatus { get set } + + /// 페이지네이션 기능을 수행합니다 + /// - Parameters: + /// - fetch: 데이터 패칭을 실행하는 클로저 + /// - onCompletion: 데이터 패칭 이후 실행할 클로저 + /// - onError: 에러 발생 시 실행할 클로저 + mutating func next(fetch: Fetch, onCompletion: ((Element) -> Void)?, onError: ((Error) -> Void)?) + + /// 페이지네이션 데이터를 초기화 합니다 + mutating func reset() +} diff --git a/GenderList/Presentation/Protocols/ViewModelType.swift b/GenderList/Presentation/Protocols/ViewModelType.swift new file mode 100644 index 0000000..8c4a84c --- /dev/null +++ b/GenderList/Presentation/Protocols/ViewModelType.swift @@ -0,0 +1,22 @@ +// +// ViewModelType.swift +// GenderList +// +// Created by Ronick on 6/22/23. +// + +import Foundation +import RxSwift + +/// 뷰모델에서 Input Output 디자인 패턴을 사용하도록 강제하는 프로토콜 +protocol ViewModelType { + associatedtype Input + associatedtype Output + + var disposeBag: DisposeBag { get set } + + /// UI 이벤트가 들어오면 이를 가공한 데이터를 방출합니다 + /// - Parameter input: 들어오는 UI 이벤트들 + /// - Returns: 가공된 데이터 + func transform(input: Input) -> Output +} diff --git a/GenderList/Presentation/Utils/ColumnStyle.swift b/GenderList/Presentation/Utils/ColumnStyle.swift new file mode 100644 index 0000000..01bd1d8 --- /dev/null +++ b/GenderList/Presentation/Utils/ColumnStyle.swift @@ -0,0 +1,12 @@ +// +// ColumnStyle.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +/// 리스트 화면 구성 상태 +enum ColumnStyle { + case one + case two +} diff --git a/GenderList/Presentation/Utils/DefaultPagenationGenerator.swift b/GenderList/Presentation/Utils/DefaultPagenationGenerator.swift new file mode 100644 index 0000000..51d35db --- /dev/null +++ b/GenderList/Presentation/Utils/DefaultPagenationGenerator.swift @@ -0,0 +1,60 @@ +// +// DefaultPagenationGenerator.swift +// GenderList +// +// Created by Ronick on 6/25/23. +// + +import Foundation + +final class DefaultPagenationGenerator: PagenationGenerator { + + typealias Element = Array + + typealias Fetch = ( + _ page: Int, + _ limit: Int, + _ completion: @escaping (_ result: Element) -> Void, + _ error: @escaping (_ error: Error) -> Void + ) -> Void + + var page: Int + let limit: Int + + private var elements: Element = [] + + public var fetchStatus: FetchStatus = .ready + + init(page: Int, limit: Int) { + self.page = page + self.limit = limit + } + + func next(fetch: Fetch, onCompletion: ((Element) -> Void)? = nil, onError: ((Error) -> Void)? = nil) { + fetchStatus = .loading + + fetch(page, limit, { [weak self] items in + guard let self else { return } + self.fetchStatus = .ready + self.elements.append(contentsOf: items) + self.page += 1 + onCompletion?(self.elements) + }, { error in + onError?(error) + }) + } + + func reset() { + page = 1 + self.elements.removeAll() + } + + func remove(indexes: [Int]) -> Element { + elements = elements + .enumerated() + .filter { !indexes.contains($0.offset) } + .map { $0.element } + + return elements + } +} diff --git a/GenderList/Presentation/Utils/Extensions/ListPageView+Rx.swift b/GenderList/Presentation/Utils/Extensions/ListPageView+Rx.swift new file mode 100644 index 0000000..b91f037 --- /dev/null +++ b/GenderList/Presentation/Utils/Extensions/ListPageView+Rx.swift @@ -0,0 +1,49 @@ +// +// ListPageView+Rx.swift +// GenderList +// +// Created by Ronick on 6/24/23. +// + +import UIKit +import RxSwift + +extension Reactive where Base: PageCollectionView { + /// 페이지 스와이프 Observable + var pageSwiped: Observable { + base.rx.didScroll + .map { + let currentPage = base.visibleIndexPath?.row ?? 0 + let previousPage = base.viewModel.pageInfo.prev + + if base.viewModel.pageInfo.current != currentPage { + base.viewModel.pageInfo.prev = base.viewModel.pageInfo.current + base.viewModel.pageInfo.current = currentPage + } + + return (prev: previousPage, current: currentPage) + } + } + + //TODO: 수정 필요 + /// 리스트 화면 구성 전환 Binder + var columnStyle: Binder { + Binder(self.base) { listPageView, columnStyle in + listPageView.viewModel.columnStyle = columnStyle + + let cell_1 = listPageView.cellForItem(at: IndexPath(row: 0, section: 0)) as? PageCollectionViewCell + let cell_2 = listPageView.cellForItem(at: IndexPath(row: 1, section: 0)) as? PageCollectionViewCell + + cell_1?.listCollectionView.setColumnStyle(columnStyle: columnStyle) + cell_2?.listCollectionView.setColumnStyle(columnStyle: columnStyle) + } + } + + /// 선택한 페이지로 스크롤 이동 Binder + var selectedPage: Binder { + Binder(self.base) { ListPageView, pageIndex in + let indexPath = IndexPath(row: pageIndex, section: 0) + ListPageView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true) + } + } +} diff --git a/GenderList/Presentation/Utils/Extensions/TabView+Rx.swift b/GenderList/Presentation/Utils/Extensions/TabView+Rx.swift new file mode 100644 index 0000000..39c650f --- /dev/null +++ b/GenderList/Presentation/Utils/Extensions/TabView+Rx.swift @@ -0,0 +1,38 @@ +// +// TabView+Rx.swift +// GenderList +// +// Created by Ronick on 6/26/23. +// + +import UIKit +import RxSwift + +extension Reactive where Base: TabCollectionView { + /// 탭 버튼 클릭 Observable + var tabButtonTapped: Observable { + base.rx.itemSelected + .map { + let currentPage = $0.row + let previousPage = base.viewModel.pageInfo.prev + + if base.viewModel.pageInfo.current != currentPage { + base.viewModel.pageInfo.prev = base.viewModel.pageInfo.current + base.viewModel.pageInfo.current = currentPage + } + + return (prev: previousPage, current: currentPage) + } + } + + /// 탭 버튼 선택 처리 Binder + var selectedTab: Binder { + Binder(self.base) { tabView, pageInfo in + let prevCell = tabView.cellForItem(at: IndexPath(row: pageInfo.prev, section: 0)) as? TabCollectionViewCell + prevCell?.changeTitleColor(to: .gray) + + let currentCell = tabView.cellForItem(at: IndexPath(row: pageInfo.current, section: 0)) as? TabCollectionViewCell + currentCell?.changeTitleColor(to: .black) + } + } +} diff --git a/GenderList/Presentation/Utils/Extensions/UICollectionView+Extension.swift b/GenderList/Presentation/Utils/Extensions/UICollectionView+Extension.swift new file mode 100644 index 0000000..4a0f7d8 --- /dev/null +++ b/GenderList/Presentation/Utils/Extensions/UICollectionView+Extension.swift @@ -0,0 +1,18 @@ +// +// UICollectionView+Extension.swift +// GenderList +// +// Created by Ronick on 6/22/23. +// + +import UIKit + +extension UICollectionView { + var visibleIndexPath: IndexPath? { + let visibleRect = CGRect(origin: contentOffset, size: bounds.size) + let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY) + let visibleIndexPath = indexPathForItem(at: visiblePoint) + + return visibleIndexPath + } +} diff --git a/GenderList/Presentation/Utils/Extensions/UICollectionView+Rx.swift b/GenderList/Presentation/Utils/Extensions/UICollectionView+Rx.swift new file mode 100644 index 0000000..7a6f2a8 --- /dev/null +++ b/GenderList/Presentation/Utils/Extensions/UICollectionView+Rx.swift @@ -0,0 +1,30 @@ +// +// UICollectionView+Rx.swift +// GenderList +// +// Created by Ronick on 6/25/23. +// + +import UIKit +import RxSwift + +extension Reactive where Base: UICollectionView { + /// 스크롤을 밑으로 끝까지 내렸을 경우의 Observable + var scrolledToBottom: Observable { + base.rx.didScroll.flatMap { + Observable.create { observer -> Disposable in + let contentOffsetY = base.contentOffset.y + let contentHeight = base.contentSize.height + let height = base.frame.height + + if contentOffsetY > contentHeight - height { + observer.onNext(()) + } + + observer.onCompleted() + + return Disposables.create() + } + } + } +} diff --git a/GenderList/Presentation/Utils/Extensions/UIView+Extension.swift b/GenderList/Presentation/Utils/Extensions/UIView+Extension.swift new file mode 100644 index 0000000..8d05cc1 --- /dev/null +++ b/GenderList/Presentation/Utils/Extensions/UIView+Extension.swift @@ -0,0 +1,39 @@ +// +// UIView+Extensions.swift +// GenderList +// +// Created by RONICK on 2023/07/04. +// + +import UIKit +import SnapKit + +extension UIView { + func makeToast(_ message : String, withDuration: Double, delay: Double) { + let toastLabel = UILabel() + toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.7) + toastLabel.textColor = UIColor.white + toastLabel.font = UIFont.systemFont(ofSize: 14.0) + toastLabel.textAlignment = .center + toastLabel.text = message + toastLabel.alpha = 0.0 + toastLabel.layer.cornerRadius = 8 + toastLabel.clipsToBounds = true + + addSubview(toastLabel) + toastLabel.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.bottom.equalToSuperview().offset(600) + } + + UIView.animate(withDuration: 0.5, delay: 1, options: .curveEaseOut, animations: { + toastLabel.alpha = 1.0 + }, completion: { (isCompleted) in + UIView.animate(withDuration: withDuration, delay: delay, options: .curveEaseOut, animations: { + toastLabel.alpha = 0.0 + }, completion: {(isCompleted) in + toastLabel.removeFromSuperview() + }) + }) + } +} diff --git a/GenderList/Presentation/Utils/FetchStatus.swift b/GenderList/Presentation/Utils/FetchStatus.swift new file mode 100644 index 0000000..16781fe --- /dev/null +++ b/GenderList/Presentation/Utils/FetchStatus.swift @@ -0,0 +1,12 @@ +// +// FetchStatus.swift +// GenderList +// +// Created by Ronick on 6/26/23. +// + +/// 페이지네이션 패치 상태 +enum FetchStatus { + case ready + case loading +} diff --git a/GenderList/Presentation/Utils/GenderListFetchHelper.swift b/GenderList/Presentation/Utils/GenderListFetchHelper.swift new file mode 100644 index 0000000..74700a3 --- /dev/null +++ b/GenderList/Presentation/Utils/GenderListFetchHelper.swift @@ -0,0 +1,70 @@ +// +// GenderListFetchHelper.swift +// GenderList +// +// Created by Ronick on 6/26/23. +// + +import RxSwift + +protocol GenderListPagenationFetchable { + associatedtype Element + + var disposeBag: DisposeBag { get } + + func fetch(genderType: String) -> Observable<[Element]> +} + +struct DefaultGenderListFetchHelper: GenderListPagenationFetchable { + typealias Element = GenderProfileItemViewModel + + private let pagenationGenerator = DefaultPagenationGenerator(page: 1, limit: 40) + private let genderListUsecase: GenderListUsecase + + var disposeBag = DisposeBag() + + private var seed: String { + "GenderList" + } + + public var fetchStatus: FetchStatus { + pagenationGenerator.fetchStatus + } + + init(usecase: GenderListUsecase) { + self.genderListUsecase = usecase + } + + func fetch(genderType: String) -> Observable<[Element]> { + let result = PublishSubject<[Element]>() + + self.pagenationGenerator.next(fetch: { page, limit, completion, error in + Task { + do { + let query = GenderListQuery(page: page, results: limit, seed: self.seed) + let genderList = try await self.genderListUsecase.get(genderListQuery: query) + .filter { $0.gender == genderType } + + completion(genderList) + } catch(let e) { + error(e) + } + } + }, onCompletion: { + result.onNext($0) + }, onError: { + result.onError($0) + }) + + return result.asObservable() + } + + func reset(genderType: String) -> Observable<[Element]> { + pagenationGenerator.reset() + return fetch(genderType: genderType) + } + + func remove(at indexes: [Int]) -> [Element] { + pagenationGenerator.remove(indexes: indexes) + } +} diff --git a/Podfile b/Podfile index 897bc76..ddac487 100644 --- a/Podfile +++ b/Podfile @@ -1,18 +1,18 @@ # Uncomment the next line to define a global platform for your project # platform :ios, '9.0' -target 'Bunjang' do +target 'GenderList' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! - # Pods for Bunjang + # Pods for GenderList - pod 'RxSwift', '~> 6.0' + pod 'RxSwift', '~> 6.5' pod 'RxCocoa', '~> 6.0' pod 'SnapKit', '~> 5.0.0' - pod 'Alamofire', '~> 5.0.0' + pod 'Alamofire', '~> 5.5.0' pod 'Kingfisher', '~> 6.3.1' end diff --git a/Podfile.lock b/Podfile.lock index 787fe51..ddabf3b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Alamofire (5.0.5) + - Alamofire (5.5.0) - Kingfisher (6.3.1) - RxCocoa (6.5.0): - RxRelay (= 6.5.0) @@ -10,10 +10,10 @@ PODS: - SnapKit (5.0.1) DEPENDENCIES: - - Alamofire (~> 5.0.0) + - Alamofire (~> 5.5.0) - Kingfisher (~> 6.3.1) - RxCocoa (~> 6.0) - - RxSwift (~> 6.0) + - RxSwift (~> 6.5) - SnapKit (~> 5.0.0) SPEC REPOS: @@ -26,13 +26,13 @@ SPEC REPOS: - SnapKit SPEC CHECKSUMS: - Alamofire: df2f8f826963b08b9a870791ad48e07a10090b2e + Alamofire: 1c4fb5369c3fe93d2857c780d8bbe09f06f97e7c Kingfisher: 016c8b653a35add51dd34a3aba36b580041acc74 RxCocoa: 94f817b71c07517321eb4f9ad299112ca8af743b RxRelay: 1de1523e604c72b6c68feadedd1af3b1b4d0ecbd RxSwift: 5710a9e6b17f3c3d6e40d6e559b9fa1e813b2ef8 SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb -PODFILE CHECKSUM: 1b558f44619140af2d32ff330f92dff687a62721 +PODFILE CHECKSUM: c41a595eb47fc44e36c18a98ff4debc2ff429de8 -COCOAPODS: 1.11.3 +COCOAPODS: 1.14.2 diff --git a/Pods/Alamofire/LICENSE b/Pods/Alamofire/LICENSE index ccafad5..6b4d719 100644 --- a/Pods/Alamofire/LICENSE +++ b/Pods/Alamofire/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) +Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/Alamofire/README.md b/Pods/Alamofire/README.md index 4f4c093..c220900 100644 --- a/Pods/Alamofire/README.md +++ b/Pods/Alamofire/README.md @@ -1,12 +1,12 @@ -![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/Alamofire/Alamofire/master/alamofire.png) +![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/Alamofire/Alamofire/master/Resources/AlamofireLogo.png) -[![Build Status](https://github.com/Alamofire/Alamofire/workflows/Alamofire%20CI/badge.svg?branch=master)](https://github.com/Alamofire/Alamofire/actions) -[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Alamofire.svg)](https://img.shields.io/cocoapods/v/Alamofire.svg) -[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Platform](https://img.shields.io/cocoapods/p/Alamofire.svg?style=flat)](https://alamofire.github.io/Alamofire) -[![Twitter](https://img.shields.io/badge/twitter-@AlamofireSF-blue.svg?style=flat)](https://twitter.com/AlamofireSF) -[![Gitter](https://badges.gitter.im/Alamofire/Alamofire.svg)](https://gitter.im/Alamofire/Alamofire?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[![Open Source Helpers](https://www.codetriage.com/alamofire/alamofire/badges/users.svg)](https://www.codetriage.com/alamofire/alamofire) +[![Swift](https://img.shields.io/badge/Swift-5.3_5.4_5.5-orange?style=flat-square)](https://img.shields.io/badge/Swift-5.3_5.4_5.5-Orange?style=flat-square) +[![Platforms](https://img.shields.io/badge/Platforms-macOS_iOS_tvOS_watchOS_Linux_Windows-yellowgreen?style=flat-square)](https://img.shields.io/badge/Platforms-macOS_iOS_tvOS_watchOS_Linux_Windows-Green?style=flat-square) +[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Alamofire.svg?style=flat-square)](https://img.shields.io/cocoapods/v/Alamofire.svg) +[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat-square)](https://github.com/Carthage/Carthage) +[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat-square)](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat-square) +[![Twitter](https://img.shields.io/badge/twitter-@AlamofireSF-blue.svg?style=flat-square)](https://twitter.com/AlamofireSF) +[![Swift Forums](https://img.shields.io/badge/Swift_Forums-Alamofire-orange?style=flat-square)](https://forums.swift.org/c/related-projects/alamofire/37) Alamofire is an HTTP networking library written in Swift. @@ -16,16 +16,18 @@ Alamofire is an HTTP networking library written in Swift. - [Migration Guides](#migration-guides) - [Communication](#communication) - [Installation](#installation) +- [Contributing](#contributing) - [Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#using-alamofire) - - [**Introduction -**](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#introduction) [Making Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#making-requests), [Response Handling](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-handling), [Response Validation](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-validation), [Response Caching](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-caching) - - **HTTP -** [HTTP Methods](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-methods), [Parameters and Parameter Encoder](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md##request-parameters-and-parameter-encoders), [HTTP Headers](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-headers), [Authentication](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#authentication) - - **Large Data -** [Downloading Data to a File](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#downloading-data-to-a-file), [Uploading Data to a Server](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#uploading-data-to-a-server) - - **Tools -** [Statistical Metrics](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#statistical-metrics), [cURL Command Output](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#curl-command-output) + - [**Introduction -**](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#introduction) [Making Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#making-requests), [Response Handling](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-handling), [Response Validation](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-validation), [Response Caching](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-caching) + - **HTTP -** [HTTP Methods](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-methods), [Parameters and Parameter Encoder](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md##request-parameters-and-parameter-encoders), [HTTP Headers](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-headers), [Authentication](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#authentication) + - **Large Data -** [Downloading Data to a File](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#downloading-data-to-a-file), [Uploading Data to a Server](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#uploading-data-to-a-server) + - **Tools -** [Statistical Metrics](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#statistical-metrics), [cURL Command Output](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#curl-command-output) - [Advanced Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md) - - **URL Session -** [Session Manager](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#session), [Session Delegate](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#sessiondelegate), [Request](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#request) - - **Routing -** [Routing Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#routing-requests), [Adapting and Retrying Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests) - - **Model Objects -** [Custom Response Serialization](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#custom-response-serialization) - - **Connection -** [Security](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#security), [Network Reachability](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#network-reachability) + - **URL Session -** [Session Manager](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#session), [Session Delegate](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#sessiondelegate), [Request](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#request) + - **Routing -** [Routing Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#routing-requests), [Adapting and Retrying Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests-with-requestinterceptor) + - **Model Objects -** [Custom Response Handlers](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#customizing-response-handlers) + - **Advanced Concurrency -** [Swift Concurrency](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#using-alamofire-with-swift-concurrency) and [Combine](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#using-alamofire-with-combine) + - **Connection -** [Security](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#security), [Network Reachability](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#network-reachability) - [Open Radars](#open-radars) - [FAQ](#faq) - [Credits](#credits) @@ -35,10 +37,12 @@ Alamofire is an HTTP networking library written in Swift. ## Features - [x] Chainable Request / Response Methods +- [x] Swift Concurrency Support Back to iOS 13, macOS 10.15, tvOS 13, and watchOS 6. +- [x] Combine Support - [x] URL / JSON Parameter Encoding - [x] Upload File / Data / Stream / MultipartFormData - [x] Download File using Request or Resume Data -- [x] Authentication with URLCredential +- [x] Authentication with `URLCredential` - [x] HTTP Response Validation - [x] Upload and Download Progress Closures with Progress - [x] cURL Command Output @@ -52,14 +56,26 @@ Alamofire is an HTTP networking library written in Swift. In order to keep Alamofire focused specifically on core networking implementations, additional component libraries have been created by the [Alamofire Software Foundation](https://github.com/Alamofire/Foundation) to bring additional functionality to the Alamofire ecosystem. -- [AlamofireImage](https://github.com/Alamofire/AlamofireImage) - An image library including image response serializers, `UIImage` and `UIImageView` extensions, custom image filters, an auto-purging in-memory cache and a priority-based image downloading system. +- [AlamofireImage](https://github.com/Alamofire/AlamofireImage) - An image library including image response serializers, `UIImage` and `UIImageView` extensions, custom image filters, an auto-purging in-memory cache, and a priority-based image downloading system. - [AlamofireNetworkActivityIndicator](https://github.com/Alamofire/AlamofireNetworkActivityIndicator) - Controls the visibility of the network activity indicator on iOS using Alamofire. It contains configurable delay timers to help mitigate flicker and can support `URLSession` instances not managed by Alamofire. ## Requirements -- iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ -- Xcode 10.2+ -- Swift 5+ +| Platform | Minimum Swift Version | Installation | Status | +| --- | --- | --- | --- | +| iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ | 5.3 | [CocoaPods](#cocoapods), [Carthage](#carthage), [Swift Package Manager](#swift-package-manager), [Manual](#manually) | Fully Tested | +| Linux | Latest Only | [Swift Package Manager](#swift-package-manager) | Building But Unsupported | +| Windows | Latest Only | [Swift Package Manager](#swift-package-manager) | Building But Unsupported | + +#### Known Issues on Linux and Windows + +Alamofire builds on Linux and Windows but there are missing features and many issues in the underlying `swift-corelibs-foundation` that prevent full functionality and may cause crashes. These include: +- `ServerTrustManager` and associated certificate functionality is unavailable, so there is no certificate pinning and no client certificate support. +- Various methods of HTTP authentication may crash, including HTTP Basic and HTTP Digest. Crashes may occur if responses contain server challenges. +- Cache control through `CachedResponseHandler` and associated APIs is unavailable, as the underlying delegate methods aren't called. +- `URLSessionTaskMetrics` are never gathered. + +Due to these issues, Alamofire is unsupported on Linux and Windows. Please report any crashes to the [Swift bug reporter](https://bugs.swift.org). ## Migration Guides @@ -75,7 +91,6 @@ In order to keep Alamofire focused specifically on core networking implementatio - If you'd like to **discuss Alamofire best practices**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). - If you'd like to **discuss a feature request**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). - If you **found a bug**, open an issue here on GitHub and follow the guide. The more detail the better! -- If you **want to contribute**, submit a pull request! ## Installation @@ -84,7 +99,7 @@ In order to keep Alamofire focused specifically on core networking implementatio [CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`: ```ruby -pod 'Alamofire', '~> 5.0' +pod 'Alamofire', '~> 5.5' ``` ### Carthage @@ -92,7 +107,7 @@ pod 'Alamofire', '~> 5.0' [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Alamofire into your Xcode project using Carthage, specify it in your `Cartfile`: ```ogdl -github "Alamofire/Alamofire" ~> 5.0 +github "Alamofire/Alamofire" ~> 5.5 ``` ### Swift Package Manager @@ -103,7 +118,7 @@ Once you have your Swift package set up, adding Alamofire as a dependency is as ```swift dependencies: [ - .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.0.0")) + .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.5.0")) ] ``` @@ -139,20 +154,23 @@ If you prefer not to use any of the aforementioned dependency managers, you can - 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`. + > You can verify which one you selected by inspecting the build log for your project. The build target for `Alamofire` will be listed as `Alamofire iOS`, `Alamofire macOS`, `Alamofire tvOS`, or `Alamofire watchOS`. - And that's it! > The `Alamofire.framework` is 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. +## Contributing + +Before contributing to Alamofire, please read the instructions detailed in our [contribution guide](https://github.com/Alamofire/Alamofire/blob/master/CONTRIBUTING.md). + ## Open Radars The following radars have some effect on the current implementation of Alamofire. -- [`rdar://21349340`](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in test case +- [`rdar://21349340`](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in the test case - `rdar://26870455` - Background URL Session Configurations do not work in the simulator - `rdar://26849668` - Some URLProtocol APIs do not properly handle `URLRequest` -- `FB7624529` - `urlSession(_:task:didFinishCollecting:)` never called on watchOS ## Resolved Radars @@ -162,10 +180,8 @@ The following radars have been resolved over time after being filed against the - (Resolved): 9/1/17 in Xcode 9 beta 6. - [`rdar://36082113`](http://openradar.appspot.com/radar?id=4942308441063424) - `URLSessionTaskMetrics` failing to link on watchOS 3.0+ - (Resolved): Just add `CFNetwork` to your linked frameworks. - -## Workarounds - -- Collection of `URLSessionTaskMetrics` is currently disabled on watchOS due to `FB7624529`. +- `FB7624529` - `urlSession(_:task:didFinishCollecting:)` never called on watchOS + - (Resolved): Metrics now collected on watchOS 7+. ## FAQ @@ -184,7 +200,7 @@ If you believe you have identified a security vulnerability with Alamofire, you ## Donations The [ASF](https://github.com/Alamofire/Foundation#members) is looking to raise money to officially stay registered as a federal non-profit organization. -Registering will allow us members to gain some legal protections and also allow us to put donations to use, tax-free. +Registering will allow Foundation members to gain some legal protections and also allow us to put donations to use, tax-free. Donating to the ASF will enable us to: - Pay our yearly legal fees to keep the non-profit in good status @@ -200,6 +216,12 @@ Any amount you can donate today to help us reach our goal would be greatly appre [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W34WPEE74APJQ) +## Supporters + +[MacStadium](https://macstadium.com) provides Alamofire with a free, hosted Mac mini. + +![Powered by MacStadium](https://raw.githubusercontent.com/Alamofire/Alamofire/master/Resources/MacStadiumLogo.png) + ## License Alamofire is released under the MIT license. [See LICENSE](https://github.com/Alamofire/Alamofire/blob/master/LICENSE) for details. diff --git a/Pods/Alamofire/Source/AFError.swift b/Pods/Alamofire/Source/AFError.swift index 8ab282c..8cd60c7 100644 --- a/Pods/Alamofire/Source/AFError.swift +++ b/Pods/Alamofire/Source/AFError.swift @@ -57,6 +57,15 @@ public enum AFError: Error { case inputStreamReadFailed(error: Error) } + /// Represents unexpected input stream length that occur when encoding the `MultipartFormData`. Instances will be + /// embedded within an `AFError.multipartEncodingFailed` `.inputStreamReadFailed` case. + public struct UnexpectedInputStreamLength: Error { + /// The expected byte count to read. + public var bytesExpected: UInt64 + /// The actual byte count read. + public var bytesRead: UInt64 + } + /// The underlying reason the `.parameterEncodingFailed` error occurred. public enum ParameterEncodingFailureReason { /// The `URLRequest` did not have a `URL` to encode. @@ -120,6 +129,7 @@ public enum AFError: Error { case invalidEmptyResponse(type: String) } + #if !(os(Linux) || os(Windows)) /// Underlying reason a server trust evaluation error occurred. public enum ServerTrustFailureReason { /// The output of a server trust evaluation. @@ -169,6 +179,7 @@ public enum AFError: Error { /// Custom server trust evaluation failed due to the associated `Error`. case customEvaluationFailed(error: Error) } + #endif /// The underlying reason the `.urlRequestValidationFailed` public enum URLRequestValidationFailureReason { @@ -200,8 +211,10 @@ public enum AFError: Error { case responseValidationFailed(reason: ResponseValidationFailureReason) /// Response serialization failed. case responseSerializationFailed(reason: ResponseSerializationFailureReason) + #if !(os(Linux) || os(Windows)) /// `ServerTrustEvaluating` instance threw an error during trust evaluation. case serverTrustEvaluationFailed(reason: ServerTrustFailureReason) + #endif /// `Session` which issued the `Request` was deinitialized, most likely because its reference went out of scope. case sessionDeinitialized /// `Session` was explicitly invalidated, possibly with the `Error` produced by the underlying `URLSession`. @@ -215,7 +228,7 @@ public enum AFError: Error { extension Error { /// Returns the instance cast as an `AFError`. public var asAFError: AFError? { - return self as? AFError + self as? AFError } /// Returns the instance cast as an `AFError`. If casting fails, a `fatalError` with the specified `message` is thrown. @@ -228,7 +241,7 @@ extension Error { /// Casts the instance as `AFError` or returns `defaultAFError` func asAFError(or defaultAFError: @autoclosure () -> AFError) -> AFError { - return self as? AFError ?? defaultAFError() + self as? AFError ?? defaultAFError() } } @@ -301,12 +314,14 @@ extension AFError { return false } + #if !(os(Linux) || os(Windows)) /// Returns whether the instance is `.serverTrustEvaluationFailed`. When `true`, the `underlyingError` property will /// contain the associated value. public var isServerTrustEvaluationError: Bool { if case .serverTrustEvaluationFailed = self { return true } return false } + #endif /// Returns whether the instance is `requestRetryFailed`. When `true`, the `underlyingError` property will /// contain the associated value. @@ -378,8 +393,10 @@ extension AFError { return reason.underlyingError case let .responseSerializationFailed(reason): return reason.underlyingError + #if !(os(Linux) || os(Windows)) case let .serverTrustEvaluationFailed(reason): return reason.underlyingError + #endif case let .sessionInvalidated(error): return error case let .createUploadableFailed(error): @@ -433,6 +450,13 @@ extension AFError { guard case let .downloadedFileMoveFailed(_, _, destination) = self else { return nil } return destination } + + #if !(os(Linux) || os(Windows)) + /// The download resume data of any underlying network error. Only produced by `DownloadRequest`s. + public var downloadResumeData: Data? { + (underlyingError as? URLError)?.userInfo[NSURLSessionDownloadTaskResumeData] as? Data + } + #endif } extension AFError.ParameterEncodingFailureReason { @@ -586,6 +610,7 @@ extension AFError.ResponseSerializationFailureReason { } } +#if !(os(Linux) || os(Windows)) extension AFError.ServerTrustFailureReason { var output: AFError.ServerTrustFailureReason.Output? { switch self { @@ -628,6 +653,7 @@ extension AFError.ServerTrustFailureReason { } } } +#endif // MARK: - Error Descriptions @@ -662,8 +688,10 @@ extension AFError: LocalizedError { """ case let .sessionInvalidated(error): return "Session was invalidated with error: \(error?.localizedDescription ?? "No description.")" + #if !(os(Linux) || os(Windows)) case let .serverTrustEvaluationFailed(reason): return "Server trust evaluation failed due to reason: \(reason.localizedDescription)" + #endif case let .urlRequestValidationFailed(reason): return "URLRequest validation failed due to reason: \(reason.localizedDescription)" case let .createUploadableFailed(error): @@ -794,6 +822,7 @@ extension AFError.ResponseValidationFailureReason { } } +#if !(os(Linux) || os(Windows)) extension AFError.ServerTrustFailureReason { var localizedDescription: String { switch self { @@ -826,6 +855,7 @@ extension AFError.ServerTrustFailureReason { } } } +#endif extension AFError.URLRequestValidationFailureReason { var localizedDescription: String { diff --git a/Pods/Alamofire/Source/Alamofire.swift b/Pods/Alamofire/Source/Alamofire.swift index b63f8f5..0d3f5dc 100644 --- a/Pods/Alamofire/Source/Alamofire.swift +++ b/Pods/Alamofire/Source/Alamofire.swift @@ -1,7 +1,7 @@ // // Alamofire.swift // -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) +// Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,8 +22,14 @@ // THE SOFTWARE. // +import Dispatch +import Foundation +#if canImport(FoundationNetworking) +@_exported import FoundationNetworking +#endif + /// Reference to `Session.default` for quick bootstrapping and examples. public let AF = Session.default /// Current Alamofire version. Necessary since SPM doesn't use dynamic libraries. Plus this will be more accurate. -let version = "5.0.5" +let version = "5.5.0" diff --git a/Pods/Alamofire/Source/AlamofireExtended.swift b/Pods/Alamofire/Source/AlamofireExtended.swift index cb9eccf..280c6de 100644 --- a/Pods/Alamofire/Source/AlamofireExtended.swift +++ b/Pods/Alamofire/Source/AlamofireExtended.swift @@ -46,16 +46,16 @@ public protocol AlamofireExtended { var af: AlamofireExtension { get set } } -public extension AlamofireExtended { +extension AlamofireExtended { /// Static Alamofire extension point. - static var af: AlamofireExtension.Type { - get { return AlamofireExtension.self } + public static var af: AlamofireExtension.Type { + get { AlamofireExtension.self } set {} } /// Instance Alamofire extension point. - var af: AlamofireExtension { - get { return AlamofireExtension(self) } + public var af: AlamofireExtension { + get { AlamofireExtension(self) } set {} } } diff --git a/Pods/Alamofire/Source/AuthenticationInterceptor.swift b/Pods/Alamofire/Source/AuthenticationInterceptor.swift new file mode 100644 index 0000000..c3a3f31 --- /dev/null +++ b/Pods/Alamofire/Source/AuthenticationInterceptor.swift @@ -0,0 +1,403 @@ +// +// AuthenticationInterceptor.swift +// +// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) +// +// 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 + +/// Types adopting the `AuthenticationCredential` protocol can be used to authenticate `URLRequest`s. +/// +/// One common example of an `AuthenticationCredential` is an OAuth2 credential containing an access token used to +/// authenticate all requests on behalf of a user. The access token generally has an expiration window of 60 minutes +/// which will then require a refresh of the credential using the refresh token to generate a new access token. +public protocol AuthenticationCredential { + /// Whether the credential requires a refresh. This property should always return `true` when the credential is + /// expired. It is also wise to consider returning `true` when the credential will expire in several seconds or + /// minutes depending on the expiration window of the credential. + /// + /// For example, if the credential is valid for 60 minutes, then it would be wise to return `true` when the + /// credential is only valid for 5 minutes or less. That ensures the credential will not expire as it is passed + /// around backend services. + var requiresRefresh: Bool { get } +} + +// MARK: - + +/// Types adopting the `Authenticator` protocol can be used to authenticate `URLRequest`s with an +/// `AuthenticationCredential` as well as refresh the `AuthenticationCredential` when required. +public protocol Authenticator: AnyObject { + /// The type of credential associated with the `Authenticator` instance. + associatedtype Credential: AuthenticationCredential + + /// Applies the `Credential` to the `URLRequest`. + /// + /// In the case of OAuth2, the access token of the `Credential` would be added to the `URLRequest` as a Bearer + /// token to the `Authorization` header. + /// + /// - Parameters: + /// - credential: The `Credential`. + /// - urlRequest: The `URLRequest`. + func apply(_ credential: Credential, to urlRequest: inout URLRequest) + + /// Refreshes the `Credential` and executes the `completion` closure with the `Result` once complete. + /// + /// Refresh can be called in one of two ways. It can be called before the `Request` is actually executed due to + /// a `requiresRefresh` returning `true` during the adapt portion of the `Request` creation process. It can also + /// be triggered by a failed `Request` where the authentication server denied access due to an expired or + /// invalidated access token. + /// + /// In the case of OAuth2, this method would use the refresh token of the `Credential` to generate a new + /// `Credential` using the authentication service. Once complete, the `completion` closure should be called with + /// the new `Credential`, or the error that occurred. + /// + /// In general, if the refresh call fails with certain status codes from the authentication server (commonly a 401), + /// the refresh token in the `Credential` can no longer be used to generate a valid `Credential`. In these cases, + /// you will need to reauthenticate the user with their username / password. + /// + /// Please note, these are just general examples of common use cases. They are not meant to solve your specific + /// authentication server challenges. Please work with your authentication server team to ensure your + /// `Authenticator` logic matches their expectations. + /// + /// - Parameters: + /// - credential: The `Credential` to refresh. + /// - session: The `Session` requiring the refresh. + /// - completion: The closure to be executed once the refresh is complete. + func refresh(_ credential: Credential, for session: Session, completion: @escaping (Result) -> Void) + + /// Determines whether the `URLRequest` failed due to an authentication error based on the `HTTPURLResponse`. + /// + /// If the authentication server **CANNOT** invalidate credentials after they are issued, then simply return `false` + /// for this method. If the authentication server **CAN** invalidate credentials due to security breaches, then you + /// will need to work with your authentication server team to understand how to identify when this occurs. + /// + /// In the case of OAuth2, where an authentication server can invalidate credentials, you will need to inspect the + /// `HTTPURLResponse` or possibly the `Error` for when this occurs. This is commonly handled by the authentication + /// server returning a 401 status code and some additional header to indicate an OAuth2 failure occurred. + /// + /// It is very important to understand how your authentication server works to be able to implement this correctly. + /// For example, if your authentication server returns a 401 when an OAuth2 error occurs, and your downstream + /// service also returns a 401 when you are not authorized to perform that operation, how do you know which layer + /// of the backend returned you a 401? You do not want to trigger a refresh unless you know your authentication + /// server is actually the layer rejecting the request. Again, work with your authentication server team to understand + /// how to identify an OAuth2 401 error vs. a downstream 401 error to avoid endless refresh loops. + /// + /// - Parameters: + /// - urlRequest: The `URLRequest`. + /// - response: The `HTTPURLResponse`. + /// - error: The `Error`. + /// + /// - Returns: `true` if the `URLRequest` failed due to an authentication error, `false` otherwise. + func didRequest(_ urlRequest: URLRequest, with response: HTTPURLResponse, failDueToAuthenticationError error: Error) -> Bool + + /// Determines whether the `URLRequest` is authenticated with the `Credential`. + /// + /// If the authentication server **CANNOT** invalidate credentials after they are issued, then simply return `true` + /// for this method. If the authentication server **CAN** invalidate credentials due to security breaches, then + /// read on. + /// + /// When an authentication server can invalidate credentials, it means that you may have a non-expired credential + /// that appears to be valid, but will be rejected by the authentication server when used. Generally when this + /// happens, a number of requests are all sent when the application is foregrounded, and all of them will be + /// rejected by the authentication server in the order they are received. The first failed request will trigger a + /// refresh internally, which will update the credential, and then retry all the queued requests with the new + /// credential. However, it is possible that some of the original requests will not return from the authentication + /// server until the refresh has completed. This is where this method comes in. + /// + /// When the authentication server rejects a credential, we need to check to make sure we haven't refreshed the + /// credential while the request was in flight. If it has already refreshed, then we don't need to trigger an + /// additional refresh. If it hasn't refreshed, then we need to refresh. + /// + /// Now that it is understood how the result of this method is used in the refresh lifecyle, let's walk through how + /// to implement it. You should return `true` in this method if the `URLRequest` is authenticated in a way that + /// matches the values in the `Credential`. In the case of OAuth2, this would mean that the Bearer token in the + /// `Authorization` header of the `URLRequest` matches the access token in the `Credential`. If it matches, then we + /// know the `Credential` was used to authenticate the `URLRequest` and should return `true`. If the Bearer token + /// did not match the access token, then you should return `false`. + /// + /// - Parameters: + /// - urlRequest: The `URLRequest`. + /// - credential: The `Credential`. + /// + /// - Returns: `true` if the `URLRequest` is authenticated with the `Credential`, `false` otherwise. + func isRequest(_ urlRequest: URLRequest, authenticatedWith credential: Credential) -> Bool +} + +// MARK: - + +/// Represents various authentication failures that occur when using the `AuthenticationInterceptor`. All errors are +/// still vended from Alamofire as `AFError` types. The `AuthenticationError` instances will be embedded within +/// `AFError` `.requestAdaptationFailed` or `.requestRetryFailed` cases. +public enum AuthenticationError: Error { + /// The credential was missing so the request could not be authenticated. + case missingCredential + /// The credential was refreshed too many times within the `RefreshWindow`. + case excessiveRefresh +} + +// MARK: - + +/// The `AuthenticationInterceptor` class manages the queuing and threading complexity of authenticating requests. +/// It relies on an `Authenticator` type to handle the actual `URLRequest` authentication and `Credential` refresh. +public class AuthenticationInterceptor: RequestInterceptor where AuthenticatorType: Authenticator { + // MARK: Typealiases + + /// Type of credential used to authenticate requests. + public typealias Credential = AuthenticatorType.Credential + + // MARK: Helper Types + + /// Type that defines a time window used to identify excessive refresh calls. When enabled, prior to executing a + /// refresh, the `AuthenticationInterceptor` compares the timestamp history of previous refresh calls against the + /// `RefreshWindow`. If more refreshes have occurred within the refresh window than allowed, the refresh is + /// cancelled and an `AuthorizationError.excessiveRefresh` error is thrown. + public struct RefreshWindow { + /// `TimeInterval` defining the duration of the time window before the current time in which the number of + /// refresh attempts is compared against `maximumAttempts`. For example, if `interval` is 30 seconds, then the + /// `RefreshWindow` represents the past 30 seconds. If more attempts occurred in the past 30 seconds than + /// `maximumAttempts`, an `.excessiveRefresh` error will be thrown. + public let interval: TimeInterval + + /// Total refresh attempts allowed within `interval` before throwing an `.excessiveRefresh` error. + public let maximumAttempts: Int + + /// Creates a `RefreshWindow` instance from the specified `interval` and `maximumAttempts`. + /// + /// - Parameters: + /// - interval: `TimeInterval` defining the duration of the time window before the current time. + /// - maximumAttempts: The maximum attempts allowed within the `TimeInterval`. + public init(interval: TimeInterval = 30.0, maximumAttempts: Int = 5) { + self.interval = interval + self.maximumAttempts = maximumAttempts + } + } + + private struct AdaptOperation { + let urlRequest: URLRequest + let session: Session + let completion: (Result) -> Void + } + + private enum AdaptResult { + case adapt(Credential) + case doNotAdapt(AuthenticationError) + case adaptDeferred + } + + private struct MutableState { + var credential: Credential? + + var isRefreshing = false + var refreshTimestamps: [TimeInterval] = [] + var refreshWindow: RefreshWindow? + + var adaptOperations: [AdaptOperation] = [] + var requestsToRetry: [(RetryResult) -> Void] = [] + } + + // MARK: Properties + + /// The `Credential` used to authenticate requests. + public var credential: Credential? { + get { $mutableState.credential } + set { $mutableState.credential = newValue } + } + + let authenticator: AuthenticatorType + let queue = DispatchQueue(label: "org.alamofire.authentication.inspector") + + @Protected + private var mutableState: MutableState + + // MARK: Initialization + + /// Creates an `AuthenticationInterceptor` instance from the specified parameters. + /// + /// A `nil` `RefreshWindow` will result in the `AuthenticationInterceptor` not checking for excessive refresh calls. + /// It is recommended to always use a `RefreshWindow` to avoid endless refresh cycles. + /// + /// - Parameters: + /// - authenticator: The `Authenticator` type. + /// - credential: The `Credential` if it exists. `nil` by default. + /// - refreshWindow: The `RefreshWindow` used to identify excessive refresh calls. `RefreshWindow()` by default. + public init(authenticator: AuthenticatorType, + credential: Credential? = nil, + refreshWindow: RefreshWindow? = RefreshWindow()) { + self.authenticator = authenticator + mutableState = MutableState(credential: credential, refreshWindow: refreshWindow) + } + + // MARK: Adapt + + public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { + let adaptResult: AdaptResult = $mutableState.write { mutableState in + // Queue the adapt operation if a refresh is already in place. + guard !mutableState.isRefreshing else { + let operation = AdaptOperation(urlRequest: urlRequest, session: session, completion: completion) + mutableState.adaptOperations.append(operation) + return .adaptDeferred + } + + // Throw missing credential error is the credential is missing. + guard let credential = mutableState.credential else { + let error = AuthenticationError.missingCredential + return .doNotAdapt(error) + } + + // Queue the adapt operation and trigger refresh operation if credential requires refresh. + guard !credential.requiresRefresh else { + let operation = AdaptOperation(urlRequest: urlRequest, session: session, completion: completion) + mutableState.adaptOperations.append(operation) + refresh(credential, for: session, insideLock: &mutableState) + return .adaptDeferred + } + + return .adapt(credential) + } + + switch adaptResult { + case let .adapt(credential): + var authenticatedRequest = urlRequest + authenticator.apply(credential, to: &authenticatedRequest) + completion(.success(authenticatedRequest)) + + case let .doNotAdapt(adaptError): + completion(.failure(adaptError)) + + case .adaptDeferred: + // No-op: adapt operation captured during refresh. + break + } + } + + // MARK: Retry + + public func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) { + // Do not attempt retry if there was not an original request and response from the server. + guard let urlRequest = request.request, let response = request.response else { + completion(.doNotRetry) + return + } + + // Do not attempt retry unless the `Authenticator` verifies failure was due to authentication error (i.e. 401 status code). + guard authenticator.didRequest(urlRequest, with: response, failDueToAuthenticationError: error) else { + completion(.doNotRetry) + return + } + + // Do not attempt retry if there is no credential. + guard let credential = credential else { + let error = AuthenticationError.missingCredential + completion(.doNotRetryWithError(error)) + return + } + + // Retry the request if the `Authenticator` verifies it was authenticated with a previous credential. + guard authenticator.isRequest(urlRequest, authenticatedWith: credential) else { + completion(.retry) + return + } + + $mutableState.write { mutableState in + mutableState.requestsToRetry.append(completion) + + guard !mutableState.isRefreshing else { return } + + refresh(credential, for: session, insideLock: &mutableState) + } + } + + // MARK: Refresh + + private func refresh(_ credential: Credential, for session: Session, insideLock mutableState: inout MutableState) { + guard !isRefreshExcessive(insideLock: &mutableState) else { + let error = AuthenticationError.excessiveRefresh + handleRefreshFailure(error, insideLock: &mutableState) + return + } + + mutableState.refreshTimestamps.append(ProcessInfo.processInfo.systemUptime) + mutableState.isRefreshing = true + + // Dispatch to queue to hop out of the lock in case authenticator.refresh is implemented synchronously. + queue.async { + self.authenticator.refresh(credential, for: session) { result in + self.$mutableState.write { mutableState in + switch result { + case let .success(credential): + self.handleRefreshSuccess(credential, insideLock: &mutableState) + case let .failure(error): + self.handleRefreshFailure(error, insideLock: &mutableState) + } + } + } + } + } + + private func isRefreshExcessive(insideLock mutableState: inout MutableState) -> Bool { + guard let refreshWindow = mutableState.refreshWindow else { return false } + + let refreshWindowMin = ProcessInfo.processInfo.systemUptime - refreshWindow.interval + + let refreshAttemptsWithinWindow = mutableState.refreshTimestamps.reduce(into: 0) { attempts, refreshTimestamp in + guard refreshWindowMin <= refreshTimestamp else { return } + attempts += 1 + } + + let isRefreshExcessive = refreshAttemptsWithinWindow >= refreshWindow.maximumAttempts + + return isRefreshExcessive + } + + private func handleRefreshSuccess(_ credential: Credential, insideLock mutableState: inout MutableState) { + mutableState.credential = credential + + let adaptOperations = mutableState.adaptOperations + let requestsToRetry = mutableState.requestsToRetry + + mutableState.adaptOperations.removeAll() + mutableState.requestsToRetry.removeAll() + + mutableState.isRefreshing = false + + // Dispatch to queue to hop out of the mutable state lock + queue.async { + adaptOperations.forEach { self.adapt($0.urlRequest, for: $0.session, completion: $0.completion) } + requestsToRetry.forEach { $0(.retry) } + } + } + + private func handleRefreshFailure(_ error: Error, insideLock mutableState: inout MutableState) { + let adaptOperations = mutableState.adaptOperations + let requestsToRetry = mutableState.requestsToRetry + + mutableState.adaptOperations.removeAll() + mutableState.requestsToRetry.removeAll() + + mutableState.isRefreshing = false + + // Dispatch to queue to hop out of the mutable state lock + queue.async { + adaptOperations.forEach { $0.completion(.failure(error)) } + requestsToRetry.forEach { $0(.doNotRetryWithError(error)) } + } + } +} diff --git a/Pods/Alamofire/Source/CachedResponseHandler.swift b/Pods/Alamofire/Source/CachedResponseHandler.swift index b6e0d4b..e7d0060 100644 --- a/Pods/Alamofire/Source/CachedResponseHandler.swift +++ b/Pods/Alamofire/Source/CachedResponseHandler.swift @@ -58,9 +58,9 @@ public struct ResponseCacher { case modify((URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?) } - /// Returns a `ResponseCacher` with a follow `Behavior`. + /// Returns a `ResponseCacher` with a `.cache` `Behavior`. public static let cache = ResponseCacher(behavior: .cache) - /// Returns a `ResponseCacher` with a do not follow `Behavior`. + /// Returns a `ResponseCacher` with a `.doNotCache` `Behavior`. public static let doNotCache = ResponseCacher(behavior: .doNotCache) /// The `Behavior` of the `ResponseCacher`. @@ -89,3 +89,21 @@ extension ResponseCacher: CachedResponseHandler { } } } + +#if swift(>=5.5) +extension CachedResponseHandler where Self == ResponseCacher { + /// Provides a `ResponseCacher` which caches the response, if allowed. Equivalent to `ResponseCacher.cache`. + public static var cache: ResponseCacher { .cache } + + /// Provides a `ResponseCacher` which does not cache the response. Equivalent to `ResponseCacher.doNotCache`. + public static var doNotCache: ResponseCacher { .doNotCache } + + /// Creates a `ResponseCacher` which modifies the proposed `CachedURLResponse` using the provided closure. + /// + /// - Parameter closure: Closure used to modify the `CachedURLResponse`. + /// - Returns: The `ResponseCacher`. + public static func modify(using closure: @escaping ((URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)) -> ResponseCacher { + ResponseCacher(behavior: .modify(closure)) + } +} +#endif diff --git a/Pods/Alamofire/Source/Combine.swift b/Pods/Alamofire/Source/Combine.swift new file mode 100644 index 0000000..066ba47 --- /dev/null +++ b/Pods/Alamofire/Source/Combine.swift @@ -0,0 +1,655 @@ +// +// Combine.swift +// +// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) +// +// 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. +// + +#if !((os(iOS) && (arch(i386) || arch(arm))) || os(Windows) || os(Linux)) + +import Combine +import Dispatch +import Foundation + +// MARK: - DataRequest / UploadRequest + +/// A Combine `Publisher` that publishes the `DataResponse` of the provided `DataRequest`. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) +public struct DataResponsePublisher: Publisher { + public typealias Output = DataResponse + public typealias Failure = Never + + private typealias Handler = (@escaping (_ response: DataResponse) -> Void) -> DataRequest + + private let request: DataRequest + private let responseHandler: Handler + + /// Creates an instance which will serialize responses using the provided `ResponseSerializer`. + /// + /// - Parameters: + /// - request: `DataRequest` for which to publish the response. + /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. + /// - serializer: `ResponseSerializer` used to produce the published `DataResponse`. + public init(_ request: DataRequest, queue: DispatchQueue, serializer: Serializer) + where Value == Serializer.SerializedObject { + self.request = request + responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } + } + + /// Creates an instance which will serialize responses using the provided `DataResponseSerializerProtocol`. + /// + /// - Parameters: + /// - request: `DataRequest` for which to publish the response. + /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. + /// - serializer: `DataResponseSerializerProtocol` used to produce the published `DataResponse`. + public init(_ request: DataRequest, + queue: DispatchQueue, + serializer: Serializer) + where Value == Serializer.SerializedObject { + self.request = request + responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } + } + + /// Publishes only the `Result` of the `DataResponse` value. + /// + /// - Returns: The `AnyPublisher` publishing the `Result` value. + public func result() -> AnyPublisher, Never> { + map(\.result).eraseToAnyPublisher() + } + + /// Publishes the `Result` of the `DataResponse` as a single `Value` or fail with the `AFError` instance. + /// + /// - Returns: The `AnyPublisher` publishing the stream. + public func value() -> AnyPublisher { + setFailureType(to: AFError.self).flatMap(\.result.publisher).eraseToAnyPublisher() + } + + public func receive(subscriber: S) where S: Subscriber, DataResponsePublisher.Failure == S.Failure, DataResponsePublisher.Output == S.Input { + subscriber.receive(subscription: Inner(request: request, + responseHandler: responseHandler, + downstream: subscriber)) + } + + private final class Inner: Subscription, Cancellable + where Downstream.Input == Output { + typealias Failure = Downstream.Failure + + @Protected + private var downstream: Downstream? + private let request: DataRequest + private let responseHandler: Handler + + init(request: DataRequest, responseHandler: @escaping Handler, downstream: Downstream) { + self.request = request + self.responseHandler = responseHandler + self.downstream = downstream + } + + func request(_ demand: Subscribers.Demand) { + assert(demand > 0) + + guard let downstream = downstream else { return } + + self.downstream = nil + responseHandler { response in + _ = downstream.receive(response) + downstream.receive(completion: .finished) + }.resume() + } + + func cancel() { + request.cancel() + downstream = nil + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) +extension DataResponsePublisher where Value == Data? { + /// Creates an instance which publishes a `DataResponse` value without serialization. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public init(_ request: DataRequest, queue: DispatchQueue) { + self.request = request + responseHandler = { request.response(queue: queue, completionHandler: $0) } + } +} + +extension DataRequest { + /// Creates a `DataResponsePublisher` for this instance using the given `ResponseSerializer` and `DispatchQueue`. + /// + /// - Parameters: + /// - serializer: `ResponseSerializer` used to serialize response `Data`. + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// + /// - Returns: The `DataResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DataResponsePublisher + where Serializer.SerializedObject == T { + DataResponsePublisher(self, queue: queue, serializer: serializer) + } + + /// Creates a `DataResponsePublisher` for this instance and uses a `DataResponseSerializer` to serialize the + /// response. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` + /// by default. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of + /// status code. `[.head]` by default. + /// - Returns: The `DataResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishData(queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { + publishResponse(using: DataResponseSerializer(dataPreprocessor: preprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } + + /// Creates a `DataResponsePublisher` for this instance and uses a `StringResponseSerializer` to serialize the + /// response. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` + /// by default. + /// - encoding: `String.Encoding` to parse the response. `nil` by default, in which case the encoding + /// will be determined by the server response, falling back to the default HTTP character + /// set, `ISO-8859-1`. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of + /// status code. `[.head]` by default. + /// + /// - Returns: The `DataResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishString(queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, + encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { + publishResponse(using: StringResponseSerializer(dataPreprocessor: preprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } + + @_disfavoredOverload + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + @available(*, deprecated, message: "Renamed publishDecodable(type:queue:preprocessor:decoder:emptyResponseCodes:emptyRequestMethods).") + public func publishDecodable(type: T.Type = T.self, + queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyResponseMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { + publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyResponseMethods), + on: queue) + } + + /// Creates a `DataResponsePublisher` for this instance and uses a `DecodableResponseSerializer` to serialize the + /// response. + /// + /// - Parameters: + /// - type: `Decodable` type to which to decode response `Data`. Inferred from the context by + /// default. + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. + /// `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` instance used to decode response `Data`. `JSONDecoder()` by default. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of + /// status code. `[.head]` by default. + /// + /// - Returns: The `DataResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishDecodable(type: T.Type = T.self, + queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { + publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } + + /// Creates a `DataResponsePublisher` for this instance which does not serialize the response before publishing. + /// + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// + /// - Returns: The `DataResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishUnserialized(queue: DispatchQueue = .main) -> DataResponsePublisher { + DataResponsePublisher(self, queue: queue) + } +} + +// A Combine `Publisher` that publishes a sequence of `Stream` values received by the provided `DataStreamRequest`. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) +public struct DataStreamPublisher: Publisher { + public typealias Output = DataStreamRequest.Stream + public typealias Failure = Never + + private typealias Handler = (@escaping DataStreamRequest.Handler) -> DataStreamRequest + + private let request: DataStreamRequest + private let streamHandler: Handler + + /// Creates an instance which will serialize responses using the provided `DataStreamSerializer`. + /// + /// - Parameters: + /// - request: `DataStreamRequest` for which to publish the response. + /// - queue: `DispatchQueue` on which the `Stream` values will be published. `.main` by + /// default. + /// - serializer: `DataStreamSerializer` used to produce the published `Stream` values. + public init(_ request: DataStreamRequest, queue: DispatchQueue, serializer: Serializer) + where Value == Serializer.SerializedObject { + self.request = request + streamHandler = { request.responseStream(using: serializer, on: queue, stream: $0) } + } + + /// Publishes only the `Result` of the `DataStreamRequest.Stream`'s `Event`s. + /// + /// - Returns: The `AnyPublisher` publishing the `Result` value. + public func result() -> AnyPublisher, Never> { + compactMap { stream in + switch stream.event { + case let .stream(result): + return result + // If the stream has completed with an error, send the error value downstream as a `.failure`. + case let .complete(completion): + return completion.error.map(Result.failure) + } + } + .eraseToAnyPublisher() + } + + /// Publishes the streamed values of the `DataStreamRequest.Stream` as a sequence of `Value` or fail with the + /// `AFError` instance. + /// + /// - Returns: The `AnyPublisher` publishing the stream. + public func value() -> AnyPublisher { + result().setFailureType(to: AFError.self).flatMap(\.publisher).eraseToAnyPublisher() + } + + public func receive(subscriber: S) where S: Subscriber, DataStreamPublisher.Failure == S.Failure, DataStreamPublisher.Output == S.Input { + subscriber.receive(subscription: Inner(request: request, + streamHandler: streamHandler, + downstream: subscriber)) + } + + private final class Inner: Subscription, Cancellable + where Downstream.Input == Output { + typealias Failure = Downstream.Failure + + @Protected + private var downstream: Downstream? + private let request: DataStreamRequest + private let streamHandler: Handler + + init(request: DataStreamRequest, streamHandler: @escaping Handler, downstream: Downstream) { + self.request = request + self.streamHandler = streamHandler + self.downstream = downstream + } + + func request(_ demand: Subscribers.Demand) { + assert(demand > 0) + + guard let downstream = downstream else { return } + + self.downstream = nil + streamHandler { stream in + _ = downstream.receive(stream) + if case .complete = stream.event { + downstream.receive(completion: .finished) + } + }.resume() + } + + func cancel() { + request.cancel() + downstream = nil + } + } +} + +extension DataStreamRequest { + /// Creates a `DataStreamPublisher` for this instance using the given `DataStreamSerializer` and `DispatchQueue`. + /// + /// - Parameters: + /// - serializer: `DataStreamSerializer` used to serialize the streamed `Data`. + /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. + /// - Returns: The `DataStreamPublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishStream(using serializer: Serializer, + on queue: DispatchQueue = .main) -> DataStreamPublisher { + DataStreamPublisher(self, queue: queue, serializer: serializer) + } + + /// Creates a `DataStreamPublisher` for this instance which uses a `PassthroughStreamSerializer` to stream `Data` + /// unserialized. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. + /// - Returns: The `DataStreamPublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishData(queue: DispatchQueue = .main) -> DataStreamPublisher { + publishStream(using: PassthroughStreamSerializer(), on: queue) + } + + /// Creates a `DataStreamPublisher` for this instance which uses a `StringStreamSerializer` to serialize stream + /// `Data` values into `String` values. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. + /// - Returns: The `DataStreamPublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishString(queue: DispatchQueue = .main) -> DataStreamPublisher { + publishStream(using: StringStreamSerializer(), on: queue) + } + + /// Creates a `DataStreamPublisher` for this instance which uses a `DecodableStreamSerializer` with the provided + /// parameters to serialize stream `Data` values into the provided type. + /// + /// - Parameters: + /// - type: `Decodable` type to which to decode stream `Data`. Inferred from the context by default. + /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. + /// - decoder: `DataDecoder` instance used to decode stream `Data`. `JSONDecoder()` by default. + /// - preprocessor: `DataPreprocessor` which filters incoming stream `Data` before serialization. + /// `PassthroughPreprocessor()` by default. + /// - Returns: The `DataStreamPublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishDecodable(type: T.Type = T.self, + queue: DispatchQueue = .main, + decoder: DataDecoder = JSONDecoder(), + preprocessor: DataPreprocessor = PassthroughPreprocessor()) -> DataStreamPublisher { + publishStream(using: DecodableStreamSerializer(decoder: decoder, + dataPreprocessor: preprocessor), + on: queue) + } +} + +/// A Combine `Publisher` that publishes the `DownloadResponse` of the provided `DownloadRequest`. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) +public struct DownloadResponsePublisher: Publisher { + public typealias Output = DownloadResponse + public typealias Failure = Never + + private typealias Handler = (@escaping (_ response: DownloadResponse) -> Void) -> DownloadRequest + + private let request: DownloadRequest + private let responseHandler: Handler + + /// Creates an instance which will serialize responses using the provided `ResponseSerializer`. + /// + /// - Parameters: + /// - request: `DownloadRequest` for which to publish the response. + /// - queue: `DispatchQueue` on which the `DownloadResponse` value will be published. `.main` by default. + /// - serializer: `ResponseSerializer` used to produce the published `DownloadResponse`. + public init(_ request: DownloadRequest, queue: DispatchQueue, serializer: Serializer) + where Value == Serializer.SerializedObject { + self.request = request + responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } + } + + /// Creates an instance which will serialize responses using the provided `DownloadResponseSerializerProtocol` value. + /// + /// - Parameters: + /// - request: `DownloadRequest` for which to publish the response. + /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. + /// - serializer: `DownloadResponseSerializerProtocol` used to produce the published `DownloadResponse`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public init(_ request: DownloadRequest, + queue: DispatchQueue, + serializer: Serializer) + where Value == Serializer.SerializedObject { + self.request = request + responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } + } + + /// Publishes only the `Result` of the `DownloadResponse` value. + /// + /// - Returns: The `AnyPublisher` publishing the `Result` value. + public func result() -> AnyPublisher, Never> { + map(\.result).eraseToAnyPublisher() + } + + /// Publishes the `Result` of the `DownloadResponse` as a single `Value` or fail with the `AFError` instance. + /// + /// - Returns: The `AnyPublisher` publishing the stream. + public func value() -> AnyPublisher { + setFailureType(to: AFError.self).flatMap(\.result.publisher).eraseToAnyPublisher() + } + + public func receive(subscriber: S) where S: Subscriber, DownloadResponsePublisher.Failure == S.Failure, DownloadResponsePublisher.Output == S.Input { + subscriber.receive(subscription: Inner(request: request, + responseHandler: responseHandler, + downstream: subscriber)) + } + + private final class Inner: Subscription, Cancellable + where Downstream.Input == Output { + typealias Failure = Downstream.Failure + + @Protected + private var downstream: Downstream? + private let request: DownloadRequest + private let responseHandler: Handler + + init(request: DownloadRequest, responseHandler: @escaping Handler, downstream: Downstream) { + self.request = request + self.responseHandler = responseHandler + self.downstream = downstream + } + + func request(_ demand: Subscribers.Demand) { + assert(demand > 0) + + guard let downstream = downstream else { return } + + self.downstream = nil + responseHandler { response in + _ = downstream.receive(response) + downstream.receive(completion: .finished) + }.resume() + } + + func cancel() { + request.cancel() + downstream = nil + } + } +} + +extension DownloadRequest { + /// Creates a `DownloadResponsePublisher` for this instance using the given `ResponseSerializer` and `DispatchQueue`. + /// + /// - Parameters: + /// - serializer: `ResponseSerializer` used to serialize the response `Data` from disk. + /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published.`.main` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DownloadResponsePublisher + where Serializer.SerializedObject == T { + DownloadResponsePublisher(self, queue: queue, serializer: serializer) + } + + /// Creates a `DownloadResponsePublisher` for this instance using the given `DownloadResponseSerializerProtocol` and + /// `DispatchQueue`. + /// + /// - Parameters: + /// - serializer: `DownloadResponseSerializer` used to serialize the response `Data` from disk. + /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published.`.main` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DownloadResponsePublisher + where Serializer.SerializedObject == T { + DownloadResponsePublisher(self, queue: queue, serializer: serializer) + } + + /// Creates a `DownloadResponsePublisher` for this instance and uses a `URLResponseSerializer` to serialize the + /// response. + /// + /// - Parameter queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishURL(queue: DispatchQueue = .main) -> DownloadResponsePublisher { + publishResponse(using: URLResponseSerializer(), on: queue) + } + + /// Creates a `DownloadResponsePublisher` for this instance and uses a `DataResponseSerializer` to serialize the + /// response. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` + /// by default. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of + /// status code. `[.head]` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishData(queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { + publishResponse(using: DataResponseSerializer(dataPreprocessor: preprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } + + /// Creates a `DownloadResponsePublisher` for this instance and uses a `StringResponseSerializer` to serialize the + /// response. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` + /// by default. + /// - encoding: `String.Encoding` to parse the response. `nil` by default, in which case the encoding + /// will be determined by the server response, falling back to the default HTTP character + /// set, `ISO-8859-1`. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of + /// status code. `[.head]` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishString(queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, + encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { + publishResponse(using: StringResponseSerializer(dataPreprocessor: preprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } + + @_disfavoredOverload + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + @available(*, deprecated, message: "Renamed publishDecodable(type:queue:preprocessor:decoder:emptyResponseCodes:emptyRequestMethods).") + public func publishDecodable(type: T.Type = T.self, + queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyResponseMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { + publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyResponseMethods), + on: queue) + } + + /// Creates a `DownloadResponsePublisher` for this instance and uses a `DecodableResponseSerializer` to serialize + /// the response. + /// + /// - Parameters: + /// - type: `Decodable` type to which to decode response `Data`. Inferred from the context by default. + /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. + /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. + /// `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` instance used to decode response `Data`. `JSONDecoder()` by default. + /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by + /// default. + /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless + /// of status code. `[.head]` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishDecodable(type: T.Type = T.self, + queue: DispatchQueue = .main, + preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { + publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + on: queue) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) +extension DownloadResponsePublisher where Value == URL? { + /// Creates an instance which publishes a `DownloadResponse` value without serialization. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public init(_ request: DownloadRequest, queue: DispatchQueue) { + self.request = request + responseHandler = { request.response(queue: queue, completionHandler: $0) } + } +} + +extension DownloadRequest { + /// Creates a `DownloadResponsePublisher` for this instance which does not serialize the response before publishing. + /// + /// - Parameter queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. + /// + /// - Returns: The `DownloadResponsePublisher`. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public func publishUnserialized(on queue: DispatchQueue = .main) -> DownloadResponsePublisher { + DownloadResponsePublisher(self, queue: queue) + } +} + +#endif diff --git a/Pods/Alamofire/Source/Concurrency.swift b/Pods/Alamofire/Source/Concurrency.swift new file mode 100644 index 0000000..2484335 --- /dev/null +++ b/Pods/Alamofire/Source/Concurrency.swift @@ -0,0 +1,698 @@ +// +// Concurrency.swift +// +// Copyright (c) 2021 Alamofire Software Foundation (http://alamofire.org/) +// +// 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. +// + +#if compiler(>=5.5.2) && canImport(_Concurrency) + +import Foundation + +// MARK: - Request Event Streams + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Request { + /// Creates a `StreamOf` for the instance's upload progress. + /// + /// - Parameter bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `StreamOf`. + public func uploadProgress(bufferingPolicy: StreamOf.BufferingPolicy = .unbounded) -> StreamOf { + stream(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + uploadProgress(queue: .singleEventQueue) { progress in + continuation.yield(progress) + } + } + } + + /// Creates a `StreamOf` for the instance's download progress. + /// + /// - Parameter bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `StreamOf`. + public func downloadProgress(bufferingPolicy: StreamOf.BufferingPolicy = .unbounded) -> StreamOf { + stream(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + downloadProgress(queue: .singleEventQueue) { progress in + continuation.yield(progress) + } + } + } + + /// Creates a `StreamOf` for the `URLRequest`s produced for the instance. + /// + /// - Parameter bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `StreamOf`. + public func urlRequests(bufferingPolicy: StreamOf.BufferingPolicy = .unbounded) -> StreamOf { + stream(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + onURLRequestCreation(on: .singleEventQueue) { request in + continuation.yield(request) + } + } + } + + /// Creates a `StreamOf` for the `URLSessionTask`s produced for the instance. + /// + /// - Parameter bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `StreamOf`. + public func urlSessionTasks(bufferingPolicy: StreamOf.BufferingPolicy = .unbounded) -> StreamOf { + stream(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + onURLSessionTaskCreation(on: .singleEventQueue) { task in + continuation.yield(task) + } + } + } + + /// Creates a `StreamOf` for the cURL descriptions produced for the instance. + /// + /// - Parameter bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `StreamOf`. + public func cURLDescriptions(bufferingPolicy: StreamOf.BufferingPolicy = .unbounded) -> StreamOf { + stream(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + cURLDescription(on: .singleEventQueue) { description in + continuation.yield(description) + } + } + } + + private func stream(of type: T.Type = T.self, + bufferingPolicy: StreamOf.BufferingPolicy = .unbounded, + yielder: @escaping (StreamOf.Continuation) -> Void) -> StreamOf { + StreamOf(bufferingPolicy: bufferingPolicy) { [unowned self] continuation in + yielder(continuation) + // Must come after serializers run in order to catch retry progress. + onFinish { + continuation.finish() + } + } + } +} + +// MARK: - DataTask + +/// Value used to `await` a `DataResponse` and associated values. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct DataTask { + /// `DataResponse` produced by the `DataRequest` and its response handler. + public var response: DataResponse { + get async { + if shouldAutomaticallyCancel { + return await withTaskCancellationHandler { + self.cancel() + } operation: { + await task.value + } + } else { + return await task.value + } + } + } + + /// `Result` of any response serialization performed for the `response`. + public var result: Result { + get async { await response.result } + } + + /// `Value` returned by the `response`. + public var value: Value { + get async throws { + try await result.get() + } + } + + private let request: DataRequest + private let task: Task, Never> + private let shouldAutomaticallyCancel: Bool + + fileprivate init(request: DataRequest, task: Task, Never>, shouldAutomaticallyCancel: Bool) { + self.request = request + self.task = task + self.shouldAutomaticallyCancel = shouldAutomaticallyCancel + } + + /// Cancel the underlying `DataRequest` and `Task`. + public func cancel() { + task.cancel() + } + + /// Resume the underlying `DataRequest`. + public func resume() { + request.resume() + } + + /// Suspend the underlying `DataRequest`. + public func suspend() { + request.suspend() + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension DataRequest { + /// Creates a `DataTask` to `await` a `Data` value. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DataTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before completion. + /// - emptyResponseCodes: HTTP response codes for which empty responses are allowed. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DataTask`. + public func serializingData(automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DataTask { + serializingResponse(using: DataResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DataTask` to `await` serialization of a `Decodable` value. + /// + /// - Parameters: + /// - type: `Decodable` type to decode from response data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DataTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the serializer. + /// `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DataTask`. + public func serializingDecodable(_ type: Value.Type = Value.self, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DataTask { + serializingResponse(using: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DataTask` to `await` serialization of a `String` value. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DataTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the serializer. + /// `PassthroughPreprocessor()` by default. + /// - encoding: `String.Encoding` to use during serialization. Defaults to `nil`, in which case + /// the encoding will be determined from the server response, falling back to the + /// default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DataTask`. + public func serializingString(automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, + encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DataTask { + serializingResponse(using: StringResponseSerializer(dataPreprocessor: dataPreprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DataTask` to `await` serialization using the provided `ResponseSerializer` instance. + /// + /// - Parameters: + /// - serializer: `ResponseSerializer` responsible for serializing the request, response, and data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DataTask`'s async + /// properties. `false` by default. + /// + /// - Returns: The `DataTask`. + public func serializingResponse(using serializer: Serializer, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false) + -> DataTask { + dataTask(automaticallyCancelling: shouldAutomaticallyCancel) { + self.response(queue: .singleEventQueue, + responseSerializer: serializer, + completionHandler: $0) + } + } + + /// Creates a `DataTask` to `await` serialization using the provided `DataResponseSerializerProtocol` instance. + /// + /// - Parameters: + /// - serializer: `DataResponseSerializerProtocol` responsible for serializing the request, + /// response, and data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DataTask`'s async + /// properties. `false` by default. + /// + /// - Returns: The `DataTask`. + public func serializingResponse(using serializer: Serializer, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false) + -> DataTask { + dataTask(automaticallyCancelling: shouldAutomaticallyCancel) { + self.response(queue: .singleEventQueue, + responseSerializer: serializer, + completionHandler: $0) + } + } + + private func dataTask(automaticallyCancelling shouldAutomaticallyCancel: Bool, + forResponse onResponse: @escaping (@escaping (DataResponse) -> Void) -> Void) + -> DataTask { + let task = Task { + await withTaskCancellationHandler { + self.cancel() + } operation: { + await withCheckedContinuation { continuation in + onResponse { + continuation.resume(returning: $0) + } + } + } + } + + return DataTask(request: self, task: task, shouldAutomaticallyCancel: shouldAutomaticallyCancel) + } +} + +// MARK: - DownloadTask + +/// Value used to `await` a `DownloadResponse` and associated values. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct DownloadTask { + /// `DownloadResponse` produced by the `DownloadRequest` and its response handler. + public var response: DownloadResponse { + get async { + if shouldAutomaticallyCancel { + return await withTaskCancellationHandler { + self.cancel() + } operation: { + await task.value + } + } else { + return await task.value + } + } + } + + /// `Result` of any response serialization performed for the `response`. + public var result: Result { + get async { await response.result } + } + + /// `Value` returned by the `response`. + public var value: Value { + get async throws { + try await result.get() + } + } + + private let task: Task, Never> + private let request: DownloadRequest + private let shouldAutomaticallyCancel: Bool + + fileprivate init(request: DownloadRequest, task: Task, Never>, shouldAutomaticallyCancel: Bool) { + self.request = request + self.task = task + self.shouldAutomaticallyCancel = shouldAutomaticallyCancel + } + + /// Cancel the underlying `DownloadRequest` and `Task`. + public func cancel() { + task.cancel() + } + + /// Resume the underlying `DownloadRequest`. + public func resume() { + request.resume() + } + + /// Suspend the underlying `DownloadRequest`. + public func suspend() { + request.suspend() + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension DownloadRequest { + /// Creates a `DownloadTask` to `await` a `Data` value. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DownloadTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before completion. + /// - emptyResponseCodes: HTTP response codes for which empty responses are allowed. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DownloadTask`. + public func serializingData(automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DownloadTask { + serializingDownload(using: DataResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DownloadTask` to `await` serialization of a `Decodable` value. + /// + /// - Note: This serializer reads the entire response into memory before parsing. + /// + /// - Parameters: + /// - type: `Decodable` type to decode from response data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DownloadTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the serializer. + /// `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DownloadTask`. + public func serializingDecodable(_ type: Value.Type = Value.self, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DownloadTask { + serializingDownload(using: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DownloadTask` to `await` serialization of the downloaded file's `URL` on disk. + /// + /// - Returns: The `DownloadTask`. + public func serializingDownloadedFileURL() -> DownloadTask { + serializingDownload(using: URLResponseSerializer()) + } + + /// Creates a `DownloadTask` to `await` serialization of a `String` value. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DownloadTask`'s async + /// properties. `false` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// serializer. `PassthroughPreprocessor()` by default. + /// - encoding: `String.Encoding` to use during serialization. Defaults to `nil`, in which case + /// the encoding will be determined from the server response, falling back to the + /// default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// + /// - Returns: The `DownloadTask`. + public func serializingString(automaticallyCancelling shouldAutomaticallyCancel: Bool = false, + dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, + encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DownloadTask { + serializingDownload(using: StringResponseSerializer(dataPreprocessor: dataPreprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + automaticallyCancelling: shouldAutomaticallyCancel) + } + + /// Creates a `DownloadTask` to `await` serialization using the provided `ResponseSerializer` instance. + /// + /// - Parameters: + /// - serializer: `ResponseSerializer` responsible for serializing the request, response, and data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DownloadTask`'s async + /// properties. `false` by default. + /// + /// - Returns: The `DownloadTask`. + public func serializingDownload(using serializer: Serializer, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false) + -> DownloadTask { + downloadTask(automaticallyCancelling: shouldAutomaticallyCancel) { + self.response(queue: .singleEventQueue, + responseSerializer: serializer, + completionHandler: $0) + } + } + + /// Creates a `DownloadTask` to `await` serialization using the provided `DownloadResponseSerializerProtocol` + /// instance. + /// + /// - Parameters: + /// - serializer: `DownloadResponseSerializerProtocol` responsible for serializing the request, + /// response, and data. + /// - shouldAutomaticallyCancel: `Bool` determining whether or not the request should be cancelled when the + /// enclosing async context is cancelled. Only applies to `DownloadTask`'s async + /// properties. `false` by default. + /// + /// - Returns: The `DownloadTask`. + public func serializingDownload(using serializer: Serializer, + automaticallyCancelling shouldAutomaticallyCancel: Bool = false) + -> DownloadTask { + downloadTask(automaticallyCancelling: shouldAutomaticallyCancel) { + self.response(queue: .singleEventQueue, + responseSerializer: serializer, + completionHandler: $0) + } + } + + private func downloadTask(automaticallyCancelling shouldAutomaticallyCancel: Bool, + forResponse onResponse: @escaping (@escaping (DownloadResponse) -> Void) -> Void) + -> DownloadTask { + let task = Task { + await withTaskCancellationHandler { + self.cancel() + } operation: { + await withCheckedContinuation { continuation in + onResponse { + continuation.resume(returning: $0) + } + } + } + } + + return DownloadTask(request: self, task: task, shouldAutomaticallyCancel: shouldAutomaticallyCancel) + } +} + +// MARK: - DataStreamTask + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct DataStreamTask { + // Type of created streams. + public typealias Stream = StreamOf> + + private let request: DataStreamRequest + + fileprivate init(request: DataStreamRequest) { + self.request = request + } + + /// Creates a `Stream` of `Data` values from the underlying `DataStreamRequest`. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` indicating whether the underlying `DataStreamRequest` should be canceled + /// which observation of the stream stops. `true` by default. + /// - bufferingPolicy: ` BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `Stream`. + public func streamingData(automaticallyCancelling shouldAutomaticallyCancel: Bool = true, bufferingPolicy: Stream.BufferingPolicy = .unbounded) -> Stream { + createStream(automaticallyCancelling: shouldAutomaticallyCancel, bufferingPolicy: bufferingPolicy) { onStream in + self.request.responseStream(on: .streamCompletionQueue(forRequestID: request.id), stream: onStream) + } + } + + /// Creates a `Stream` of `UTF-8` `String`s from the underlying `DataStreamRequest`. + /// + /// - Parameters: + /// - shouldAutomaticallyCancel: `Bool` indicating whether the underlying `DataStreamRequest` should be canceled + /// which observation of the stream stops. `true` by default. + /// - bufferingPolicy: ` BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// - Returns: + public func streamingStrings(automaticallyCancelling shouldAutomaticallyCancel: Bool = true, bufferingPolicy: Stream.BufferingPolicy = .unbounded) -> Stream { + createStream(automaticallyCancelling: shouldAutomaticallyCancel, bufferingPolicy: bufferingPolicy) { onStream in + self.request.responseStreamString(on: .streamCompletionQueue(forRequestID: request.id), stream: onStream) + } + } + + /// Creates a `Stream` of `Decodable` values from the underlying `DataStreamRequest`. + /// + /// - Parameters: + /// - type: `Decodable` type to be serialized from stream payloads. + /// - shouldAutomaticallyCancel: `Bool` indicating whether the underlying `DataStreamRequest` should be canceled + /// which observation of the stream stops. `true` by default. + /// - bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `Stream`. + public func streamingDecodables(_ type: T.Type = T.self, + automaticallyCancelling shouldAutomaticallyCancel: Bool = true, + bufferingPolicy: Stream.BufferingPolicy = .unbounded) + -> Stream where T: Decodable { + streamingResponses(serializedUsing: DecodableStreamSerializer(), + automaticallyCancelling: shouldAutomaticallyCancel, + bufferingPolicy: bufferingPolicy) + } + + /// Creates a `Stream` of values using the provided `DataStreamSerializer` from the underlying `DataStreamRequest`. + /// + /// - Parameters: + /// - serializer: `DataStreamSerializer` to use to serialize incoming `Data`. + /// - shouldAutomaticallyCancel: `Bool` indicating whether the underlying `DataStreamRequest` should be canceled + /// which observation of the stream stops. `true` by default. + /// - bufferingPolicy: `BufferingPolicy` that determines the stream's buffering behavior.`.unbounded` by default. + /// + /// - Returns: The `Stream`. + public func streamingResponses(serializedUsing serializer: Serializer, + automaticallyCancelling shouldAutomaticallyCancel: Bool = true, + bufferingPolicy: Stream.BufferingPolicy = .unbounded) + -> Stream { + createStream(automaticallyCancelling: shouldAutomaticallyCancel, bufferingPolicy: bufferingPolicy) { onStream in + self.request.responseStream(using: serializer, + on: .streamCompletionQueue(forRequestID: request.id), + stream: onStream) + } + } + + private func createStream(automaticallyCancelling shouldAutomaticallyCancel: Bool = true, + bufferingPolicy: Stream.BufferingPolicy = .unbounded, + forResponse onResponse: @escaping (@escaping (DataStreamRequest.Stream) -> Void) -> Void) + -> Stream { + StreamOf(bufferingPolicy: bufferingPolicy) { + guard shouldAutomaticallyCancel, + request.isInitialized || request.isResumed || request.isSuspended else { return } + + cancel() + } builder: { continuation in + onResponse { stream in + continuation.yield(stream) + if case .complete = stream.event { + continuation.finish() + } + } + } + } + + /// Cancel the underlying `DataStreamRequest`. + public func cancel() { + request.cancel() + } + + /// Resume the underlying `DataStreamRequest`. + public func resume() { + request.resume() + } + + /// Suspend the underlying `DataStreamRequest`. + public func suspend() { + request.suspend() + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension DataStreamRequest { + /// Creates a `DataStreamTask` used to `await` streams of serialized values. + /// + /// - Returns: The `DataStreamTask`. + public func streamTask() -> DataStreamTask { + DataStreamTask(request: self) + } +} + +extension DispatchQueue { + fileprivate static let singleEventQueue = DispatchQueue(label: "org.alamofire.concurrencySingleEventQueue", + attributes: .concurrent) + + fileprivate static func streamCompletionQueue(forRequestID id: UUID) -> DispatchQueue { + DispatchQueue(label: "org.alamofire.concurrencyStreamCompletionQueue-\(id)", target: .singleEventQueue) + } +} + +/// An asynchronous sequence generated from an underlying `AsyncStream`. Only produced by Alamofire. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct StreamOf: AsyncSequence { + public typealias AsyncIterator = Iterator + public typealias BufferingPolicy = AsyncStream.Continuation.BufferingPolicy + fileprivate typealias Continuation = AsyncStream.Continuation + + private let bufferingPolicy: BufferingPolicy + private let onTermination: (() -> Void)? + private let builder: (Continuation) -> Void + + fileprivate init(bufferingPolicy: BufferingPolicy = .unbounded, + onTermination: (() -> Void)? = nil, + builder: @escaping (Continuation) -> Void) { + self.bufferingPolicy = bufferingPolicy + self.onTermination = onTermination + self.builder = builder + } + + public func makeAsyncIterator() -> Iterator { + var continuation: AsyncStream.Continuation? + let stream = AsyncStream { innerContinuation in + continuation = innerContinuation + builder(innerContinuation) + } + + return Iterator(iterator: stream.makeAsyncIterator()) { + continuation?.finish() + self.onTermination?() + } + } + + public struct Iterator: AsyncIteratorProtocol { + private final class Token { + private let onDeinit: () -> Void + + init(onDeinit: @escaping () -> Void) { + self.onDeinit = onDeinit + } + + deinit { + onDeinit() + } + } + + private var iterator: AsyncStream.AsyncIterator + private let token: Token + + init(iterator: AsyncStream.AsyncIterator, onCancellation: @escaping () -> Void) { + self.iterator = iterator + token = Token(onDeinit: onCancellation) + } + + public mutating func next() async -> Element? { + await iterator.next() + } + } +} + +#endif diff --git a/Pods/Alamofire/Source/EventMonitor.swift b/Pods/Alamofire/Source/EventMonitor.swift index 4363828..3b09671 100644 --- a/Pods/Alamofire/Source/EventMonitor.swift +++ b/Pods/Alamofire/Source/EventMonitor.swift @@ -164,6 +164,27 @@ public protocol EventMonitor { /// Event called when a `DataRequest` calls a `ResponseSerializer` and creates a generic `DataResponse`. func request(_ request: DataRequest, didParseResponse response: DataResponse) + // MARK: DataStreamRequest Events + + /// Event called when a `DataStreamRequest` calls a `Validation` closure. + /// + /// - Parameters: + /// - request: `DataStreamRequest` which is calling the `Validation`. + /// - urlRequest: `URLRequest` of the request being validated. + /// - response: `HTTPURLResponse` of the request being validated. + /// - result: Produced `ValidationResult`. + func request(_ request: DataStreamRequest, + didValidateRequest urlRequest: URLRequest?, + response: HTTPURLResponse, + withResult result: Request.ValidationResult) + + /// Event called when a `DataStreamSerializer` produces a value from streamed `Data`. + /// + /// - Parameters: + /// - request: `DataStreamRequest` for which the value was serialized. + /// - result: `Result` of the serialization attempt. + func request(_ request: DataStreamRequest, didParseStream result: Result) + // MARK: UploadRequest Events /// Event called when an `UploadRequest` creates its `Uploadable` value, indicating the type of upload it represents. @@ -201,7 +222,7 @@ public protocol EventMonitor { extension EventMonitor { /// The default queue on which `CompositeEventMonitor`s will call the `EventMonitor` methods. `.main` by default. - public var queue: DispatchQueue { return .main } + public var queue: DispatchQueue { .main } // MARK: Default Implementations @@ -268,6 +289,11 @@ extension EventMonitor { withResult result: Request.ValidationResult) {} public func request(_ request: DataRequest, didParseResponse response: DataResponse) {} public func request(_ request: DataRequest, didParseResponse response: DataResponse) {} + public func request(_ request: DataStreamRequest, + didValidateRequest urlRequest: URLRequest?, + response: HTTPURLResponse, + withResult result: Request.ValidationResult) {} + public func request(_ request: DataStreamRequest, didParseStream result: Result) {} public func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) {} public func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) {} public func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) {} @@ -284,7 +310,7 @@ extension EventMonitor { /// An `EventMonitor` which can contain multiple `EventMonitor`s and calls their methods on their queues. public final class CompositeEventMonitor: EventMonitor { - public let queue = DispatchQueue(label: "org.alamofire.compositeEventMonitor", qos: .background) + public let queue = DispatchQueue(label: "org.alamofire.compositeEventMonitor", qos: .utility) let monitors: [EventMonitor] @@ -486,6 +512,21 @@ public final class CompositeEventMonitor: EventMonitor { performEvent { $0.request(request, didParseResponse: response) } } + public func request(_ request: DataStreamRequest, + didValidateRequest urlRequest: URLRequest?, + response: HTTPURLResponse, + withResult result: Request.ValidationResult) { + performEvent { $0.request(request, + didValidateRequest: urlRequest, + response: response, + withResult: result) + } + } + + public func request(_ request: DataStreamRequest, didParseStream result: Result) { + performEvent { $0.request(request, didParseStream: result) } + } + public func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) { performEvent { $0.request(request, didCreateUploadable: uploadable) } } @@ -628,6 +669,9 @@ open class ClosureEventMonitor: EventMonitor { /// Closure called on the `request(_:didParseResponse:)` event. open var requestDidParseResponse: ((DataRequest, DataResponse) -> Void)? + /// Closure called on the `request(_:didValidateRequest:response:withResult:)` event. + open var requestDidValidateRequestResponseWithResult: ((DataStreamRequest, URLRequest?, HTTPURLResponse, Request.ValidationResult) -> Void)? + /// Closure called on the `request(_:didCreateUploadable:)` event. open var requestDidCreateUploadable: ((UploadRequest, UploadRequest.Uploadable) -> Void)? @@ -806,6 +850,10 @@ open class ClosureEventMonitor: EventMonitor { requestDidParseResponse?(request, response) } + public func request(_ request: DataStreamRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, withResult result: Request.ValidationResult) { + requestDidValidateRequestResponseWithResult?(request, urlRequest, response, result) + } + open func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) { requestDidCreateUploadable?(request, uploadable) } diff --git a/Pods/Alamofire/Source/HTTPHeaders.swift b/Pods/Alamofire/Source/HTTPHeaders.swift index 641087c..cdbdbc6 100644 --- a/Pods/Alamofire/Source/HTTPHeaders.swift +++ b/Pods/Alamofire/Source/HTTPHeaders.swift @@ -93,16 +93,19 @@ public struct HTTPHeaders { headers.remove(at: index) } - /// Sort the current instance by header name. + /// Sort the current instance by header name, case insensitively. public mutating func sort() { - headers.sort { $0.name < $1.name } + headers.sort { $0.name.lowercased() < $1.name.lowercased() } } /// Returns an instance sorted by header name. /// /// - Returns: A copy of the current instance sorted by name. public func sorted() -> HTTPHeaders { - return HTTPHeaders(headers.sorted { $0.name < $1.name }) + var headers = self + headers.sort() + + return headers } /// Case-insensitively find a header's value by name. @@ -120,7 +123,7 @@ public struct HTTPHeaders { /// /// - Parameter name: The name of the header. public subscript(_ name: String) -> String? { - get { return value(for: name) } + get { value(for: name) } set { if let value = newValue { update(name: name, value: value) @@ -156,31 +159,31 @@ extension HTTPHeaders: ExpressibleByArrayLiteral { extension HTTPHeaders: Sequence { public func makeIterator() -> IndexingIterator<[HTTPHeader]> { - return headers.makeIterator() + headers.makeIterator() } } extension HTTPHeaders: Collection { public var startIndex: Int { - return headers.startIndex + headers.startIndex } public var endIndex: Int { - return headers.endIndex + headers.endIndex } public subscript(position: Int) -> HTTPHeader { - return headers[position] + headers[position] } public func index(after i: Int) -> Int { - return headers.index(after: i) + headers.index(after: i) } } extension HTTPHeaders: CustomStringConvertible { public var description: String { - return headers.map { $0.description } + headers.map(\.description) .joined(separator: "\n") } } @@ -208,7 +211,7 @@ public struct HTTPHeader: Hashable { extension HTTPHeader: CustomStringConvertible { public var description: String { - return "\(name): \(value)" + "\(name): \(value)" } } @@ -218,7 +221,7 @@ extension HTTPHeader { /// - Parameter value: The `Accept` value. /// - Returns: The header. public static func accept(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Accept", value: value) + HTTPHeader(name: "Accept", value: value) } /// Returns an `Accept-Charset` header. @@ -226,7 +229,7 @@ extension HTTPHeader { /// - Parameter value: The `Accept-Charset` value. /// - Returns: The header. public static func acceptCharset(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Accept-Charset", value: value) + HTTPHeader(name: "Accept-Charset", value: value) } /// Returns an `Accept-Language` header. @@ -238,7 +241,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func acceptLanguage(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Accept-Language", value: value) + HTTPHeader(name: "Accept-Language", value: value) } /// Returns an `Accept-Encoding` header. @@ -250,7 +253,7 @@ extension HTTPHeader { /// /// - Returns: The header public static func acceptEncoding(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Accept-Encoding", value: value) + HTTPHeader(name: "Accept-Encoding", value: value) } /// Returns a `Basic` `Authorization` header using the `username` and `password` provided. @@ -272,7 +275,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func authorization(bearerToken: String) -> HTTPHeader { - return authorization("Bearer \(bearerToken)") + authorization("Bearer \(bearerToken)") } /// Returns an `Authorization` header. @@ -285,7 +288,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func authorization(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Authorization", value: value) + HTTPHeader(name: "Authorization", value: value) } /// Returns a `Content-Disposition` header. @@ -294,7 +297,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func contentDisposition(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Content-Disposition", value: value) + HTTPHeader(name: "Content-Disposition", value: value) } /// Returns a `Content-Type` header. @@ -306,7 +309,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func contentType(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "Content-Type", value: value) + HTTPHeader(name: "Content-Type", value: value) } /// Returns a `User-Agent` header. @@ -315,7 +318,7 @@ extension HTTPHeader { /// /// - Returns: The header. public static func userAgent(_ value: String) -> HTTPHeader { - return HTTPHeader(name: "User-Agent", value: value) + HTTPHeader(name: "User-Agent", value: value) } } @@ -329,12 +332,12 @@ extension Array where Element == HTTPHeader { // MARK: - Defaults -public extension HTTPHeaders { +extension HTTPHeaders { /// The default set of `HTTPHeaders` used by Alamofire. Includes `Accept-Encoding`, `Accept-Language`, and /// `User-Agent`. - static let `default`: HTTPHeaders = [.defaultAcceptEncoding, - .defaultAcceptLanguage, - .defaultUserAgent] + public static let `default`: HTTPHeaders = [.defaultAcceptEncoding, + .defaultAcceptLanguage, + .defaultUserAgent] } extension HTTPHeader { @@ -357,9 +360,7 @@ extension HTTPHeader { /// `preferredLanguages`. /// /// See the [Accept-Language HTTP header documentation](https://tools.ietf.org/html/rfc7231#section-5.3.5). - public static let defaultAcceptLanguage: HTTPHeader = { - .acceptLanguage(Locale.preferredLanguages.prefix(6).qualityEncoded()) - }() + public static let defaultAcceptLanguage: HTTPHeader = .acceptLanguage(Locale.preferredLanguages.prefix(6).qualityEncoded()) /// Returns Alamofire's default `User-Agent` header. /// @@ -367,52 +368,53 @@ extension HTTPHeader { /// /// Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 13.0.0) Alamofire/5.0.0` public static let defaultUserAgent: HTTPHeader = { - let userAgent: String = { - if let info = Bundle.main.infoDictionary { - let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown" - let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown" - let appVersion = info["CFBundleShortVersionString"] as? String ?? "Unknown" - let appBuild = info[kCFBundleVersionKey as String] as? String ?? "Unknown" - - let osNameVersion: String = { - let version = ProcessInfo.processInfo.operatingSystemVersion - let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)" - // swiftformat:disable indent - let osName: String = { - #if os(iOS) - return "iOS" - #elseif os(watchOS) - return "watchOS" - #elseif os(tvOS) - return "tvOS" - #elseif os(macOS) - return "macOS" - #elseif os(Linux) - return "Linux" - #else - return "Unknown" - #endif - }() - // swiftformat:enable indent - - return "\(osName) \(versionString)" - }() - - let alamofireVersion = "Alamofire/\(version)" - - return "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)" - } - - return "Alamofire" + let info = Bundle.main.infoDictionary + let executable = (info?["CFBundleExecutable"] as? String) ?? + (ProcessInfo.processInfo.arguments.first?.split(separator: "/").last.map(String.init)) ?? + "Unknown" + let bundle = info?["CFBundleIdentifier"] as? String ?? "Unknown" + let appVersion = info?["CFBundleShortVersionString"] as? String ?? "Unknown" + let appBuild = info?["CFBundleVersion"] as? String ?? "Unknown" + + let osNameVersion: String = { + let version = ProcessInfo.processInfo.operatingSystemVersion + let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)" + let osName: String = { + #if os(iOS) + #if targetEnvironment(macCatalyst) + return "macOS(Catalyst)" + #else + return "iOS" + #endif + #elseif os(watchOS) + return "watchOS" + #elseif os(tvOS) + return "tvOS" + #elseif os(macOS) + return "macOS" + #elseif os(Linux) + return "Linux" + #elseif os(Windows) + return "Windows" + #else + return "Unknown" + #endif + }() + + return "\(osName) \(versionString)" }() + let alamofireVersion = "Alamofire/\(version)" + + let userAgent = "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)" + return .userAgent(userAgent) }() } extension Collection where Element == String { func qualityEncoded() -> String { - return enumerated().map { index, encoding in + enumerated().map { index, encoding in let quality = 1.0 - (Double(index) * 0.1) return "\(encoding);q=\(quality)" }.joined(separator: ", ") @@ -424,7 +426,7 @@ extension Collection where Element == String { extension URLRequest { /// Returns `allHTTPHeaderFields` as `HTTPHeaders`. public var headers: HTTPHeaders { - get { return allHTTPHeaderFields.map(HTTPHeaders.init) ?? HTTPHeaders() } + get { allHTTPHeaderFields.map(HTTPHeaders.init) ?? HTTPHeaders() } set { allHTTPHeaderFields = newValue.dictionary } } } @@ -432,14 +434,14 @@ extension URLRequest { extension HTTPURLResponse { /// Returns `allHeaderFields` as `HTTPHeaders`. public var headers: HTTPHeaders { - return (allHeaderFields as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() + (allHeaderFields as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() } } -public extension URLSessionConfiguration { +extension URLSessionConfiguration { /// Returns `httpAdditionalHeaders` as `HTTPHeaders`. - var headers: HTTPHeaders { - get { return (httpAdditionalHeaders as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() } + public var headers: HTTPHeaders { + get { (httpAdditionalHeaders as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() } set { httpAdditionalHeaders = newValue.dictionary } } } diff --git a/Pods/Alamofire/Source/MultipartFormData.swift b/Pods/Alamofire/Source/MultipartFormData.swift index 4ef54aa..8f72860 100644 --- a/Pods/Alamofire/Source/MultipartFormData.swift +++ b/Pods/Alamofire/Source/MultipartFormData.swift @@ -45,17 +45,20 @@ import CoreServices open class MultipartFormData { // MARK: - Helper Types - struct EncodingCharacters { + enum EncodingCharacters { static let crlf = "\r\n" } - struct BoundaryGenerator { + enum BoundaryGenerator { enum BoundaryType { case initial, encapsulated, final } static func randomBoundary() -> String { - return String(format: "alamofire.boundary.%08x%08x", arc4random(), arc4random()) + let first = UInt32.random(in: UInt32.min...UInt32.max) + let second = UInt32.random(in: UInt32.min...UInt32.max) + + return String(format: "alamofire.boundary.%08x%08x", first, second) } static func boundaryData(forBoundaryType boundaryType: BoundaryType, boundary: String) -> Data { @@ -97,7 +100,7 @@ open class MultipartFormData { open lazy var contentType: String = "multipart/form-data; boundary=\(self.boundary)" /// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries. - public var contentLength: UInt64 { return bodyParts.reduce(0) { $0 + $1.bodyContentLength } } + public var contentLength: UInt64 { bodyParts.reduce(0) { $0 + $1.bodyContentLength } } /// The boundary used to separate the body parts in the encoded form data. public let boundary: String @@ -210,6 +213,7 @@ open class MultipartFormData { // Check 2 - is file URL reachable? //============================================================ + #if !(os(Linux) || os(Windows)) do { let isReachable = try fileURL.checkPromisedItemIsReachable() guard isReachable else { @@ -220,6 +224,7 @@ open class MultipartFormData { setBodyPartError(withReason: .bodyPartFileNotReachableWithError(atURL: fileURL, error: error)) return } + #endif //============================================================ // Check 3 - is file URL a directory? @@ -416,6 +421,12 @@ open class MultipartFormData { } } + guard UInt64(encoded.count) == bodyPart.bodyContentLength else { + let error = AFError.UnexpectedInputStreamLength(bytesExpected: bodyPart.bodyContentLength, + bytesRead: UInt64(encoded.count)) + throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: error)) + } + return encoded } @@ -500,11 +511,13 @@ open class MultipartFormData { // MARK: - Private - Mime Type private func mimeType(forPathExtension pathExtension: String) -> String { + #if !(os(Linux) || os(Windows)) if let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(), let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue() { return contentType as String } + #endif return "application/octet-stream" } @@ -524,15 +537,15 @@ open class MultipartFormData { // MARK: - Private - Boundary Encoding private func initialBoundaryData() -> Data { - return BoundaryGenerator.boundaryData(forBoundaryType: .initial, boundary: boundary) + BoundaryGenerator.boundaryData(forBoundaryType: .initial, boundary: boundary) } private func encapsulatedBoundaryData() -> Data { - return BoundaryGenerator.boundaryData(forBoundaryType: .encapsulated, boundary: boundary) + BoundaryGenerator.boundaryData(forBoundaryType: .encapsulated, boundary: boundary) } private func finalBoundaryData() -> Data { - return BoundaryGenerator.boundaryData(forBoundaryType: .final, boundary: boundary) + BoundaryGenerator.boundaryData(forBoundaryType: .final, boundary: boundary) } // MARK: - Private - Errors diff --git a/Pods/Alamofire/Source/MultipartUpload.swift b/Pods/Alamofire/Source/MultipartUpload.swift index 4772c30..ceda21f 100644 --- a/Pods/Alamofire/Source/MultipartUpload.swift +++ b/Pods/Alamofire/Source/MultipartUpload.swift @@ -28,30 +28,25 @@ import Foundation final class MultipartUpload { lazy var result = Result { try build() } - let isInBackgroundSession: Bool - let multipartFormData: MultipartFormData + @Protected + private(set) var multipartFormData: MultipartFormData let encodingMemoryThreshold: UInt64 let request: URLRequestConvertible let fileManager: FileManager - init(isInBackgroundSession: Bool, - encodingMemoryThreshold: UInt64, + init(encodingMemoryThreshold: UInt64, request: URLRequestConvertible, multipartFormData: MultipartFormData) { - self.isInBackgroundSession = isInBackgroundSession self.encodingMemoryThreshold = encodingMemoryThreshold self.request = request fileManager = multipartFormData.fileManager self.multipartFormData = multipartFormData } - func build() throws -> (request: URLRequest, uploadable: UploadRequest.Uploadable) { - var urlRequest = try request.asURLRequest() - urlRequest.setValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") - + func build() throws -> UploadRequest.Uploadable { let uploadable: UploadRequest.Uploadable - if multipartFormData.contentLength < encodingMemoryThreshold && !isInBackgroundSession { - let data = try multipartFormData.encode() + if $multipartFormData.contentLength < encodingMemoryThreshold { + let data = try $multipartFormData.read { try $0.encode() } uploadable = .data(data) } else { @@ -63,25 +58,32 @@ final class MultipartUpload { try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil) do { - try multipartFormData.writeEncodedData(to: fileURL) + try $multipartFormData.read { try $0.writeEncodedData(to: fileURL) } } catch { // Cleanup after attempted write if it fails. try? fileManager.removeItem(at: fileURL) + throw error } uploadable = .file(fileURL, shouldRemove: true) } - return (request: urlRequest, uploadable: uploadable) + return uploadable } } extension MultipartUpload: UploadConvertible { func asURLRequest() throws -> URLRequest { - return try result.get().request + var urlRequest = try request.asURLRequest() + + $multipartFormData.read { multipartFormData in + urlRequest.headers.add(.contentType(multipartFormData.contentType)) + } + + return urlRequest } func createUploadable() throws -> UploadRequest.Uploadable { - return try result.get().uploadable + try result.get() } } diff --git a/Pods/Alamofire/Source/NetworkReachabilityManager.swift b/Pods/Alamofire/Source/NetworkReachabilityManager.swift index a07aa1d..deeb3a4 100644 --- a/Pods/Alamofire/Source/NetworkReachabilityManager.swift +++ b/Pods/Alamofire/Source/NetworkReachabilityManager.swift @@ -22,7 +22,7 @@ // THE SOFTWARE. // -#if !(os(watchOS) || os(Linux)) +#if !(os(watchOS) || os(Linux) || os(Windows)) import Foundation import SystemConfiguration @@ -72,17 +72,17 @@ open class NetworkReachabilityManager { // MARK: - Properties /// Whether the network is currently reachable. - open var isReachable: Bool { return isReachableOnCellular || isReachableOnEthernetOrWiFi } + open var isReachable: Bool { isReachableOnCellular || isReachableOnEthernetOrWiFi } /// Whether the network is currently reachable over the cellular interface. /// /// - Note: Using this property to decide whether to make a high or low bandwidth request is not recommended. /// Instead, set the `allowsCellularAccess` on any `URLRequest`s being issued. /// - open var isReachableOnCellular: Bool { return status == .reachable(.cellular) } + open var isReachableOnCellular: Bool { status == .reachable(.cellular) } /// Whether the network is currently reachable over Ethernet or WiFi interface. - open var isReachableOnEthernetOrWiFi: Bool { return status == .reachable(.ethernetOrWiFi) } + open var isReachableOnEthernetOrWiFi: Bool { status == .reachable(.ethernetOrWiFi) } /// `DispatchQueue` on which reachability will update. public let reachabilityQueue = DispatchQueue(label: "org.alamofire.reachabilityQueue") @@ -96,7 +96,7 @@ open class NetworkReachabilityManager { /// The current network reachability status. open var status: NetworkReachabilityStatus { - return flags.map(NetworkReachabilityStatus.init) ?? .unknown + flags.map(NetworkReachabilityStatus.init) ?? .unknown } /// Mutable state storage. @@ -113,7 +113,8 @@ open class NetworkReachabilityManager { private let reachability: SCNetworkReachability /// Protected storage for mutable state. - private let mutableState = Protector(MutableState()) + @Protected + private var mutableState = MutableState() // MARK: - Initialization @@ -167,13 +168,13 @@ open class NetworkReachabilityManager { onUpdatePerforming listener: @escaping Listener) -> Bool { stopListening() - mutableState.write { state in + $mutableState.write { state in state.listenerQueue = queue state.listener = listener } var context = SCNetworkReachabilityContext(version: 0, - info: Unmanaged.passRetained(self).toOpaque(), + info: Unmanaged.passUnretained(self).toOpaque(), retain: nil, release: nil, copyDescription: nil) @@ -201,7 +202,7 @@ open class NetworkReachabilityManager { open func stopListening() { SCNetworkReachabilitySetCallback(reachability, nil, nil) SCNetworkReachabilitySetDispatchQueue(reachability, nil) - mutableState.write { state in + $mutableState.write { state in state.listener = nil state.listenerQueue = nil state.previousStatus = nil @@ -218,7 +219,7 @@ open class NetworkReachabilityManager { func notifyListener(_ flags: SCNetworkReachabilityFlags) { let newStatus = NetworkReachabilityStatus(flags) - mutableState.write { state in + $mutableState.write { state in guard state.previousStatus != newStatus else { return } state.previousStatus = newStatus @@ -234,11 +235,11 @@ open class NetworkReachabilityManager { extension NetworkReachabilityManager.NetworkReachabilityStatus: Equatable {} extension SCNetworkReachabilityFlags { - var isReachable: Bool { return contains(.reachable) } - var isConnectionRequired: Bool { return contains(.connectionRequired) } - var canConnectAutomatically: Bool { return contains(.connectionOnDemand) || contains(.connectionOnTraffic) } - var canConnectWithoutUserInteraction: Bool { return canConnectAutomatically && !contains(.interventionRequired) } - var isActuallyReachable: Bool { return isReachable && (!isConnectionRequired || canConnectWithoutUserInteraction) } + var isReachable: Bool { contains(.reachable) } + var isConnectionRequired: Bool { contains(.connectionRequired) } + var canConnectAutomatically: Bool { contains(.connectionOnDemand) || contains(.connectionOnTraffic) } + var canConnectWithoutUserInteraction: Bool { canConnectAutomatically && !contains(.interventionRequired) } + var isActuallyReachable: Bool { isReachable && (!isConnectionRequired || canConnectWithoutUserInteraction) } var isCellular: Bool { #if os(iOS) || os(tvOS) return contains(.isWWAN) diff --git a/Pods/Alamofire/Source/Notifications.swift b/Pods/Alamofire/Source/Notifications.swift index 4a4b25a..66434b6 100644 --- a/Pods/Alamofire/Source/Notifications.swift +++ b/Pods/Alamofire/Source/Notifications.swift @@ -24,24 +24,24 @@ import Foundation -public extension Request { +extension Request { /// Posted when a `Request` is resumed. The `Notification` contains the resumed `Request`. - static let didResumeNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResume") + public static let didResumeNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResume") /// Posted when a `Request` is suspended. The `Notification` contains the suspended `Request`. - static let didSuspendNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspend") + public static let didSuspendNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspend") /// Posted when a `Request` is cancelled. The `Notification` contains the cancelled `Request`. - static let didCancelNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancel") + public static let didCancelNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancel") /// Posted when a `Request` is finished. The `Notification` contains the completed `Request`. - static let didFinishNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didFinish") + public static let didFinishNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didFinish") /// Posted when a `URLSessionTask` is resumed. The `Notification` contains the `Request` associated with the `URLSessionTask`. - static let didResumeTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResumeTask") + public static let didResumeTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResumeTask") /// Posted when a `URLSessionTask` is suspended. The `Notification` contains the `Request` associated with the `URLSessionTask`. - static let didSuspendTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspendTask") + public static let didSuspendTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspendTask") /// Posted when a `URLSessionTask` is cancelled. The `Notification` contains the `Request` associated with the `URLSessionTask`. - static let didCancelTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancelTask") + public static let didCancelTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancelTask") /// Posted when a `URLSessionTask` is completed. The `Notification` contains the `Request` associated with the `URLSessionTask`. - static let didCompleteTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCompleteTask") + public static let didCompleteTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCompleteTask") } // MARK: - @@ -49,7 +49,7 @@ public extension Request { extension Notification { /// The `Request` contained by the instance's `userInfo`, `nil` otherwise. public var request: Request? { - return userInfo?[String.requestKey] as? Request + userInfo?[String.requestKey] as? Request } /// Convenience initializer for a `Notification` containing a `Request` payload. diff --git a/Pods/Alamofire/Source/ParameterEncoder.swift b/Pods/Alamofire/Source/ParameterEncoder.swift index 1e5c70a..2263660 100644 --- a/Pods/Alamofire/Source/ParameterEncoder.swift +++ b/Pods/Alamofire/Source/ParameterEncoder.swift @@ -43,7 +43,7 @@ public protocol ParameterEncoder { /// If no `Content-Type` header is already set on the provided `URLRequest`s, it's set to `application/json`. open class JSONParameterEncoder: ParameterEncoder { /// Returns an encoder with default parameters. - public static var `default`: JSONParameterEncoder { return JSONParameterEncoder() } + public static var `default`: JSONParameterEncoder { JSONParameterEncoder() } /// Returns an encoder with `JSONEncoder.outputFormatting` set to `.prettyPrinted`. public static var prettyPrinted: JSONParameterEncoder { @@ -92,6 +92,21 @@ open class JSONParameterEncoder: ParameterEncoder { } } +#if swift(>=5.5) +extension ParameterEncoder where Self == JSONParameterEncoder { + /// Provides a default `JSONParameterEncoder` instance. + public static var json: JSONParameterEncoder { JSONParameterEncoder() } + + /// Creates a `JSONParameterEncoder` using the provided `JSONEncoder`. + /// + /// - Parameter encoder: `JSONEncoder` used to encode parameters. `JSONEncoder()` by default. + /// - Returns: The `JSONParameterEncoder`. + public static func json(encoder: JSONEncoder = JSONEncoder()) -> JSONParameterEncoder { + JSONParameterEncoder(encoder: encoder) + } +} +#endif + /// A `ParameterEncoder` that encodes types as URL-encoded query strings to be set on the URL or as body data, depending /// on the `Destination` set. /// @@ -125,7 +140,7 @@ open class URLEncodedFormParameterEncoder: ParameterEncoder { } /// Returns an encoder with default parameters. - public static var `default`: URLEncodedFormParameterEncoder { return URLEncodedFormParameterEncoder() } + public static var `default`: URLEncodedFormParameterEncoder { URLEncodedFormParameterEncoder() } /// The `URLEncodedFormEncoder` to use. public let encoder: URLEncodedFormEncoder @@ -159,7 +174,7 @@ open class URLEncodedFormParameterEncoder: ParameterEncoder { } if destination.encodesParametersInURL(for: method), - var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { + var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { let query: String = try Result { try encoder.encode(parameters) } .mapError { AFError.parameterEncoderFailed(reason: .encoderFailed(error: $0)) }.get() let newQueryString = [components.percentEncodedQuery, query].compactMap { $0 }.joinedWithAmpersands() @@ -182,3 +197,21 @@ open class URLEncodedFormParameterEncoder: ParameterEncoder { return request } } + +#if swift(>=5.5) +extension ParameterEncoder where Self == URLEncodedFormParameterEncoder { + /// Provides a default `URLEncodedFormParameterEncoder` instance. + public static var urlEncodedForm: URLEncodedFormParameterEncoder { URLEncodedFormParameterEncoder() } + + /// Creates a `URLEncodedFormParameterEncoder` with the provided encoder and destination. + /// + /// - Parameters: + /// - encoder: `URLEncodedFormEncoder` used to encode the parameters. `URLEncodedFormEncoder()` by default. + /// - destination: `Destination` to which to encode the parameters. `.methodDependent` by default. + /// - Returns: The `URLEncodedFormParameterEncoder`. + public static func urlEncodedForm(encoder: URLEncodedFormEncoder = URLEncodedFormEncoder(), + destination: URLEncodedFormParameterEncoder.Destination = .methodDependent) -> URLEncodedFormParameterEncoder { + URLEncodedFormParameterEncoder(encoder: encoder, destination: destination) + } +} +#endif diff --git a/Pods/Alamofire/Source/ParameterEncoding.swift b/Pods/Alamofire/Source/ParameterEncoding.swift index fbf1701..e7fa452 100644 --- a/Pods/Alamofire/Source/ParameterEncoding.swift +++ b/Pods/Alamofire/Source/ParameterEncoding.swift @@ -85,13 +85,17 @@ public struct URLEncoding: ParameterEncoding { case brackets /// No brackets are appended. The key is encoded as is. case noBrackets + /// Brackets containing the item index are appended. This matches the jQuery and Node.js behavior. + case indexInBrackets - func encode(key: String) -> String { + func encode(key: String, atIndex index: Int) -> String { switch self { case .brackets: return "\(key)[]" case .noBrackets: return key + case .indexInBrackets: + return "\(key)[\(index)]" } } } @@ -116,13 +120,13 @@ public struct URLEncoding: ParameterEncoding { // MARK: Properties /// Returns a default `URLEncoding` instance with a `.methodDependent` destination. - public static var `default`: URLEncoding { return URLEncoding() } + public static var `default`: URLEncoding { URLEncoding() } /// Returns a `URLEncoding` instance with a `.queryString` destination. - public static var queryString: URLEncoding { return URLEncoding(destination: .queryString) } + public static var queryString: URLEncoding { URLEncoding(destination: .queryString) } /// Returns a `URLEncoding` instance with an `.httpBody` destination. - public static var httpBody: URLEncoding { return URLEncoding(destination: .httpBody) } + public static var httpBody: URLEncoding { URLEncoding(destination: .httpBody) } /// The destination defining where the encoded query string is to be applied to the URL request. public let destination: Destination @@ -168,8 +172,8 @@ public struct URLEncoding: ParameterEncoding { urlRequest.url = urlComponents.url } } else { - if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { - urlRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type") + if urlRequest.headers["Content-Type"] == nil { + urlRequest.headers.update(.contentType("application/x-www-form-urlencoded; charset=utf-8")) } urlRequest.httpBody = Data(query(parameters).utf8) @@ -187,27 +191,26 @@ public struct URLEncoding: ParameterEncoding { /// - Returns: The percent-escaped, URL encoded query string components. public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] { var components: [(String, String)] = [] - - if let dictionary = value as? [String: Any] { + switch value { + case let dictionary as [String: Any]: for (nestedKey, value) in dictionary { components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value) } - } else if let array = value as? [Any] { - for value in array { - components += queryComponents(fromKey: arrayEncoding.encode(key: key), value: value) + case let array as [Any]: + for (index, value) in array.enumerated() { + components += queryComponents(fromKey: arrayEncoding.encode(key: key, atIndex: index), value: value) } - } else if let value = value as? NSNumber { - if value.isBool { - components.append((escape(key), escape(boolEncoding.encode(value: value.boolValue)))) + case let number as NSNumber: + if number.isBool { + components.append((escape(key), escape(boolEncoding.encode(value: number.boolValue)))) } else { - components.append((escape(key), escape("\(value)"))) + components.append((escape(key), escape("\(number)"))) } - } else if let bool = value as? Bool { + case let bool as Bool: components.append((escape(key), escape(boolEncoding.encode(value: bool)))) - } else { + default: components.append((escape(key), escape("\(value)"))) } - return components } @@ -217,7 +220,7 @@ public struct URLEncoding: ParameterEncoding { /// /// - Returns: The percent-escaped `String`. public func escape(_ string: String) -> String { - return string.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed) ?? string + string.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed) ?? string } private func query(_ parameters: [String: Any]) -> String { @@ -239,10 +242,10 @@ public struct JSONEncoding: ParameterEncoding { // MARK: Properties /// Returns a `JSONEncoding` instance with default writing options. - public static var `default`: JSONEncoding { return JSONEncoding() } + public static var `default`: JSONEncoding { JSONEncoding() } /// Returns a `JSONEncoding` instance with `.prettyPrinted` writing options. - public static var prettyPrinted: JSONEncoding { return JSONEncoding(options: .prettyPrinted) } + public static var prettyPrinted: JSONEncoding { JSONEncoding(options: .prettyPrinted) } /// The options for writing the parameters as JSON data. public let options: JSONSerialization.WritingOptions @@ -266,8 +269,8 @@ public struct JSONEncoding: ParameterEncoding { do { let data = try JSONSerialization.data(withJSONObject: parameters, options: options) - if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { - urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") + if urlRequest.headers["Content-Type"] == nil { + urlRequest.headers.update(.contentType("application/json")) } urlRequest.httpBody = data @@ -294,8 +297,8 @@ public struct JSONEncoding: ParameterEncoding { do { let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options) - if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { - urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") + if urlRequest.headers["Content-Type"] == nil { + urlRequest.headers.update(.contentType("application/json")) } urlRequest.httpBody = data @@ -310,5 +313,9 @@ public struct JSONEncoding: ParameterEncoding { // MARK: - extension NSNumber { - fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) } + fileprivate var isBool: Bool { + // Use Obj-C type encoding to check whether the underlying type is a `Bool`, as it's guaranteed as part of + // swift-corelibs-foundation, per [this discussion on the Swift forums](https://forums.swift.org/t/alamofire-on-linux-possible-but-not-release-ready/34553/22). + String(cString: objCType) == "c" + } } diff --git a/Pods/Alamofire/Source/Protector.swift b/Pods/Alamofire/Source/Protected.swift similarity index 62% rename from Pods/Alamofire/Source/Protector.swift rename to Pods/Alamofire/Source/Protected.swift index 3e42a53..2c056fa 100644 --- a/Pods/Alamofire/Source/Protector.swift +++ b/Pods/Alamofire/Source/Protected.swift @@ -1,7 +1,7 @@ // -// Protector.swift +// Protected.swift // -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) +// Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -24,10 +24,40 @@ import Foundation -// MARK: - +private protocol Lock { + func lock() + func unlock() +} +extension Lock { + /// Executes a closure returning a value while acquiring the lock. + /// + /// - Parameter closure: The closure to run. + /// + /// - Returns: The value the closure generated. + func around(_ closure: () throws -> T) rethrows -> T { + lock(); defer { unlock() } + return try closure() + } + + /// Execute a closure while acquiring the lock. + /// + /// - Parameter closure: The closure to run. + func around(_ closure: () throws -> Void) rethrows { + lock(); defer { unlock() } + try closure() + } +} + +#if os(Linux) || os(Windows) + +extension NSLock: Lock {} + +#endif + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) /// An `os_unfair_lock` wrapper. -final class UnfairLock { +final class UnfairLock: Lock { private let unfairLock: os_unfair_lock_t init() { @@ -40,36 +70,25 @@ final class UnfairLock { unfairLock.deallocate() } - private func lock() { + fileprivate func lock() { os_unfair_lock_lock(unfairLock) } - private func unlock() { + fileprivate func unlock() { os_unfair_lock_unlock(unfairLock) } - - /// Executes a closure returning a value while acquiring the lock. - /// - /// - Parameter closure: The closure to run. - /// - /// - Returns: The value the closure generated. - func around(_ closure: () -> T) -> T { - lock(); defer { unlock() } - return closure() - } - - /// Execute a closure while acquiring the lock. - /// - /// - Parameter closure: The closure to run. - func around(_ closure: () -> Void) { - lock(); defer { unlock() } - return closure() - } } +#endif /// A thread-safe wrapper around a value. -final class Protector { +@propertyWrapper +@dynamicMemberLookup +final class Protected { + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) private let lock = UnfairLock() + #elseif os(Linux) || os(Windows) + private let lock = NSLock() + #endif private var value: T init(_ value: T) { @@ -77,18 +96,24 @@ final class Protector { } /// The contained value. Unsafe for anything more than direct read or write. - var directValue: T { - get { return lock.around { value } } + var wrappedValue: T { + get { lock.around { value } } set { lock.around { value = newValue } } } + var projectedValue: Protected { self } + + init(wrappedValue: T) { + value = wrappedValue + } + /// Synchronously read or transform the contained value. /// /// - Parameter closure: The closure to execute. /// /// - Returns: The return value of the closure passed. - func read(_ closure: (T) -> U) -> U { - return lock.around { closure(self.value) } + func read(_ closure: (T) throws -> U) rethrows -> U { + try lock.around { try closure(self.value) } } /// Synchronously modify the protected value. @@ -97,59 +122,28 @@ final class Protector { /// /// - Returns: The modified value. @discardableResult - func write(_ closure: (inout T) -> U) -> U { - return lock.around { closure(&self.value) } + func write(_ closure: (inout T) throws -> U) rethrows -> U { + try lock.around { try closure(&self.value) } } -} -extension Protector where T: RangeReplaceableCollection { - /// Adds a new element to the end of this protected collection. - /// - /// - Parameter newElement: The `Element` to append. - func append(_ newElement: T.Element) { - write { (ward: inout T) in - ward.append(newElement) - } - } - - /// Adds the elements of a sequence to the end of this protected collection. - /// - /// - Parameter newElements: The `Sequence` to append. - func append(contentsOf newElements: S) where S.Element == T.Element { - write { (ward: inout T) in - ward.append(contentsOf: newElements) - } - } - - /// Add the elements of a collection to the end of the protected collection. - /// - /// - Parameter newElements: The `Collection` to append. - func append(contentsOf newElements: C) where C.Element == T.Element { - write { (ward: inout T) in - ward.append(contentsOf: newElements) - } + subscript(dynamicMember keyPath: WritableKeyPath) -> Property { + get { lock.around { value[keyPath: keyPath] } } + set { lock.around { value[keyPath: keyPath] = newValue } } } -} -extension Protector where T == Data? { - /// Adds the contents of a `Data` value to the end of the protected `Data`. - /// - /// - Parameter data: The `Data` to be appended. - func append(_ data: Data) { - write { (ward: inout T) in - ward?.append(data) - } + subscript(dynamicMember keyPath: KeyPath) -> Property { + lock.around { value[keyPath: keyPath] } } } -extension Protector where T == Request.MutableState { +extension Protected where T == Request.MutableState { /// Attempts to transition to the passed `State`. /// /// - Parameter state: The `State` to attempt transition to. /// /// - Returns: Whether the transition occurred. func attemptToTransitionTo(_ state: Request.State) -> Bool { - return lock.around { + lock.around { guard value.state.canTransitionTo(state) else { return false } value.state = state diff --git a/Pods/Alamofire/Source/RedirectHandler.swift b/Pods/Alamofire/Source/RedirectHandler.swift index b6c069c..5c232b8 100644 --- a/Pods/Alamofire/Source/RedirectHandler.swift +++ b/Pods/Alamofire/Source/RedirectHandler.swift @@ -93,3 +93,21 @@ extension Redirector: RedirectHandler { } } } + +#if swift(>=5.5) +extension RedirectHandler where Self == Redirector { + /// Provides a `Redirector` which follows redirects. Equivalent to `Redirector.follow`. + public static var follow: Redirector { .follow } + + /// Provides a `Redirector` which does not follow redirects. Equivalent to `Redirector.doNotFollow`. + public static var doNotFollow: Redirector { .doNotFollow } + + /// Creates a `Redirector` which modifies the redirected `URLRequest` using the provided closure. + /// + /// - Parameter closure: Closure used to modify the redirect. + /// - Returns: The `Redirector`. + public static func modify(using closure: @escaping (URLSessionTask, URLRequest, HTTPURLResponse) -> URLRequest?) -> Redirector { + Redirector(behavior: .modify(closure)) + } +} +#endif diff --git a/Pods/Alamofire/Source/Request.swift b/Pods/Alamofire/Source/Request.swift index 3fa1eb5..fdbdf11 100644 --- a/Pods/Alamofire/Source/Request.swift +++ b/Pods/Alamofire/Source/Request.swift @@ -1,7 +1,7 @@ // // Request.swift // -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) +// Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -92,8 +92,12 @@ public class Request { var redirectHandler: RedirectHandler? /// `CachedResponseHandler` provided to handle response caching. var cachedResponseHandler: CachedResponseHandler? - /// Closure called when the `Request` is able to create a cURL description of itself. - var cURLHandler: ((String) -> Void)? + /// Queue and closure called when the `Request` is able to create a cURL description of itself. + var cURLHandler: (queue: DispatchQueue, handler: (String) -> Void)? + /// Queue and closure called when the `Request` creates a `URLRequest`. + var urlRequestHandler: (queue: DispatchQueue, handler: (URLRequest) -> Void)? + /// Queue and closure called when the `Request` creates a `URLSessionTask`. + var urlSessionTaskHandler: (queue: DispatchQueue, handler: (URLSessionTask) -> Void)? /// Response serialization closures that handle response parsing. var responseSerializers: [() -> Void] = [] /// Response serialization completion closures executed once all response serializers are complete. @@ -116,23 +120,26 @@ public class Request { /// Whether the instance has had `finish()` called and is running the serializers. Should be replaced with a /// representation in the state machine in the future. var isFinishing = false + /// Actions to run when requests are finished. Use for concurrency support. + var finishHandlers: [() -> Void] = [] } /// Protected `MutableState` value that provides thread-safe access to state values. - fileprivate let protectedMutableState: Protector = Protector(MutableState()) + @Protected + fileprivate var mutableState = MutableState() /// `State` of the `Request`. - public var state: State { return protectedMutableState.directValue.state } + public var state: State { $mutableState.state } /// Returns whether `state` is `.initialized`. - public var isInitialized: Bool { return state == .initialized } + public var isInitialized: Bool { state == .initialized } /// Returns whether `state is `.resumed`. - public var isResumed: Bool { return state == .resumed } + public var isResumed: Bool { state == .resumed } /// Returns whether `state` is `.suspended`. - public var isSuspended: Bool { return state == .suspended } + public var isSuspended: Bool { state == .suspended } /// Returns whether `state` is `.cancelled`. - public var isCancelled: Bool { return state == .cancelled } + public var isCancelled: Bool { state == .cancelled } /// Returns whether `state` is `.finished`. - public var isFinished: Bool { return state == .finished } + public var isFinished: Bool { state == .finished } // MARK: Progress @@ -144,102 +151,101 @@ public class Request { /// `Progress` of the download of any response data. Reset to `0` if the `Request` is retried. public let downloadProgress = Progress(totalUnitCount: 0) /// `ProgressHandler` called when `uploadProgress` is updated, on the provided `DispatchQueue`. - fileprivate var uploadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? { - get { return protectedMutableState.directValue.uploadProgressHandler } - set { protectedMutableState.write { $0.uploadProgressHandler = newValue } } + private var uploadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? { + get { $mutableState.uploadProgressHandler } + set { $mutableState.uploadProgressHandler = newValue } } /// `ProgressHandler` called when `downloadProgress` is updated, on the provided `DispatchQueue`. fileprivate var downloadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? { - get { return protectedMutableState.directValue.downloadProgressHandler } - set { protectedMutableState.write { $0.downloadProgressHandler = newValue } } + get { $mutableState.downloadProgressHandler } + set { $mutableState.downloadProgressHandler = newValue } } // MARK: Redirect Handling /// `RedirectHandler` set on the instance. public private(set) var redirectHandler: RedirectHandler? { - get { return protectedMutableState.directValue.redirectHandler } - set { protectedMutableState.write { $0.redirectHandler = newValue } } + get { $mutableState.redirectHandler } + set { $mutableState.redirectHandler = newValue } } // MARK: Cached Response Handling /// `CachedResponseHandler` set on the instance. public private(set) var cachedResponseHandler: CachedResponseHandler? { - get { return protectedMutableState.directValue.cachedResponseHandler } - set { protectedMutableState.write { $0.cachedResponseHandler = newValue } } + get { $mutableState.cachedResponseHandler } + set { $mutableState.cachedResponseHandler = newValue } } // MARK: URLCredential /// `URLCredential` used for authentication challenges. Created by calling one of the `authenticate` methods. public private(set) var credential: URLCredential? { - get { return protectedMutableState.directValue.credential } - set { protectedMutableState.write { $0.credential = newValue } } + get { $mutableState.credential } + set { $mutableState.credential = newValue } } // MARK: Validators /// `Validator` callback closures that store the validation calls enqueued. - fileprivate var protectedValidators: Protector<[() -> Void]> = Protector([]) + @Protected + fileprivate var validators: [() -> Void] = [] // MARK: URLRequests /// All `URLRequests` created on behalf of the `Request`, including original and adapted requests. - public var requests: [URLRequest] { return protectedMutableState.directValue.requests } + public var requests: [URLRequest] { $mutableState.requests } /// First `URLRequest` created on behalf of the `Request`. May not be the first one actually executed. - public var firstRequest: URLRequest? { return requests.first } + public var firstRequest: URLRequest? { requests.first } /// Last `URLRequest` created on behalf of the `Request`. - public var lastRequest: URLRequest? { return requests.last } + public var lastRequest: URLRequest? { requests.last } /// Current `URLRequest` created on behalf of the `Request`. - public var request: URLRequest? { return lastRequest } + public var request: URLRequest? { lastRequest } /// `URLRequest`s from all of the `URLSessionTask`s executed on behalf of the `Request`. May be different from /// `requests` due to `URLSession` manipulation. - public var performedRequests: [URLRequest] { - return protectedMutableState.read { $0.tasks.compactMap { $0.currentRequest } } - } + public var performedRequests: [URLRequest] { $mutableState.read { $0.tasks.compactMap(\.currentRequest) } } // MARK: HTTPURLResponse /// `HTTPURLResponse` received from the server, if any. If the `Request` was retried, this is the response of the /// last `URLSessionTask`. - public var response: HTTPURLResponse? { return lastTask?.response as? HTTPURLResponse } + public var response: HTTPURLResponse? { lastTask?.response as? HTTPURLResponse } // MARK: Tasks /// All `URLSessionTask`s created on behalf of the `Request`. - public var tasks: [URLSessionTask] { return protectedMutableState.directValue.tasks } + public var tasks: [URLSessionTask] { $mutableState.tasks } /// First `URLSessionTask` created on behalf of the `Request`. - public var firstTask: URLSessionTask? { return tasks.first } + public var firstTask: URLSessionTask? { tasks.first } /// Last `URLSessionTask` crated on behalf of the `Request`. - public var lastTask: URLSessionTask? { return tasks.last } + public var lastTask: URLSessionTask? { tasks.last } /// Current `URLSessionTask` created on behalf of the `Request`. - public var task: URLSessionTask? { return lastTask } + public var task: URLSessionTask? { lastTask } // MARK: Metrics /// All `URLSessionTaskMetrics` gathered on behalf of the `Request`. Should correspond to the `tasks` created. - public var allMetrics: [URLSessionTaskMetrics] { return protectedMutableState.directValue.metrics } + public var allMetrics: [URLSessionTaskMetrics] { $mutableState.metrics } /// First `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var firstMetrics: URLSessionTaskMetrics? { return allMetrics.first } + public var firstMetrics: URLSessionTaskMetrics? { allMetrics.first } /// Last `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var lastMetrics: URLSessionTaskMetrics? { return allMetrics.last } + public var lastMetrics: URLSessionTaskMetrics? { allMetrics.last } /// Current `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var metrics: URLSessionTaskMetrics? { return lastMetrics } + public var metrics: URLSessionTaskMetrics? { lastMetrics } // MARK: Retry Count /// Number of times the `Request` has been retried. - public var retryCount: Int { return protectedMutableState.directValue.retryCount } + public var retryCount: Int { $mutableState.retryCount } // MARK: Error /// `Error` returned from Alamofire internally, from the network request directly, or any validators executed. public fileprivate(set) var error: AFError? { - get { return protectedMutableState.directValue.error } - set { protectedMutableState.write { $0.error = newValue } } + get { $mutableState.error } + set { $mutableState.error = newValue } } /// Default initializer for the `Request` superclass. @@ -277,7 +283,7 @@ public class Request { func didCreateInitialURLRequest(_ request: URLRequest) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - protectedMutableState.write { $0.requests.append(request) } + $mutableState.write { $0.requests.append(request) } eventMonitor?.request(self, didCreateInitialURLRequest: request) } @@ -307,7 +313,7 @@ public class Request { func didAdaptInitialRequest(_ initialRequest: URLRequest, to adaptedRequest: URLRequest) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - protectedMutableState.write { $0.requests.append(adaptedRequest) } + $mutableState.write { $0.requests.append(adaptedRequest) } eventMonitor?.request(self, didAdaptInitialRequest: initialRequest, to: adaptedRequest) } @@ -337,6 +343,10 @@ public class Request { func didCreateURLRequest(_ request: URLRequest) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) + $mutableState.read { state in + state.urlRequestHandler?.queue.async { state.urlRequestHandler?.handler(request) } + } + eventMonitor?.request(self, didCreateURLRequest: request) callCURLHandlerIfNecessary() @@ -344,10 +354,11 @@ public class Request { /// Asynchronously calls any stored `cURLHandler` and then removes it from `mutableState`. private func callCURLHandlerIfNecessary() { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in guard let cURLHandler = mutableState.cURLHandler else { return } - self.underlyingQueue.async { cURLHandler(self.cURLDescription()) } + cURLHandler.queue.async { cURLHandler.handler(self.cURLDescription()) } + mutableState.cURLHandler = nil } } @@ -358,7 +369,13 @@ public class Request { func didCreateTask(_ task: URLSessionTask) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - protectedMutableState.write { $0.tasks.append(task) } + $mutableState.write { state in + state.tasks.append(task) + + guard let urlSessionTaskHandler = state.urlSessionTaskHandler else { return } + + urlSessionTaskHandler.queue.async { urlSessionTaskHandler.handler(task) } + } eventMonitor?.request(self, didCreateTask: task) } @@ -399,7 +416,7 @@ public class Request { func didCancel() { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - error = AFError.explicitlyCancelled + error = error ?? AFError.explicitlyCancelled eventMonitor?.requestDidCancel(self) } @@ -419,7 +436,7 @@ public class Request { func didGatherMetrics(_ metrics: URLSessionTaskMetrics) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - protectedMutableState.write { $0.metrics.append(metrics) } + $mutableState.write { $0.metrics.append(metrics) } eventMonitor?.request(self, didGatherMetrics: metrics) } @@ -451,7 +468,7 @@ public class Request { self.error = self.error ?? error - protectedValidators.directValue.forEach { $0() } + validators.forEach { $0() } eventMonitor?.request(self, didCompleteTask: task, with: error) @@ -462,7 +479,7 @@ public class Request { func prepareForRetry() { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - protectedMutableState.write { $0.retryCount += 1 } + $mutableState.write { $0.retryCount += 1 } reset() @@ -496,9 +513,9 @@ public class Request { func finish(error: AFError? = nil) { dispatchPrecondition(condition: .onQueue(underlyingQueue)) - guard !protectedMutableState.directValue.isFinishing else { return } + guard !$mutableState.isFinishing else { return } - protectedMutableState.directValue.isFinishing = true + $mutableState.isFinishing = true if let error = error { self.error = error } @@ -514,7 +531,7 @@ public class Request { /// /// - Parameter closure: The closure containing the response serialization call. func appendResponseSerializer(_ closure: @escaping () -> Void) { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in mutableState.responseSerializers.append(closure) if mutableState.state == .finished { @@ -537,7 +554,7 @@ public class Request { func nextResponseSerializer() -> (() -> Void)? { var responseSerializer: (() -> Void)? - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in let responseSerializerIndex = mutableState.responseSerializerCompletions.count if responseSerializerIndex < mutableState.responseSerializers.count { @@ -554,7 +571,7 @@ public class Request { // Execute all response serializer completions and clear them var completions: [() -> Void] = [] - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in completions = mutableState.responseSerializerCompletions // Clear out all response serializers and response serializer completions in mutable state since the @@ -588,7 +605,7 @@ public class Request { /// - Parameter completion: The completion handler provided with the response serializer, called when all serializers /// are complete. func responseSerializerDidComplete(completion: @escaping () -> Void) { - protectedMutableState.write { $0.responseSerializerCompletions.append(completion) } + $mutableState.write { $0.responseSerializerCompletions.append(completion) } processNextResponseSerializer() } @@ -601,7 +618,7 @@ public class Request { downloadProgress.totalUnitCount = 0 downloadProgress.completedUnitCount = 0 - protectedMutableState.write { state in + $mutableState.write { state in state.isFinishing = false state.responseSerializerCompletions = [] } @@ -623,7 +640,7 @@ public class Request { /// /// - Parameter perform: The closure to perform. func withState(perform: (State) -> Void) { - protectedMutableState.withState(perform: perform) + $mutableState.withState(perform: perform) } // MARK: Task Creation @@ -650,7 +667,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func cancel() -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in guard mutableState.state.canTransitionTo(.cancelled) else { return } mutableState.state = .cancelled @@ -676,7 +693,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func suspend() -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in guard mutableState.state.canTransitionTo(.suspended) else { return } mutableState.state = .suspended @@ -697,7 +714,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func resume() -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in guard mutableState.state.canTransitionTo(.resumed) else { return } mutableState.state = .resumed @@ -737,7 +754,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func authenticate(with credential: URLCredential) -> Self { - protectedMutableState.write { $0.credential = credential } + $mutableState.credential = credential return self } @@ -753,7 +770,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func downloadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self { - protectedMutableState.write { $0.downloadProgressHandler = (handler: closure, queue: queue) } + $mutableState.downloadProgressHandler = (handler: closure, queue: queue) return self } @@ -769,7 +786,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func uploadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self { - protectedMutableState.write { $0.uploadProgressHandler = (handler: closure, queue: queue) } + $mutableState.uploadProgressHandler = (handler: closure, queue: queue) return self } @@ -785,7 +802,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func redirect(using handler: RedirectHandler) -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in precondition(mutableState.redirectHandler == nil, "Redirect handler has already been set.") mutableState.redirectHandler = handler } @@ -804,7 +821,7 @@ public class Request { /// - Returns: The instance. @discardableResult public func cacheResponse(using handler: CachedResponseHandler) -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in precondition(mutableState.cachedResponseHandler == nil, "Cached response handler has already been set.") mutableState.cachedResponseHandler = handler } @@ -812,21 +829,92 @@ public class Request { return self } + // MARK: - Lifetime APIs + /// Sets a handler to be called when the cURL description of the request is available. /// /// - Note: When waiting for a `Request`'s `URLRequest` to be created, only the last `handler` will be called. /// - /// - Parameter handler: Closure to be called when the cURL description is available. + /// - Parameters: + /// - queue: `DispatchQueue` on which `handler` will be called. + /// - handler: Closure to be called when the cURL description is available. + /// + /// - Returns: The instance. + @discardableResult + public func cURLDescription(on queue: DispatchQueue, calling handler: @escaping (String) -> Void) -> Self { + $mutableState.write { mutableState in + if mutableState.requests.last != nil { + queue.async { handler(self.cURLDescription()) } + } else { + mutableState.cURLHandler = (queue, handler) + } + } + + return self + } + + /// Sets a handler to be called when the cURL description of the request is available. + /// + /// - Note: When waiting for a `Request`'s `URLRequest` to be created, only the last `handler` will be called. + /// + /// - Parameter handler: Closure to be called when the cURL description is available. Called on the instance's + /// `underlyingQueue` by default. /// /// - Returns: The instance. @discardableResult public func cURLDescription(calling handler: @escaping (String) -> Void) -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in if mutableState.requests.last != nil { underlyingQueue.async { handler(self.cURLDescription()) } } else { - mutableState.cURLHandler = handler + mutableState.cURLHandler = (underlyingQueue, handler) + } + } + + return self + } + + /// Sets a closure to called whenever Alamofire creates a `URLRequest` for this instance. + /// + /// - Note: This closure will be called multiple times if the instance adapts incoming `URLRequest`s or is retried. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which `handler` will be called. `.main` by default. + /// - handler: Closure to be called when a `URLRequest` is available. + /// + /// - Returns: The instance. + @discardableResult + public func onURLRequestCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLRequest) -> Void) -> Self { + $mutableState.write { state in + if let request = state.requests.last { + queue.async { handler(request) } } + + state.urlRequestHandler = (queue, handler) + } + + return self + } + + /// Sets a closure to be called whenever the instance creates a `URLSessionTask`. + /// + /// - Note: This API should only be used to provide `URLSessionTask`s to existing API, like `NSFileProvider`. It + /// **SHOULD NOT** be used to interact with tasks directly, as that may be break Alamofire features. + /// Additionally, this closure may be called multiple times if the instance is retried. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which `handler` will be called. `.main` by default. + /// - handler: Closure to be called when the `URLSessionTask` is available. + /// + /// - Returns: The instance. + @discardableResult + public func onURLSessionTaskCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLSessionTask) -> Void) -> Self { + $mutableState.write { state in + if let task = state.tasks.last { + queue.async { handler(task) } + } + + state.urlSessionTaskHandler = (queue, handler) } return self @@ -834,10 +922,25 @@ public class Request { // MARK: Cleanup + /// Adds a `finishHandler` closure to be called when the request completes. + /// + /// - Parameter closure: Closure to be called when the request finishes. + func onFinish(perform finishHandler: @escaping () -> Void) { + guard !isFinished else { finishHandler(); return } + + $mutableState.write { state in + state.finishHandlers.append(finishHandler) + } + } + /// Final cleanup step executed when the instance finishes response serialization. func cleanup() { delegate?.cleanup(after: self) - // No-op: override in subclass + let handlers = $mutableState.finishHandlers + handlers.forEach { $0() } + $mutableState.write { state in + state.finishHandlers.removeAll() + } } } @@ -845,7 +948,7 @@ public class Request { extension Request: Equatable { public static func ==(lhs: Request, rhs: Request) -> Bool { - return lhs.id == rhs.id + lhs.id == rhs.id } } @@ -860,8 +963,8 @@ extension Request: CustomStringConvertible { /// created, as well as the response status code, if a response has been received. public var description: String { guard let request = performedRequests.last ?? lastRequest, - let url = request.url, - let method = request.httpMethod else { return "No request created yet." } + let url = request.url, + let method = request.httpMethod else { return "No request created yet." } let requestDescription = "\(method) \(url.absoluteString)" @@ -982,10 +1085,11 @@ public class DataRequest: Request { /// `URLRequestConvertible` value used to create `URLRequest`s for this instance. public let convertible: URLRequestConvertible /// `Data` read from the server so far. - public var data: Data? { return protectedData.directValue } + public var data: Data? { mutableData } /// Protected storage for the `Data` read by the instance. - private var protectedData: Protector = Protector(nil) + @Protected + private var mutableData: Data? = nil /// Creates a `DataRequest` using the provided parameters. /// @@ -1018,7 +1122,7 @@ public class DataRequest: Request { override func reset() { super.reset() - protectedData.directValue = nil + mutableData = nil } /// Called when `Data` is received by this instance. @@ -1028,9 +1132,9 @@ public class DataRequest: Request { /// - Parameter data: The `Data` received. func didReceive(data: Data) { if self.data == nil { - protectedData.directValue = data + mutableData = data } else { - protectedData.append(data) + $mutableData.write { $0?.append(data) } } updateDownloadProgress() @@ -1075,12 +1179,284 @@ public class DataRequest: Request { withResult: result) } - protectedValidators.append(validator) + $validators.write { $0.append(validator) } return self } } +// MARK: - DataStreamRequest + +/// `Request` subclass which streams HTTP response `Data` through a `Handler` closure. +public final class DataStreamRequest: Request { + /// Closure type handling `DataStreamRequest.Stream` values. + public typealias Handler = (Stream) throws -> Void + + /// Type encapsulating an `Event` as it flows through the stream, as well as a `CancellationToken` which can be used + /// to stop the stream at any time. + public struct Stream { + /// Latest `Event` from the stream. + public let event: Event + /// Token used to cancel the stream. + public let token: CancellationToken + + /// Cancel the ongoing stream by canceling the underlying `DataStreamRequest`. + public func cancel() { + token.cancel() + } + } + + /// Type representing an event flowing through the stream. Contains either the `Result` of processing streamed + /// `Data` or the completion of the stream. + public enum Event { + /// Output produced every time the instance receives additional `Data`. The associated value contains the + /// `Result` of processing the incoming `Data`. + case stream(Result) + /// Output produced when the instance has completed, whether due to stream end, cancellation, or an error. + /// Associated `Completion` value contains the final state. + case complete(Completion) + } + + /// Value containing the state of a `DataStreamRequest` when the stream was completed. + public struct Completion { + /// Last `URLRequest` issued by the instance. + public let request: URLRequest? + /// Last `HTTPURLResponse` received by the instance. + public let response: HTTPURLResponse? + /// Last `URLSessionTaskMetrics` produced for the instance. + public let metrics: URLSessionTaskMetrics? + /// `AFError` produced for the instance, if any. + public let error: AFError? + } + + /// Type used to cancel an ongoing stream. + public struct CancellationToken { + weak var request: DataStreamRequest? + + init(_ request: DataStreamRequest) { + self.request = request + } + + /// Cancel the ongoing stream by canceling the underlying `DataStreamRequest`. + public func cancel() { + request?.cancel() + } + } + + /// `URLRequestConvertible` value used to create `URLRequest`s for this instance. + public let convertible: URLRequestConvertible + /// Whether or not the instance will be cancelled if stream parsing encounters an error. + public let automaticallyCancelOnStreamError: Bool + + /// Internal mutable state specific to this type. + struct StreamMutableState { + /// `OutputStream` bound to the `InputStream` produced by `asInputStream`, if it has been called. + var outputStream: OutputStream? + /// Stream closures called as `Data` is received. + var streams: [(_ data: Data) -> Void] = [] + /// Number of currently executing streams. Used to ensure completions are only fired after all streams are + /// enqueued. + var numberOfExecutingStreams = 0 + /// Completion calls enqueued while streams are still executing. + var enqueuedCompletionEvents: [() -> Void] = [] + } + + @Protected + var streamMutableState = StreamMutableState() + + /// Creates a `DataStreamRequest` using the provided parameters. + /// + /// - Parameters: + /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` + /// by default. + /// - convertible: `URLRequestConvertible` value used to create `URLRequest`s for this + /// instance. + /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance will be cancelled when an `Error` + /// is thrown while serializing stream `Data`. + /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. + /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default + /// targets + /// `underlyingQueue`, but can be passed another queue from a `Session`. + /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. + /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. + /// - delegate: `RequestDelegate` that provides an interface to actions not performed by + /// the `Request`. + init(id: UUID = UUID(), + convertible: URLRequestConvertible, + automaticallyCancelOnStreamError: Bool, + underlyingQueue: DispatchQueue, + serializationQueue: DispatchQueue, + eventMonitor: EventMonitor?, + interceptor: RequestInterceptor?, + delegate: RequestDelegate) { + self.convertible = convertible + self.automaticallyCancelOnStreamError = automaticallyCancelOnStreamError + + super.init(id: id, + underlyingQueue: underlyingQueue, + serializationQueue: serializationQueue, + eventMonitor: eventMonitor, + interceptor: interceptor, + delegate: delegate) + } + + override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { + let copiedRequest = request + return session.dataTask(with: copiedRequest) + } + + override func finish(error: AFError? = nil) { + $streamMutableState.write { state in + state.outputStream?.close() + } + + super.finish(error: error) + } + + func didReceive(data: Data) { + $streamMutableState.write { state in + #if !(os(Linux) || os(Windows)) + if let stream = state.outputStream { + underlyingQueue.async { + var bytes = Array(data) + stream.write(&bytes, maxLength: bytes.count) + } + } + #endif + state.numberOfExecutingStreams += state.streams.count + let localState = state + underlyingQueue.async { localState.streams.forEach { $0(data) } } + } + } + + /// Validates the `URLRequest` and `HTTPURLResponse` received for the instance using the provided `Validation` closure. + /// + /// - Parameter validation: `Validation` closure used to validate the request and response. + /// + /// - Returns: The `DataStreamRequest`. + @discardableResult + public func validate(_ validation: @escaping Validation) -> Self { + let validator: () -> Void = { [unowned self] in + guard self.error == nil, let response = self.response else { return } + + let result = validation(self.request, response) + + if case let .failure(error) = result { + self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) + } + + self.eventMonitor?.request(self, + didValidateRequest: self.request, + response: response, + withResult: result) + } + + $validators.write { $0.append(validator) } + + return self + } + + #if !(os(Linux) || os(Windows)) + /// Produces an `InputStream` that receives the `Data` received by the instance. + /// + /// - Note: The `InputStream` produced by this method must have `open()` called before being able to read `Data`. + /// Additionally, this method will automatically call `resume()` on the instance, regardless of whether or + /// not the creating session has `startRequestsImmediately` set to `true`. + /// + /// - Parameter bufferSize: Size, in bytes, of the buffer between the `OutputStream` and `InputStream`. + /// + /// - Returns: The `InputStream` bound to the internal `OutboundStream`. + public func asInputStream(bufferSize: Int = 1024) -> InputStream? { + defer { resume() } + + var inputStream: InputStream? + $streamMutableState.write { state in + Foundation.Stream.getBoundStreams(withBufferSize: bufferSize, + inputStream: &inputStream, + outputStream: &state.outputStream) + state.outputStream?.open() + } + + return inputStream + } + #endif + + func capturingError(from closure: () throws -> Void) { + do { + try closure() + } catch { + self.error = error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) + cancel() + } + } + + func appendStreamCompletion(on queue: DispatchQueue, + stream: @escaping Handler) { + appendResponseSerializer { + self.underlyingQueue.async { + self.responseSerializerDidComplete { + self.$streamMutableState.write { state in + guard state.numberOfExecutingStreams == 0 else { + state.enqueuedCompletionEvents.append { + self.enqueueCompletion(on: queue, stream: stream) + } + + return + } + + self.enqueueCompletion(on: queue, stream: stream) + } + } + } + } + } + + func enqueueCompletion(on queue: DispatchQueue, + stream: @escaping Handler) { + queue.async { + do { + let completion = Completion(request: self.request, + response: self.response, + metrics: self.metrics, + error: self.error) + try stream(.init(event: .complete(completion), token: .init(self))) + } catch { + // Ignore error, as errors on Completion can't be handled anyway. + } + } + } +} + +extension DataStreamRequest.Stream { + /// Incoming `Result` values from `Event.stream`. + public var result: Result? { + guard case let .stream(result) = event else { return nil } + + return result + } + + /// `Success` value of the instance, if any. + public var value: Success? { + guard case let .success(value) = result else { return nil } + + return value + } + + /// `Failure` value of the instance, if any. + public var error: Failure? { + guard case let .failure(error) = result else { return nil } + + return error + } + + /// `Completion` value of the instance, if any. + public var completion: DataStreamRequest.Completion? { + guard case let .complete(completion) = event else { return nil } + + return completion + } +} + // MARK: - DownloadRequest /// `Request` subclass which downloads `Data` to a file on disk using `URLSessionDownloadTask`. @@ -1104,8 +1480,11 @@ public class DownloadRequest: Request { /// A closure executed once a `DownloadRequest` has successfully completed in order to determine where to move the /// temporary file written to during the download process. The closure takes two arguments: the temporary file URL - /// and the URL response, and returns a two arguments: the file URL where the temporary file should be moved and + /// and the `HTTPURLResponse`, and returns two values: the file URL where the temporary file should be moved and /// the options defining how the file should be moved. + /// + /// - Note: Downloads from a local `file://` `URL`s do not use the `Destination` closure, as those downloads do not + /// return an `HTTPURLResponse`. Instead the file is merely moved within the temporary directory. public typealias Destination = (_ temporaryURL: URL, _ response: HTTPURLResponse) -> (destinationURL: URL, options: Options) @@ -1121,7 +1500,7 @@ public class DownloadRequest: Request { public class func suggestedDownloadDestination(for directory: FileManager.SearchPathDirectory = .documentDirectory, in domain: FileManager.SearchPathDomainMask = .userDomainMask, options: Options = []) -> Destination { - return { temporaryURL, response in + { temporaryURL, response in let directoryURLs = FileManager.default.urls(for: directory, in: domain) let url = directoryURLs.first?.appendingPathComponent(response.suggestedFilename!) ?? temporaryURL @@ -1134,10 +1513,16 @@ public class DownloadRequest: Request { /// with this destination must be additionally moved if they should survive the system reclamation of temporary /// space. static let defaultDestination: Destination = { url, _ in + (defaultDestinationURL(url), []) + } + + /// Default `URL` creation closure. Creates a `URL` in the temporary directory with `Alamofire_` prepended to the + /// provided file name. + static let defaultDestinationURL: (URL) -> URL = { url in let filename = "Alamofire_\(url.lastPathComponent)" let destination = url.deletingLastPathComponent().appendingPathComponent(filename) - return (destination, []) + return destination } // MARK: Downloadable @@ -1161,15 +1546,23 @@ public class DownloadRequest: Request { } /// Protected mutable state specific to `DownloadRequest`. - private let protectedDownloadMutableState: Protector = Protector(DownloadRequestMutableState()) + @Protected + private var mutableDownloadState = DownloadRequestMutableState() - /// If the download is resumable and eventually cancelled, this value may be used to resume the download using the - /// `download(resumingWith data:)` API. + /// If the download is resumable and is eventually cancelled or fails, this value may be used to resume the download + /// using the `download(resumingWith data:)` API. /// /// - Note: For more information about `resumeData`, see [Apple's documentation](https://developer.apple.com/documentation/foundation/urlsessiondownloadtask/1411634-cancel). - public var resumeData: Data? { return protectedDownloadMutableState.directValue.resumeData } + public var resumeData: Data? { + #if !(os(Linux) || os(Windows)) + return $mutableDownloadState.resumeData ?? error?.downloadResumeData + #else + return $mutableDownloadState.resumeData + #endif + } + /// If the download is successful, the `URL` where the file was downloaded. - public var fileURL: URL? { return protectedDownloadMutableState.directValue.fileURL } + public var fileURL: URL? { $mutableDownloadState.fileURL } // MARK: Initial State @@ -1212,7 +1605,7 @@ public class DownloadRequest: Request { override func reset() { super.reset() - protectedDownloadMutableState.write { + $mutableDownloadState.write { $0.resumeData = nil $0.fileURL = nil } @@ -1227,7 +1620,7 @@ public class DownloadRequest: Request { eventMonitor?.request(self, didFinishDownloadingUsing: task, with: result) switch result { - case let .success(url): protectedDownloadMutableState.write { $0.fileURL = url } + case let .success(url): $mutableDownloadState.fileURL = url case let .failure(error): self.error = error } } @@ -1245,7 +1638,7 @@ public class DownloadRequest: Request { } override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - return session.downloadTask(with: request) + session.downloadTask(with: request) } /// Creates a `URLSessionTask` from the provided resume data. @@ -1256,7 +1649,7 @@ public class DownloadRequest: Request { /// /// - Returns: The `URLSessionTask` created. public func task(forResumeData data: Data, using session: URLSession) -> URLSessionTask { - return session.downloadTask(withResumeData: data) + session.downloadTask(withResumeData: data) } /// Cancels the instance. Once cancelled, a `DownloadRequest` can no longer be resumed or suspended. @@ -1266,8 +1659,8 @@ public class DownloadRequest: Request { /// /// - Returns: The instance. @discardableResult - public override func cancel() -> Self { - return cancel(producingResumeData: false) + override public func cancel() -> Self { + cancel(producingResumeData: false) } /// Cancels the instance, optionally producing resume data. Once cancelled, a `DownloadRequest` can no longer be @@ -1279,7 +1672,7 @@ public class DownloadRequest: Request { /// - Returns: The instance. @discardableResult public func cancel(producingResumeData shouldProduceResumeData: Bool) -> Self { - return cancel(optionallyProducingResumeData: shouldProduceResumeData ? { _ in } : nil) + cancel(optionallyProducingResumeData: shouldProduceResumeData ? { _ in } : nil) } /// Cancels the instance while producing resume data. Once cancelled, a `DownloadRequest` can no longer be resumed @@ -1295,7 +1688,7 @@ public class DownloadRequest: Request { /// - Returns: The instance. @discardableResult public func cancel(byProducingResumeData completionHandler: @escaping (_ data: Data?) -> Void) -> Self { - return cancel(optionallyProducingResumeData: completionHandler) + cancel(optionallyProducingResumeData: completionHandler) } /// Internal implementation of cancellation that optionally takes a resume data handler. If no handler is passed, @@ -1305,7 +1698,7 @@ public class DownloadRequest: Request { /// /// - Returns: The instance. private func cancel(optionallyProducingResumeData completionHandler: ((_ resumeData: Data?) -> Void)?) -> Self { - protectedMutableState.write { mutableState in + $mutableState.write { mutableState in guard mutableState.state.canTransitionTo(.cancelled) else { return } mutableState.state = .cancelled @@ -1321,7 +1714,7 @@ public class DownloadRequest: Request { // Resume to ensure metrics are gathered. task.resume() task.cancel { resumeData in - self.protectedDownloadMutableState.write { $0.resumeData = resumeData } + self.$mutableDownloadState.resumeData = resumeData self.underlyingQueue.async { self.didCancelTask(task) } completionHandler(resumeData) } @@ -1350,7 +1743,9 @@ public class DownloadRequest: Request { let result = validation(self.request, response, self.fileURL) - if case let .failure(error) = result { self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) } + if case let .failure(error) = result { + self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) + } self.eventMonitor?.request(self, didValidateRequest: self.request, @@ -1359,7 +1754,7 @@ public class DownloadRequest: Request { withResult: result) } - protectedValidators.append(validator) + $validators.write { $0.append(validator) } return self } @@ -1404,6 +1799,8 @@ public class UploadRequest: DataRequest { /// `underlyingQueue`, but can be passed another queue from a `Session`. /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. + /// - fileManager: `FileManager` used to perform cleanup tasks, including the removal of multipart form + /// encoded payloads written to disk. /// - delegate: `RequestDelegate` that provides an interface to actions not performed by the `Request`. init(id: UUID = UUID(), convertible: UploadConvertible, @@ -1483,11 +1880,11 @@ public class UploadRequest: DataRequest { return stream } - public override func cleanup() { + override public func cleanup() { defer { super.cleanup() } guard - let uploadable = self.uploadable, + let uploadable = uploadable, case let .file(url, shouldRemove) = uploadable, shouldRemove else { return } @@ -1507,7 +1904,7 @@ public protocol UploadableConvertible { extension UploadRequest.Uploadable: UploadableConvertible { public func createUploadable() throws -> UploadRequest.Uploadable { - return self + self } } diff --git a/Pods/Alamofire/Source/RequestInterceptor.swift b/Pods/Alamofire/Source/RequestInterceptor.swift index 09ba4ee..7ed39a5 100644 --- a/Pods/Alamofire/Source/RequestInterceptor.swift +++ b/Pods/Alamofire/Source/RequestInterceptor.swift @@ -24,6 +24,17 @@ import Foundation +/// Stores all state associated with a `URLRequest` being adapted. +public struct RequestAdapterState { + /// The `UUID` of the `Request` associated with the `URLRequest` to adapt. + public let requestID: UUID + + /// The `Session` associated with the `URLRequest` to adapt. + public let session: Session +} + +// MARK: - + /// A type that can inspect and optionally adapt a `URLRequest` in some manner if necessary. public protocol RequestAdapter { /// Inspects and adapts the specified `URLRequest` in some manner and calls the completion handler with the Result. @@ -33,6 +44,20 @@ public protocol RequestAdapter { /// - session: The `Session` that will execute the `URLRequest`. /// - completion: The completion handler that must be called when adaptation is complete. func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) + + /// Inspects and adapts the specified `URLRequest` in some manner and calls the completion handler with the Result. + /// + /// - Parameters: + /// - urlRequest: The `URLRequest` to adapt. + /// - state: The `RequestAdapterState` associated with the `URLRequest`. + /// - completion: The completion handler that must be called when adaptation is complete. + func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result) -> Void) +} + +extension RequestAdapter { + public func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result) -> Void) { + adapt(urlRequest, for: state.session, completion: completion) + } } // MARK: - @@ -126,8 +151,24 @@ open class Adapter: RequestInterceptor { open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { adaptHandler(urlRequest, session, completion) } + + open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result) -> Void) { + adaptHandler(urlRequest, state.session, completion) + } } +#if swift(>=5.5) +extension RequestAdapter where Self == Adapter { + /// Creates an `Adapter` using the provided `AdaptHandler` closure. + /// + /// - Parameter closure: `AdaptHandler` to use to adapt the request. + /// - Returns: The `Adapter`. + public static func adapter(using closure: @escaping AdaptHandler) -> Adapter { + Adapter(closure) + } +} +#endif + // MARK: - /// Closure-based `RequestRetrier`. @@ -149,6 +190,18 @@ open class Retrier: RequestInterceptor { } } +#if swift(>=5.5) +extension RequestRetrier where Self == Retrier { + /// Creates a `Retrier` using the provided `RetryHandler` closure. + /// + /// - Parameter closure: `RetryHandler` to use to retry the request. + /// - Returns: The `Retrier`. + public static func retrier(using closure: @escaping RetryHandler) -> Retrier { + Retrier(closure) + } +} +#endif + // MARK: - /// `RequestInterceptor` which can use multiple `RequestAdapter` and `RequestRetrier` values. @@ -181,11 +234,12 @@ open class Interceptor: RequestInterceptor { /// Creates an instance from the arrays of `RequestAdapter` and `RequestRetrier` values. /// /// - Parameters: - /// - adapters: `RequestAdapter` values to be used. - /// - retriers: `RequestRetrier` values to be used. - public init(adapters: [RequestAdapter] = [], retriers: [RequestRetrier] = []) { - self.adapters = adapters - self.retriers = retriers + /// - adapters: `RequestAdapter` values to be used. + /// - retriers: `RequestRetrier` values to be used. + /// - interceptors: `RequestInterceptor`s to be used. + public init(adapters: [RequestAdapter] = [], retriers: [RequestRetrier] = [], interceptors: [RequestInterceptor] = []) { + self.adapters = adapters + interceptors + self.retriers = retriers + interceptors } open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { @@ -212,6 +266,30 @@ open class Interceptor: RequestInterceptor { } } + open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result) -> Void) { + adapt(urlRequest, using: state, adapters: adapters, completion: completion) + } + + private func adapt(_ urlRequest: URLRequest, + using state: RequestAdapterState, + adapters: [RequestAdapter], + completion: @escaping (Result) -> Void) { + var pendingAdapters = adapters + + guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return } + + let adapter = pendingAdapters.removeFirst() + + adapter.adapt(urlRequest, using: state) { result in + switch result { + case let .success(urlRequest): + self.adapt(urlRequest, using: state, adapters: pendingAdapters, completion: completion) + case .failure: + completion(result) + } + } + } + open func retry(_ request: Request, for session: Session, dueTo error: Error, @@ -241,3 +319,39 @@ open class Interceptor: RequestInterceptor { } } } + +#if swift(>=5.5) +extension RequestInterceptor where Self == Interceptor { + /// Creates an `Interceptor` using the provided `AdaptHandler` and `RetryHandler` closures. + /// + /// - Parameters: + /// - adapter: `AdapterHandler`to use to adapt the request. + /// - retrier: `RetryHandler` to use to retry the request. + /// - Returns: The `Interceptor`. + public static func interceptor(adapter: @escaping AdaptHandler, retrier: @escaping RetryHandler) -> Interceptor { + Interceptor(adaptHandler: adapter, retryHandler: retrier) + } + + /// Creates an `Interceptor` using the provided `RequestAdapter` and `RequestRetrier` instances. + /// - Parameters: + /// - adapter: `RequestAdapter` to use to adapt the request + /// - retrier: `RequestRetrier` to use to retry the request. + /// - Returns: The `Interceptor`. + public static func interceptor(adapter: RequestAdapter, retrier: RequestRetrier) -> Interceptor { + Interceptor(adapter: adapter, retrier: retrier) + } + + /// Creates an `Interceptor` using the provided `RequestAdapter`s, `RequestRetrier`s, and `RequestInterceptor`s. + /// - Parameters: + /// - adapters: `RequestAdapter`s to use to adapt the request. These adapters will be run until one fails. + /// - retriers: `RequestRetrier`s to use to retry the request. These retriers will be run one at a time until + /// a retry is triggered. + /// - interceptors: `RequestInterceptor`s to use to intercept the request. + /// - Returns: The `Interceptor`. + public static func interceptor(adapters: [RequestAdapter] = [], + retriers: [RequestRetrier] = [], + interceptors: [RequestInterceptor] = []) -> Interceptor { + Interceptor(adapters: adapters, retriers: retriers, interceptors: interceptors) + } +} +#endif diff --git a/Pods/Alamofire/Source/RequestTaskMap.swift b/Pods/Alamofire/Source/RequestTaskMap.swift index 39afe1c..85b58f3 100644 --- a/Pods/Alamofire/Source/RequestTaskMap.swift +++ b/Pods/Alamofire/Source/RequestTaskMap.swift @@ -26,12 +26,14 @@ import Foundation /// A type that maintains a two way, one to one map of `URLSessionTask`s to `Request`s. struct RequestTaskMap { + private typealias Events = (completed: Bool, metricsGathered: Bool) + private var tasksToRequests: [URLSessionTask: Request] private var requestsToTasks: [Request: URLSessionTask] - private var taskEvents: [URLSessionTask: (completed: Bool, metricsGathered: Bool)] + private var taskEvents: [URLSessionTask: Events] var requests: [Request] { - return Array(tasksToRequests.values) + Array(tasksToRequests.values) } init(tasksToRequests: [URLSessionTask: Request] = [:], @@ -43,7 +45,7 @@ struct RequestTaskMap { } subscript(_ request: Request) -> URLSessionTask? { - get { return requestsToTasks[request] } + get { requestsToTasks[request] } set { guard let newValue = newValue else { guard let task = requestsToTasks[request] else { @@ -64,7 +66,7 @@ struct RequestTaskMap { } subscript(_ task: URLSessionTask) -> Request? { - get { return tasksToRequests[task] } + get { tasksToRequests[task] } set { guard let newValue = newValue else { guard let request = tasksToRequests[task] else { @@ -129,11 +131,18 @@ struct RequestTaskMap { switch (events.completed, events.metricsGathered) { case (true, _): fatalError("RequestTaskMap consistency error: duplicate completionReceivedForTask call.") - #if os(watchOS) // watchOS doesn't gather metrics, so unconditionally remove the reference and return true. + #if os(Linux) // Linux doesn't gather metrics, so unconditionally remove the reference and return true. default: self[task] = nil; return true #else - case (false, false): taskEvents[task] = (completed: true, metricsGathered: false); return false - case (false, true): self[task] = nil; return true + case (false, false): + if #available(macOS 10.12, iOS 10, watchOS 7, tvOS 10, *) { + taskEvents[task] = (completed: true, metricsGathered: false); return false + } else { + // watchOS < 7 doesn't gather metrics, so unconditionally remove the reference and return true. + self[task] = nil; return true + } + case (false, true): + self[task] = nil; return true #endif } } diff --git a/Pods/Alamofire/Source/Response.swift b/Pods/Alamofire/Source/Response.swift index 865a044..d9ae9d8 100644 --- a/Pods/Alamofire/Source/Response.swift +++ b/Pods/Alamofire/Source/Response.swift @@ -53,10 +53,10 @@ public struct DataResponse { public let result: Result /// Returns the associated value of the result if it is a success, `nil` otherwise. - public var value: Success? { return result.success } + public var value: Success? { result.success } /// Returns the associated error value if the result if it is a failure, `nil` otherwise. - public var error: Failure? { return result.failure } + public var error: Failure? { result.failure } /// Creates a `DataResponse` instance with the specified parameters derived from the response serialization. /// @@ -88,34 +88,33 @@ extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible { /// The textual representation used when written to an output stream, which includes whether the result was a /// success or failure. public var description: String { - return "\(result)" + "\(result)" } - /// The debug textual representation used when written to an output stream, which includes the URL request, the URL - /// response, the server data, the duration of the network and serialization actions, and the response serialization - /// result. + /// The debug textual representation used when written to an output stream, which includes (if available) a summary + /// of the `URLRequest`, the request's headers and body (if decodable as a `String` below 100KB); the + /// `HTTPURLResponse`'s status code, headers, and body; the duration of the network and serialization actions; and + /// the `Result` of serialization. public var debugDescription: String { - let requestDescription = request.map { "\($0.httpMethod!) \($0)" } ?? "nil" - let requestBody = request?.httpBody.map { String(decoding: $0, as: UTF8.self) } ?? "None" + guard let urlRequest = request else { return "[Request]: None\n[Result]: \(result)" } + + let requestDescription = DebugDescription.description(of: urlRequest) + let responseDescription = response.map { response in - let sortedHeaders = response.headers.sorted() + let responseBodyDescription = DebugDescription.description(for: data, headers: response.headers) return """ - [Status Code]: \(response.statusCode) - [Headers]: - \(sortedHeaders) + \(DebugDescription.description(of: response)) + \(responseBodyDescription.indentingNewlines()) """ - } ?? "nil" - let responseBody = data.map { String(decoding: $0, as: UTF8.self) } ?? "None" - let metricsDescription = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" + } ?? "[Response]: None" + + let networkDuration = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" return """ - [Request]: \(requestDescription) - [Request Body]: \n\(requestBody) - [Response]: \n\(responseDescription) - [Response Body]: \n\(responseBody) - [Data]: \(data?.description ?? "None") - [Network Duration]: \(metricsDescription) + \(requestDescription) + \(responseDescription) + [Network Duration]: \(networkDuration) [Serialization Duration]: \(serializationDuration)s [Result]: \(result) """ @@ -138,12 +137,12 @@ extension DataResponse { /// - returns: A `DataResponse` whose result wraps the value returned by the given closure. If this instance's /// result is a failure, returns a response wrapping the same failure. public func map(_ transform: (Success) -> NewSuccess) -> DataResponse { - return DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.map(transform)) + DataResponse(request: request, + response: response, + data: data, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.map(transform)) } /// Evaluates the given closure when the result of this `DataResponse` is a success, passing the unwrapped result @@ -161,12 +160,12 @@ extension DataResponse { /// - returns: A success or failure `DataResponse` depending on the result of the given closure. If this instance's /// result is a failure, returns the same failure. public func tryMap(_ transform: (Success) throws -> NewSuccess) -> DataResponse { - return DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMap(transform)) + DataResponse(request: request, + response: response, + data: data, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.tryMap(transform)) } /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter. @@ -180,12 +179,12 @@ extension DataResponse { /// /// - Returns: A `DataResponse` instance containing the result of the transform. public func mapError(_ transform: (Failure) -> NewFailure) -> DataResponse { - return DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.mapError(transform)) + DataResponse(request: request, + response: response, + data: data, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.mapError(transform)) } /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter. @@ -201,12 +200,12 @@ extension DataResponse { /// /// - Returns: A `DataResponse` instance containing the result of the transform. public func tryMapError(_ transform: (Failure) throws -> NewFailure) -> DataResponse { - return DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMapError(transform)) + DataResponse(request: request, + response: response, + data: data, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.tryMapError(transform)) } } @@ -239,18 +238,17 @@ public struct DownloadResponse { public let result: Result /// Returns the associated value of the result if it is a success, `nil` otherwise. - public var value: Success? { return result.success } + public var value: Success? { result.success } /// Returns the associated error value if the result if it is a failure, `nil` otherwise. - public var error: Failure? { return result.failure } + public var error: Failure? { result.failure } /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization. /// /// - Parameters: /// - request: The `URLRequest` sent to the server. /// - response: The `HTTPURLResponse` from the server. - /// - temporaryURL: The temporary destination `URL` of the data returned from the server. - /// - destinationURL: The final destination `URL` of the data returned from the server, if it was moved. + /// - fileURL: The final destination URL of the data returned from the server after it is moved. /// - resumeData: The resume `Data` generated if the request was cancelled. /// - metrics: The `URLSessionTaskMetrics` of the `DownloadRequest`. /// - serializationDuration: The duration taken by serialization. @@ -278,34 +276,26 @@ extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertibl /// The textual representation used when written to an output stream, which includes whether the result was a /// success or failure. public var description: String { - return "\(result)" + "\(result)" } /// The debug textual representation used when written to an output stream, which includes the URL request, the URL /// response, the temporary and destination URLs, the resume data, the durations of the network and serialization /// actions, and the response serialization result. public var debugDescription: String { - let requestDescription = request.map { "\($0.httpMethod!) \($0)" } ?? "nil" - let requestBody = request?.httpBody.map { String(decoding: $0, as: UTF8.self) } ?? "None" - let responseDescription = response.map { response in - let sortedHeaders = response.headers.sorted() + guard let urlRequest = request else { return "[Request]: None\n[Result]: \(result)" } - return """ - [Status Code]: \(response.statusCode) - [Headers]: - \(sortedHeaders) - """ - } ?? "nil" - let metricsDescription = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" + let requestDescription = DebugDescription.description(of: urlRequest) + let responseDescription = response.map(DebugDescription.description(of:)) ?? "[Response]: None" + let networkDuration = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" let resumeDataDescription = resumeData.map { "\($0)" } ?? "None" return """ - [Request]: \(requestDescription) - [Request Body]: \n\(requestBody) - [Response]: \n\(responseDescription) - [File URL]: \(fileURL?.path ?? "nil") - [ResumeData]: \(resumeDataDescription) - [Network Duration]: \(metricsDescription) + \(requestDescription) + \(responseDescription) + [File URL]: \(fileURL?.path ?? "None") + [Resume Data]: \(resumeDataDescription) + [Network Duration]: \(networkDuration) [Serialization Duration]: \(serializationDuration)s [Result]: \(result) """ @@ -328,13 +318,13 @@ extension DownloadResponse { /// - returns: A `DownloadResponse` whose result wraps the value returned by the given closure. If this instance's /// result is a failure, returns a response wrapping the same failure. public func map(_ transform: (Success) -> NewSuccess) -> DownloadResponse { - return DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.map(transform)) + DownloadResponse(request: request, + response: response, + fileURL: fileURL, + resumeData: resumeData, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.map(transform)) } /// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped @@ -352,13 +342,13 @@ extension DownloadResponse { /// - returns: A success or failure `DownloadResponse` depending on the result of the given closure. If this /// instance's result is a failure, returns the same failure. public func tryMap(_ transform: (Success) throws -> NewSuccess) -> DownloadResponse { - return DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMap(transform)) + DownloadResponse(request: request, + response: response, + fileURL: fileURL, + resumeData: resumeData, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.tryMap(transform)) } /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter. @@ -372,13 +362,13 @@ extension DownloadResponse { /// /// - Returns: A `DownloadResponse` instance containing the result of the transform. public func mapError(_ transform: (Failure) -> NewFailure) -> DownloadResponse { - return DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.mapError(transform)) + DownloadResponse(request: request, + response: response, + fileURL: fileURL, + resumeData: resumeData, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.mapError(transform)) } /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter. @@ -394,12 +384,70 @@ extension DownloadResponse { /// /// - Returns: A `DownloadResponse` instance containing the result of the transform. public func tryMapError(_ transform: (Failure) throws -> NewFailure) -> DownloadResponse { - return DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMapError(transform)) + DownloadResponse(request: request, + response: response, + fileURL: fileURL, + resumeData: resumeData, + metrics: metrics, + serializationDuration: serializationDuration, + result: result.tryMapError(transform)) + } +} + +private enum DebugDescription { + static func description(of request: URLRequest) -> String { + let requestSummary = "\(request.httpMethod!) \(request)" + let requestHeadersDescription = DebugDescription.description(for: request.headers) + let requestBodyDescription = DebugDescription.description(for: request.httpBody, headers: request.headers) + + return """ + [Request]: \(requestSummary) + \(requestHeadersDescription.indentingNewlines()) + \(requestBodyDescription.indentingNewlines()) + """ + } + + static func description(of response: HTTPURLResponse) -> String { + """ + [Response]: + [Status Code]: \(response.statusCode) + \(DebugDescription.description(for: response.headers).indentingNewlines()) + """ + } + + static func description(for headers: HTTPHeaders) -> String { + guard !headers.isEmpty else { return "[Headers]: None" } + + let headerDescription = "\(headers.sorted())".indentingNewlines() + return """ + [Headers]: + \(headerDescription) + """ + } + + static func description(for data: Data?, + headers: HTTPHeaders, + allowingPrintableTypes printableTypes: [String] = ["json", "xml", "text"], + maximumLength: Int = 100_000) -> String { + guard let data = data, !data.isEmpty else { return "[Body]: None" } + + guard + data.count <= maximumLength, + printableTypes.compactMap({ headers["Content-Type"]?.contains($0) }).contains(true) + else { return "[Body]: \(data.count) bytes" } + + return """ + [Body]: + \(String(decoding: data, as: UTF8.self) + .trimmingCharacters(in: .whitespacesAndNewlines) + .indentingNewlines()) + """ + } +} + +extension String { + fileprivate func indentingNewlines(by spaceCount: Int = 4) -> String { + let spaces = String(repeating: " ", count: spaceCount) + return replacingOccurrences(of: "\n", with: "\n\(spaces)") } } diff --git a/Pods/Alamofire/Source/ResponseSerialization.swift b/Pods/Alamofire/Source/ResponseSerialization.swift index 61b2cd5..3097364 100644 --- a/Pods/Alamofire/Source/ResponseSerialization.swift +++ b/Pods/Alamofire/Source/ResponseSerialization.swift @@ -83,7 +83,7 @@ public protocol DataPreprocessor { public struct PassthroughPreprocessor: DataPreprocessor { public init() {} - public func preprocess(_ data: Data) throws -> Data { return data } + public func preprocess(_ data: Data) throws -> Data { data } } /// `DataPreprocessor` that trims Google's typical `)]}',\n` XSSI JSON header. @@ -91,21 +91,33 @@ public struct GoogleXSSIPreprocessor: DataPreprocessor { public init() {} public func preprocess(_ data: Data) throws -> Data { - return (data.prefix(6) == Data(")]}',\n".utf8)) ? data.dropFirst(6) : data + (data.prefix(6) == Data(")]}',\n".utf8)) ? data.dropFirst(6) : data } } +#if swift(>=5.5) +extension DataPreprocessor where Self == PassthroughPreprocessor { + /// Provides a `PassthroughPreprocessor` instance. + public static var passthrough: PassthroughPreprocessor { PassthroughPreprocessor() } +} + +extension DataPreprocessor where Self == GoogleXSSIPreprocessor { + /// Provides a `GoogleXSSIPreprocessor` instance. + public static var googleXSSI: GoogleXSSIPreprocessor { GoogleXSSIPreprocessor() } +} +#endif + extension ResponseSerializer { /// Default `DataPreprocessor`. `PassthroughPreprocessor` by default. - public static var defaultDataPreprocessor: DataPreprocessor { return PassthroughPreprocessor() } + public static var defaultDataPreprocessor: DataPreprocessor { PassthroughPreprocessor() } /// Default `HTTPMethod`s for which empty response bodies are considered appropriate. `[.head]` by default. - public static var defaultEmptyRequestMethods: Set { return [.head] } + public static var defaultEmptyRequestMethods: Set { [.head] } /// HTTP response codes for which empty response bodies are considered appropriate. `[204, 205]` by default. - public static var defaultEmptyResponseCodes: Set { return [204, 205] } + public static var defaultEmptyResponseCodes: Set { [204, 205] } - public var dataPreprocessor: DataPreprocessor { return Self.defaultDataPreprocessor } - public var emptyRequestMethods: Set { return Self.defaultEmptyRequestMethods } - public var emptyResponseCodes: Set { return Self.defaultEmptyResponseCodes } + public var dataPreprocessor: DataPreprocessor { Self.defaultDataPreprocessor } + public var emptyRequestMethods: Set { Self.defaultEmptyRequestMethods } + public var emptyResponseCodes: Set { Self.defaultEmptyResponseCodes } /// Determines whether the `request` allows empty response bodies, if `request` exists. /// @@ -113,7 +125,7 @@ extension ResponseSerializer { /// /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `request` was `nil`. public func requestAllowsEmptyResponseData(_ request: URLRequest?) -> Bool? { - return request.flatMap { $0.httpMethod } + request.flatMap(\.httpMethod) .flatMap(HTTPMethod.init) .map { emptyRequestMethods.contains($0) } } @@ -124,7 +136,7 @@ extension ResponseSerializer { /// /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `response` was `nil`. public func responseAllowsEmptyResponseData(_ response: HTTPURLResponse?) -> Bool? { - return response.flatMap { $0.statusCode } + response.map(\.statusCode) .map { emptyResponseCodes.contains($0) } } @@ -136,14 +148,14 @@ extension ResponseSerializer { /// /// - Returns: `true` if `request` or `response` allow empty bodies, `false` otherwise. public func emptyResponseAllowed(forRequest request: URLRequest?, response: HTTPURLResponse?) -> Bool { - return (requestAllowsEmptyResponseData(request) == true) || (responseAllowsEmptyResponseData(response) == true) + (requestAllowsEmptyResponseData(request) == true) || (responseAllowsEmptyResponseData(response) == true) } } /// By default, any serializer declared to conform to both types will get file serialization for free, as it just feeds /// the data read from disk into the data response serializer. -public extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol { - func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject { +extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol { + public func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject { guard error == nil else { throw error! } guard let fileURL = fileURL else { @@ -199,22 +211,13 @@ extension DataRequest { return self } - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default - /// - responseSerializer: The response serializer responsible for serializing the request, response, and data. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, - responseSerializer: Serializer, - completionHandler: @escaping (AFDataResponse) -> Void) + private func _response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDataResponse) -> Void) -> Self { appendResponseSerializer { // Start work that should be on the serialization queue. - let start = CFAbsoluteTimeGetCurrent() + let start = ProcessInfo.processInfo.systemUptime let result: AFResult = Result { try responseSerializer.serialize(request: self.request, response: self.response, @@ -224,7 +227,7 @@ extension DataRequest { error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) } - let end = CFAbsoluteTimeGetCurrent() + let end = ProcessInfo.processInfo.systemUptime // End work that should be on the serialization queue. self.underlyingQueue.async { @@ -276,6 +279,38 @@ extension DataRequest { return self } + + /// Adds a handler to be called once the request has finished. + /// + /// - Parameters: + /// - queue: The queue on which the completion handler is dispatched. `.main` by default + /// - responseSerializer: The response serializer responsible for serializing the request, response, and data. + /// - completionHandler: The code to be executed once the request has finished. + /// + /// - Returns: The request. + @discardableResult + public func response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDataResponse) -> Void) + -> Self { + _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler) + } + + /// Adds a handler to be called once the request has finished. + /// + /// - Parameters: + /// - queue: The queue on which the completion handler is dispatched. `.main` by default + /// - responseSerializer: The response serializer responsible for serializing the request, response, and data. + /// - completionHandler: The code to be executed once the request has finished. + /// + /// - Returns: The request. + @discardableResult + public func response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDataResponse) -> Void) + -> Self { + _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler) + } } extension DownloadRequest { @@ -313,23 +348,13 @@ extension DownloadRequest { return self } - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - responseSerializer: The response serializer responsible for serializing the request, response, and data - /// contained in the destination `URL`. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, - responseSerializer: Serializer, - completionHandler: @escaping (AFDownloadResponse) -> Void) + private func _response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { appendResponseSerializer { // Start work that should be on the serialization queue. - let start = CFAbsoluteTimeGetCurrent() + let start = ProcessInfo.processInfo.systemUptime let result: AFResult = Result { try responseSerializer.serializeDownload(request: self.request, response: self.response, @@ -338,7 +363,7 @@ extension DownloadRequest { }.mapError { error in error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) } - let end = CFAbsoluteTimeGetCurrent() + let end = ProcessInfo.processInfo.systemUptime // End work that should be on the serialization queue. self.underlyingQueue.async { @@ -392,37 +417,97 @@ extension DownloadRequest { return self } -} -// MARK: - Data + /// Adds a handler to be called once the request has finished. + /// + /// - Parameters: + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - responseSerializer: The response serializer responsible for serializing the request, response, and data + /// contained in the destination `URL`. + /// - completionHandler: The code to be executed once the request has finished. + /// + /// - Returns: The request. + @discardableResult + public func response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDownloadResponse) -> Void) + -> Self { + _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler) + } -extension DataRequest { /// Adds a handler to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - completionHandler: The code to be executed once the request has finished. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - responseSerializer: The response serializer responsible for serializing the request, response, and data + /// contained in the destination `URL`. + /// - completionHandler: The code to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult - public func responseData(queue: DispatchQueue = .main, - completionHandler: @escaping (AFDataResponse) -> Void) + public func response(queue: DispatchQueue = .main, + responseSerializer: Serializer, + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - return response(queue: queue, - responseSerializer: DataResponseSerializer(), - completionHandler: completionHandler) + _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler) + } +} + +// MARK: - URL + +/// A `DownloadResponseSerializerProtocol` that performs only `Error` checking and ensures that a downloaded `fileURL` +/// is present. +public struct URLResponseSerializer: DownloadResponseSerializerProtocol { + /// Creates an instance. + public init() {} + + public func serializeDownload(request: URLRequest?, + response: HTTPURLResponse?, + fileURL: URL?, + error: Error?) throws -> URL { + guard error == nil else { throw error! } + + guard let url = fileURL else { + throw AFError.responseSerializationFailed(reason: .inputFileNil) + } + + return url + } +} + +#if swift(>=5.5) +extension DownloadResponseSerializerProtocol where Self == URLResponseSerializer { + /// Provides a `URLResponseSerializer` instance. + public static var url: URLResponseSerializer { URLResponseSerializer() } +} +#endif + +extension DownloadRequest { + /// Adds a handler using a `URLResponseSerializer` to be called once the request is finished. + /// + /// - Parameters: + /// - queue: The queue on which the completion handler is called. `.main` by default. + /// - completionHandler: A closure to be executed once the request has finished. + /// + /// - Returns: The request. + @discardableResult + public func responseURL(queue: DispatchQueue = .main, + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { + response(queue: queue, responseSerializer: URLResponseSerializer(), completionHandler: completionHandler) } } -/// A `ResponseSerializer` that performs minimal response checking and returns any response data as-is. By default, a -/// request returning `nil` or no data is considered an error. However, if the response is has a status code valid for -/// empty responses (`204`, `205`), then an empty `Data` value is returned. +// MARK: - Data + +/// A `ResponseSerializer` that performs minimal response checking and returns any response `Data` as-is. By default, a +/// request returning `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the +/// response has an HTTP status code valid for empty responses, then an empty `Data` value is returned. public final class DataResponseSerializer: ResponseSerializer { public let dataPreprocessor: DataPreprocessor public let emptyResponseCodes: Set public let emptyRequestMethods: Set - /// Creates an instance using the provided values. + /// Creates a `DataResponseSerializer` using the provided parameters. /// /// - Parameters: /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. @@ -453,29 +538,86 @@ public final class DataResponseSerializer: ResponseSerializer { } } +#if swift(>=5.5) +extension ResponseSerializer where Self == DataResponseSerializer { + /// Provides a default `DataResponseSerializer` instance. + public static var data: DataResponseSerializer { DataResponseSerializer() } + + /// Creates a `DataResponseSerializer` using the provided parameters. + /// + /// - Parameters: + /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. + /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. + /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. + /// + /// - Returns: The `DataResponseSerializer`. + public static func data(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DataResponseSerializer { + DataResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods) + } +} +#endif + +extension DataRequest { + /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished. + /// + /// - Parameters: + /// - queue: The queue on which the completion handler is called. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. + /// + /// - Returns: The request. + @discardableResult + public func responseData(queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods, + completionHandler: @escaping (AFDataResponse) -> Void) -> Self { + response(queue: queue, + responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) + } +} + extension DownloadRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - completionHandler: The code to be executed once the request has finished. + /// - queue: The queue on which the completion handler is called. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult public func responseData(queue: DispatchQueue = .main, - completionHandler: @escaping (AFDownloadResponse) -> Void) - -> Self { - return response(queue: queue, - responseSerializer: DataResponseSerializer(), - completionHandler: completionHandler) + dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods, + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { + response(queue: queue, + responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) } } // MARK: - String /// A `ResponseSerializer` that decodes the response data as a `String`. By default, a request returning `nil` or no -/// data is considered an error. However, if the response is has a status code valid for empty responses (`204`, `205`), -/// then an empty `String` is returned. +/// data is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code +/// valid for empty responses, then an empty `String` is returned. public final class StringResponseSerializer: ResponseSerializer { public let dataPreprocessor: DataPreprocessor /// Optional string encoding used to validate the response. @@ -516,10 +658,8 @@ public final class StringResponseSerializer: ResponseSerializer { var convertedEncoding = encoding - if let encodingName = response?.textEncodingName as CFString?, convertedEncoding == nil { - let ianaCharSet = CFStringConvertIANACharSetNameToEncoding(encodingName) - let nsStringEncoding = CFStringConvertEncodingToNSStringEncoding(ianaCharSet) - convertedEncoding = String.Encoding(rawValue: nsStringEncoding) + if let encodingName = response?.textEncodingName, convertedEncoding == nil { + convertedEncoding = String.Encoding(ianaCharsetName: encodingName) } let actualEncoding = convertedEncoding ?? .isoLatin1 @@ -532,52 +672,99 @@ public final class StringResponseSerializer: ResponseSerializer { } } +#if swift(>=5.5) +extension ResponseSerializer where Self == StringResponseSerializer { + /// Provides a default `StringResponseSerializer` instance. + public static var string: StringResponseSerializer { StringResponseSerializer() } + + /// Creates a `StringResponseSerializer` with the provided values. + /// + /// - Parameters: + /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. + /// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. + /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. + /// + /// - Returns: The `StringResponseSerializer`. + public static func string(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, + encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> StringResponseSerializer { + StringResponseSerializer(dataPreprocessor: dataPreprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods) + } +} +#endif + extension DataRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined from - /// the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - completionHandler: A closure to be executed once the request has finished. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult public func responseString(queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, encoding: String.Encoding? = nil, + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods, completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - return response(queue: queue, - responseSerializer: StringResponseSerializer(encoding: encoding), - completionHandler: completionHandler) + response(queue: queue, + responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) } } extension DownloadRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined from - /// the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - completionHandler: A closure to be executed once the request has finished. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult public func responseString(queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, encoding: String.Encoding? = nil, - completionHandler: @escaping (AFDownloadResponse) -> Void) - -> Self { - return response(queue: queue, - responseSerializer: StringResponseSerializer(encoding: encoding), - completionHandler: completionHandler) + emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods, + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { + response(queue: queue, + responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor, + encoding: encoding, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) } } // MARK: - JSON /// A `ResponseSerializer` that decodes the response data using `JSONSerialization`. By default, a request returning -/// `nil` or no data is considered an error. However, if the response is has a status code valid for empty responses -/// (`204`, `205`), then an `NSNull` value is returned. +/// `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the response has an +/// HTTP status code valid for empty responses, then an `NSNull` value is returned. +@available(*, deprecated, message: "JSONResponseSerializer deprecated and will be removed in Alamofire 6. Use DecodableResponseSerializer instead.") public final class JSONResponseSerializer: ResponseSerializer { public let dataPreprocessor: DataPreprocessor public let emptyResponseCodes: Set @@ -624,41 +811,68 @@ public final class JSONResponseSerializer: ResponseSerializer { } extension DataRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - options: The JSON serialization reading options. `.allowFragments` by default. - /// - completionHandler: A closure to be executed once the request has finished. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` + /// by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. + @available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.") @discardableResult public func responseJSON(queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = JSONResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = JSONResponseSerializer.defaultEmptyRequestMethods, options: JSONSerialization.ReadingOptions = .allowFragments, completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - return response(queue: queue, - responseSerializer: JSONResponseSerializer(options: options), - completionHandler: completionHandler) + response(queue: queue, + responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods, + options: options), + completionHandler: completionHandler) } } extension DownloadRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - options: The JSON serialization reading options. `.allowFragments` by default. - /// - completionHandler: A closure to be executed once the request has finished. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` + /// by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. + @available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.") @discardableResult public func responseJSON(queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor, + emptyResponseCodes: Set = JSONResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = JSONResponseSerializer.defaultEmptyRequestMethods, options: JSONSerialization.ReadingOptions = .allowFragments, - completionHandler: @escaping (AFDownloadResponse) -> Void) - -> Self { - return response(queue: queue, - responseSerializer: JSONResponseSerializer(options: options), - completionHandler: completionHandler) + completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { + response(queue: queue, + responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods, + options: options), + completionHandler: completionHandler) } } @@ -672,15 +886,15 @@ public protocol EmptyResponse { static func emptyValue() -> Self } -/// Type representing an empty response. Use `Empty.value` to get the static instance. -public struct Empty: Decodable { +/// Type representing an empty value. Use `Empty.value` to get the static instance. +public struct Empty: Codable { /// Static `Empty` instance used for all `Empty` responses. public static let value = Empty() } extension Empty: EmptyResponse { public static func emptyValue() -> Empty { - return value + value } } @@ -701,13 +915,17 @@ public protocol DataDecoder { /// `JSONDecoder` automatically conforms to `DataDecoder`. extension JSONDecoder: DataDecoder {} +/// `PropertyListDecoder` automatically conforms to `DataDecoder`. +extension PropertyListDecoder: DataDecoder {} // MARK: - Decodable /// A `ResponseSerializer` that decodes the response data as a generic value using any type that conforms to /// `DataDecoder`. By default, this is an instance of `JSONDecoder`. Additionally, a request returning `nil` or no data -/// is considered an error. However, if the response is has a status code valid for empty responses (`204`, `205`), then -/// the `Empty.value` value is returned. +/// is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code valid +/// for empty responses then an empty value will be returned. If the decoded type conforms to `EmptyResponse`, the +/// type's `emptyValue()` will be returned. If the decoded type is `Empty`, the `.value` instance is returned. If the +/// decoded type *does not* conform to `EmptyResponse` and isn't `Empty`, an error will be produced. public final class DecodableResponseSerializer: ResponseSerializer { public let dataPreprocessor: DataPreprocessor /// The `DataDecoder` instance used to decode responses. @@ -757,44 +975,316 @@ public final class DecodableResponseSerializer: ResponseSerializer } } +#if swift(>=5.5) +extension ResponseSerializer { + /// Creates a `DecodableResponseSerializer` using the values provided. + /// + /// - Parameters: + /// - type: `Decodable` type to decode from response data. + /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. + /// - decoder: The `DataDecoder`. `JSONDecoder()` by default. + /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. + /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. + /// + /// - Returns: The `DecodableResponseSerializer`. + public static func decodable(of type: T.Type, + dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, + decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DecodableResponseSerializer where Self == DecodableResponseSerializer { + DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods) + } +} +#endif + extension DataRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - type: `Decodable` type to decode from response data. - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. - /// - completionHandler: A closure to be executed once the request has finished. + /// - type: `Decodable` type to decode from response data. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult public func responseDecodable(of type: T.Type = T.self, queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods, completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - return response(queue: queue, - responseSerializer: DecodableResponseSerializer(decoder: decoder), - completionHandler: completionHandler) + response(queue: queue, + responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) } } extension DownloadRequest { - /// Adds a handler to be called once the request has finished. + /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished. /// /// - Parameters: - /// - type: `Decodable` type to decode from response data. - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. - /// - completionHandler: A closure to be executed once the request has finished. + /// - type: `Decodable` type to decode from response data. + /// - queue: The queue on which the completion handler is dispatched. `.main` by default. + /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the + /// `completionHandler`. `PassthroughPreprocessor()` by default. + /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. + /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined + /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. + /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. + /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. + /// - completionHandler: A closure to be executed once the request has finished. /// - /// - Returns: The request. + /// - Returns: The request. @discardableResult public func responseDecodable(of type: T.Type = T.self, queue: DispatchQueue = .main, + dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, decoder: DataDecoder = JSONDecoder(), + emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, + emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods, completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - return response(queue: queue, - responseSerializer: DecodableResponseSerializer(decoder: decoder), - completionHandler: completionHandler) + response(queue: queue, + responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, + decoder: decoder, + emptyResponseCodes: emptyResponseCodes, + emptyRequestMethods: emptyRequestMethods), + completionHandler: completionHandler) + } +} + +// MARK: - DataStreamRequest + +/// A type which can serialize incoming `Data`. +public protocol DataStreamSerializer { + /// Type produced from the serialized `Data`. + associatedtype SerializedObject + + /// Serializes incoming `Data` into a `SerializedObject` value. + /// + /// - Parameter data: `Data` to be serialized. + /// + /// - Throws: Any error produced during serialization. + func serialize(_ data: Data) throws -> SerializedObject +} + +/// `DataStreamSerializer` which uses the provided `DataPreprocessor` and `DataDecoder` to serialize the incoming `Data`. +public struct DecodableStreamSerializer: DataStreamSerializer { + /// `DataDecoder` used to decode incoming `Data`. + public let decoder: DataDecoder + /// `DataPreprocessor` incoming `Data` is passed through before being passed to the `DataDecoder`. + public let dataPreprocessor: DataPreprocessor + + /// Creates an instance with the provided `DataDecoder` and `DataPreprocessor`. + /// - Parameters: + /// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default. + /// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the + /// `decoder`. `PassthroughPreprocessor()` by default. + public init(decoder: DataDecoder = JSONDecoder(), dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) { + self.decoder = decoder + self.dataPreprocessor = dataPreprocessor + } + + public func serialize(_ data: Data) throws -> T { + let processedData = try dataPreprocessor.preprocess(data) + do { + return try decoder.decode(T.self, from: processedData) + } catch { + throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error)) + } + } +} + +/// `DataStreamSerializer` which performs no serialization on incoming `Data`. +public struct PassthroughStreamSerializer: DataStreamSerializer { + /// Creates an instance. + public init() {} + + public func serialize(_ data: Data) throws -> Data { data } +} + +/// `DataStreamSerializer` which serializes incoming stream `Data` into `UTF8`-decoded `String` values. +public struct StringStreamSerializer: DataStreamSerializer { + /// Creates an instance. + public init() {} + + public func serialize(_ data: Data) throws -> String { + String(decoding: data, as: UTF8.self) + } +} + +#if swift(>=5.5) +extension DataStreamSerializer { + /// Creates a `DecodableStreamSerializer` instance with the provided `DataDecoder` and `DataPreprocessor`. + /// + /// - Parameters: + /// - type: `Decodable` type to decode from stream data. + /// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default. + /// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the + /// `decoder`. `PassthroughPreprocessor()` by default. + public static func decodable(of type: T.Type, + decoder: DataDecoder = JSONDecoder(), + dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) -> Self where Self == DecodableStreamSerializer { + DecodableStreamSerializer(decoder: decoder, dataPreprocessor: dataPreprocessor) + } +} + +extension DataStreamSerializer where Self == PassthroughStreamSerializer { + /// Provides a `PassthroughStreamSerializer` instance. + public static var passthrough: PassthroughStreamSerializer { PassthroughStreamSerializer() } +} + +extension DataStreamSerializer where Self == StringStreamSerializer { + /// Provides a `StringStreamSerializer` instance. + public static var string: StringStreamSerializer { StringStreamSerializer() } +} +#endif + +extension DataStreamRequest { + /// Adds a `StreamHandler` which performs no parsing on incoming `Data`. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. + /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. + /// + /// - Returns: The `DataStreamRequest`. + @discardableResult + public func responseStream(on queue: DispatchQueue = .main, stream: @escaping Handler) -> Self { + let parser = { [unowned self] (data: Data) in + queue.async { + self.capturingError { + try stream(.init(event: .stream(.success(data)), token: .init(self))) + } + + self.updateAndCompleteIfPossible() + } + } + + $streamMutableState.write { $0.streams.append(parser) } + appendStreamCompletion(on: queue, stream: stream) + + return self + } + + /// Adds a `StreamHandler` which uses the provided `DataStreamSerializer` to process incoming `Data`. + /// + /// - Parameters: + /// - serializer: `DataStreamSerializer` used to process incoming `Data`. Its work is done on the `serializationQueue`. + /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. + /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. + /// + /// - Returns: The `DataStreamRequest`. + @discardableResult + public func responseStream(using serializer: Serializer, + on queue: DispatchQueue = .main, + stream: @escaping Handler) -> Self { + let parser = { [unowned self] (data: Data) in + self.serializationQueue.async { + // Start work on serialization queue. + let result = Result { try serializer.serialize(data) } + .mapError { $0.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: $0))) } + // End work on serialization queue. + self.underlyingQueue.async { + self.eventMonitor?.request(self, didParseStream: result) + + if result.isFailure, self.automaticallyCancelOnStreamError { + self.cancel() + } + + queue.async { + self.capturingError { + try stream(.init(event: .stream(result), token: .init(self))) + } + + self.updateAndCompleteIfPossible() + } + } + } + } + + $streamMutableState.write { $0.streams.append(parser) } + appendStreamCompletion(on: queue, stream: stream) + + return self + } + + /// Adds a `StreamHandler` which parses incoming `Data` as a UTF8 `String`. + /// + /// - Parameters: + /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. + /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. + /// + /// - Returns: The `DataStreamRequest`. + @discardableResult + public func responseStreamString(on queue: DispatchQueue = .main, + stream: @escaping Handler) -> Self { + let parser = { [unowned self] (data: Data) in + self.serializationQueue.async { + // Start work on serialization queue. + let string = String(decoding: data, as: UTF8.self) + // End work on serialization queue. + self.underlyingQueue.async { + self.eventMonitor?.request(self, didParseStream: .success(string)) + + queue.async { + self.capturingError { + try stream(.init(event: .stream(.success(string)), token: .init(self))) + } + + self.updateAndCompleteIfPossible() + } + } + } + } + + $streamMutableState.write { $0.streams.append(parser) } + appendStreamCompletion(on: queue, stream: stream) + + return self + } + + private func updateAndCompleteIfPossible() { + $streamMutableState.write { state in + state.numberOfExecutingStreams -= 1 + + guard state.numberOfExecutingStreams == 0, !state.enqueuedCompletionEvents.isEmpty else { return } + + let completionEvents = state.enqueuedCompletionEvents + self.underlyingQueue.async { completionEvents.forEach { $0() } } + state.enqueuedCompletionEvents.removeAll() + } + } + + /// Adds a `StreamHandler` which parses incoming `Data` using the provided `DataDecoder`. + /// + /// - Parameters: + /// - type: `Decodable` type to parse incoming `Data` into. + /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. + /// - decoder: `DataDecoder` used to decode the incoming `Data`. + /// - preprocessor: `DataPreprocessor` used to process the incoming `Data` before it's passed to the `decoder`. + /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. + /// + /// - Returns: The `DataStreamRequest`. + @discardableResult + public func responseStreamDecodable(of type: T.Type = T.self, + on queue: DispatchQueue = .main, + using decoder: DataDecoder = JSONDecoder(), + preprocessor: DataPreprocessor = PassthroughPreprocessor(), + stream: @escaping Handler) -> Self { + responseStream(using: DecodableStreamSerializer(decoder: decoder, dataPreprocessor: preprocessor), + stream: stream) } } diff --git a/Pods/Alamofire/Source/Result+Alamofire.swift b/Pods/Alamofire/Source/Result+Alamofire.swift index 60b35f8..39ac286 100644 --- a/Pods/Alamofire/Source/Result+Alamofire.swift +++ b/Pods/Alamofire/Source/Result+Alamofire.swift @@ -30,6 +30,17 @@ public typealias AFResult = Result // MARK: - Internal APIs extension Result { + /// Returns whether the instance is `.success`. + var isSuccess: Bool { + guard case .success = self else { return false } + return true + } + + /// Returns whether the instance is `.failure`. + var isFailure: Bool { + !isSuccess + } + /// Returns the associated value if the result is a success, `nil` otherwise. var success: Success? { guard case let .success(value) = self else { return nil } diff --git a/Pods/Alamofire/Source/RetryPolicy.swift b/Pods/Alamofire/Source/RetryPolicy.swift index 988342b..f6fd8d3 100644 --- a/Pods/Alamofire/Source/RetryPolicy.swift +++ b/Pods/Alamofire/Source/RetryPolicy.swift @@ -1,7 +1,7 @@ // // RetryPolicy.swift // -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) +// Copyright (c) 2019-2020 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -64,7 +64,7 @@ open class RetryPolicy: RequestInterceptor { // process. // - [Enabled] The other process could release the background session. .backgroundSessionInUseByAnotherProcess, - + // [System] The shared container identifier of the URL session configuration is needed but has not been set. // - [Disabled] Cannot change at runtime. // .backgroundSessionRequiresSharedContainer, @@ -72,11 +72,11 @@ open class RetryPolicy: RequestInterceptor { // [System] The app is suspended or exits while a background data task is processing. // - [Enabled] App can be foregrounded or launched to recover. .backgroundSessionWasDisconnected, - + // [Network] The URL Loading system received bad data from the server. // - [Enabled] Server could return valid data when retrying. .badServerResponse, - + // [Resource] A malformed URL prevented a URL request from being initiated. // - [Disabled] URL was most likely constructed incorrectly. // .badURL, @@ -85,7 +85,7 @@ open class RetryPolicy: RequestInterceptor { // simultaneous phone and data communication (EDGE or GPRS). // - [Enabled] Phone call could be ended to allow request to recover. .callIsActive, - + // [Client] An asynchronous load has been canceled. // - [Disabled] Request was cancelled by the client. // .cancelled, @@ -97,7 +97,7 @@ open class RetryPolicy: RequestInterceptor { // [Network] An attempt to connect to a host failed. // - [Enabled] Server or DNS lookup could recover during retry. .cannotConnectToHost, - + // [File System] A download task couldn’t create the downloaded file on disk because of an I/O failure. // - [Disabled] File system error is unlikely to recover with retry. // .cannotCreateFile, @@ -113,11 +113,11 @@ open class RetryPolicy: RequestInterceptor { // [Network] The host name for a URL could not be resolved. // - [Enabled] Server or DNS lookup could recover during retry. .cannotFindHost, - + // [Network] A request to load an item only from the cache could not be satisfied. // - [Enabled] Cache could be populated during a retry. .cannotLoadFromNetwork, - + // [File System] A download task was unable to move a downloaded file on disk. // - [Disabled] File system error is unlikely to recover with retry. // .cannotMoveFile, @@ -153,19 +153,19 @@ open class RetryPolicy: RequestInterceptor { // [System] The cellular network disallowed a connection. // - [Enabled] WiFi connection could be established during retry. .dataNotAllowed, - + // [Network] The host address could not be found via DNS lookup. // - [Enabled] DNS lookup could succeed during retry. .dnsLookupFailed, - + // [Data] A download task failed to decode an encoded file during the download. // - [Enabled] Server could correct the decoding issue with retry. .downloadDecodingFailedMidStream, - + // [Data] A download task failed to decode an encoded file after downloading. // - [Enabled] Server could correct the decoding issue with retry. .downloadDecodingFailedToComplete, - + // [File System] A file does not exist. // - [Disabled] File system error is unlikely to recover with retry. // .fileDoesNotExist, @@ -184,11 +184,11 @@ open class RetryPolicy: RequestInterceptor { // is disabled. // - [Enabled] WiFi connection could be established during retry. .internationalRoamingOff, - + // [Connectivity] A client or server connection was severed in the middle of an in-progress load. // - [Enabled] A network connection could be established during retry. .networkConnectionLost, - + // [File System] A resource couldn’t be read because of insufficient permissions. // - [Disabled] Permissions are unlikely to be granted during retry. // .noPermissionsToReadFile, @@ -197,7 +197,7 @@ open class RetryPolicy: RequestInterceptor { // cannot be established automatically. // - [Enabled] A network connection could be established during retry. .notConnectedToInternet, - + // [Resource] A redirect was specified by way of server response code, but the server did not accompany this // code with a redirect URL. // - [Disabled] The redirect URL is unlikely to be supplied during a retry. @@ -216,11 +216,11 @@ open class RetryPolicy: RequestInterceptor { // - [Enabled] The secure connection could be established during a retry given the lack of specificity // provided by the error. .secureConnectionFailed, - + // [Security] A server certificate had a date which indicates it has expired, or is not yet valid. // - [Enabled] The server certificate could become valid within the retry window. .serverCertificateHasBadDate, - + // [Security] A server certificate was not signed by any root server. // - [Disabled] The server certificate is unlikely to change during the retry window. // .serverCertificateHasUnknownRoot, @@ -228,7 +228,7 @@ open class RetryPolicy: RequestInterceptor { // [Security] A server certificate is not yet valid. // - [Enabled] The server certificate could become valid within the retry window. .serverCertificateNotYetValid, - + // [Security] A server certificate was signed by a root server that isn’t trusted. // - [Disabled] The server certificate is unlikely to become trusted within the retry window. // .serverCertificateUntrusted, @@ -277,7 +277,7 @@ open class RetryPolicy: RequestInterceptor { /// The URL error codes that are automatically retried by the policy. public let retryableURLErrorCodes: Set - /// Creates an `ExponentialBackoffRetryPolicy` from the specified parameters. + /// Creates a `RetryPolicy` from the specified parameters. /// /// - Parameters: /// - retryLimit: The total number of times the request is allowed to be retried. `2` by default. @@ -309,33 +309,71 @@ open class RetryPolicy: RequestInterceptor { for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) { - if - request.retryCount < retryLimit, - let httpMethod = request.request?.method, - retryableHTTPMethods.contains(httpMethod), - shouldRetry(response: request.response, error: error) { - let timeDelay = pow(Double(exponentialBackoffBase), Double(request.retryCount)) * exponentialBackoffScale - completion(.retryWithDelay(timeDelay)) + if request.retryCount < retryLimit, shouldRetry(request: request, dueTo: error) { + completion(.retryWithDelay(pow(Double(exponentialBackoffBase), Double(request.retryCount)) * exponentialBackoffScale)) } else { completion(.doNotRetry) } } - private func shouldRetry(response: HTTPURLResponse?, error: Error) -> Bool { - if let statusCode = response?.statusCode, retryableHTTPStatusCodes.contains(statusCode) { + /// Determines whether or not to retry the provided `Request`. + /// + /// - Parameters: + /// - request: `Request` that failed due to the provided `Error`. + /// - error: `Error` encountered while executing the `Request`. + /// + /// - Returns: `Bool` determining whether or not to retry the `Request`. + open func shouldRetry(request: Request, dueTo error: Error) -> Bool { + guard let httpMethod = request.request?.method, retryableHTTPMethods.contains(httpMethod) else { return false } + + if let statusCode = request.response?.statusCode, retryableHTTPStatusCodes.contains(statusCode) { return true } else { let errorCode = (error as? URLError)?.code let afErrorCode = (error.asAFError?.underlyingError as? URLError)?.code - if let code = errorCode ?? afErrorCode, retryableURLErrorCodes.contains(code) { - return true - } else { - return false - } + + guard let code = errorCode ?? afErrorCode else { return false } + + return retryableURLErrorCodes.contains(code) } } } +#if swift(>=5.5) +extension RequestInterceptor where Self == RetryPolicy { + /// Provides a default `RetryPolicy` instance. + public static var retryPolicy: RetryPolicy { RetryPolicy() } + + /// Creates an `RetryPolicy` from the specified parameters. + /// + /// - Parameters: + /// - retryLimit: The total number of times the request is allowed to be retried. `2` by default. + /// - exponentialBackoffBase: The base of the exponential backoff policy. `2` by default. + /// - exponentialBackoffScale: The scale of the exponential backoff. `0.5` by default. + /// - retryableHTTPMethods: The HTTP methods that are allowed to be retried. + /// `RetryPolicy.defaultRetryableHTTPMethods` by default. + /// - retryableHTTPStatusCodes: The HTTP status codes that are automatically retried by the policy. + /// `RetryPolicy.defaultRetryableHTTPStatusCodes` by default. + /// - retryableURLErrorCodes: The URL error codes that are automatically retried by the policy. + /// `RetryPolicy.defaultRetryableURLErrorCodes` by default. + /// + /// - Returns: The `RetryPolicy` + public static func retryPolicy(retryLimit: UInt = RetryPolicy.defaultRetryLimit, + exponentialBackoffBase: UInt = RetryPolicy.defaultExponentialBackoffBase, + exponentialBackoffScale: Double = RetryPolicy.defaultExponentialBackoffScale, + retryableHTTPMethods: Set = RetryPolicy.defaultRetryableHTTPMethods, + retryableHTTPStatusCodes: Set = RetryPolicy.defaultRetryableHTTPStatusCodes, + retryableURLErrorCodes: Set = RetryPolicy.defaultRetryableURLErrorCodes) -> RetryPolicy { + RetryPolicy(retryLimit: retryLimit, + exponentialBackoffBase: exponentialBackoffBase, + exponentialBackoffScale: exponentialBackoffScale, + retryableHTTPMethods: retryableHTTPMethods, + retryableHTTPStatusCodes: retryableHTTPStatusCodes, + retryableURLErrorCodes: retryableURLErrorCodes) + } +} +#endif + // MARK: - /// A retry policy that automatically retries idempotent requests for network connection lost errors. For more @@ -365,3 +403,32 @@ open class ConnectionLostRetryPolicy: RetryPolicy { retryableURLErrorCodes: [.networkConnectionLost]) } } + +#if swift(>=5.5) +extension RequestInterceptor where Self == ConnectionLostRetryPolicy { + /// Provides a default `ConnectionLostRetryPolicy` instance. + public static var connectionLostRetryPolicy: ConnectionLostRetryPolicy { ConnectionLostRetryPolicy() } + + /// Creates a `ConnectionLostRetryPolicy` instance from the specified parameters. + /// + /// - Parameters: + /// - retryLimit: The total number of times the request is allowed to be retried. + /// `RetryPolicy.defaultRetryLimit` by default. + /// - exponentialBackoffBase: The base of the exponential backoff policy. + /// `RetryPolicy.defaultExponentialBackoffBase` by default. + /// - exponentialBackoffScale: The scale of the exponential backoff. + /// `RetryPolicy.defaultExponentialBackoffScale` by default. + /// - retryableHTTPMethods: The idempotent http methods to retry. + /// + /// - Returns: The `ConnectionLostRetryPolicy`. + public static func connectionLostRetryPolicy(retryLimit: UInt = RetryPolicy.defaultRetryLimit, + exponentialBackoffBase: UInt = RetryPolicy.defaultExponentialBackoffBase, + exponentialBackoffScale: Double = RetryPolicy.defaultExponentialBackoffScale, + retryableHTTPMethods: Set = RetryPolicy.defaultRetryableHTTPMethods) -> ConnectionLostRetryPolicy { + ConnectionLostRetryPolicy(retryLimit: retryLimit, + exponentialBackoffBase: exponentialBackoffBase, + exponentialBackoffScale: exponentialBackoffScale, + retryableHTTPMethods: retryableHTTPMethods) + } +} +#endif diff --git a/Pods/Alamofire/Source/ServerTrustEvaluation.swift b/Pods/Alamofire/Source/ServerTrustEvaluation.swift index e3af5ed..d63a63d 100644 --- a/Pods/Alamofire/Source/ServerTrustEvaluation.swift +++ b/Pods/Alamofire/Source/ServerTrustEvaluation.swift @@ -48,6 +48,7 @@ open class ServerTrustManager { self.evaluators = evaluators } + #if !(os(Linux) || os(Windows)) /// Returns the `ServerTrustEvaluating` value for the given host, if one is set. /// /// By default, this method will return the policy that perfectly matches the given host. Subclasses could override @@ -69,12 +70,13 @@ open class ServerTrustManager { return evaluator } + #endif } /// A protocol describing the API used to evaluate server trusts. public protocol ServerTrustEvaluating { - #if os(Linux) - // Implement this once Linux has API for evaluating server trusts. + #if os(Linux) || os(Windows) + // Implement this once Linux/Windows has API for evaluating server trusts. #else /// Evaluates the given `SecTrust` value for the given `host`. /// @@ -89,6 +91,7 @@ public protocol ServerTrustEvaluating { // MARK: - Server Trust Evaluators +#if !(os(Linux) || os(Windows)) /// An evaluator which uses the default server trust evaluation while allowing you to control whether to validate the /// host provided by the challenge. Applications are encouraged to always validate the host in production environments /// to guarantee the validity of the server's certificate chain. @@ -150,19 +153,19 @@ public final class RevocationTrustEvaluator: ServerTrustEvaluating { private let validateHost: Bool private let options: Options - /// Creates a `RevocationTrustEvaluator`. + /// Creates a `RevocationTrustEvaluator` using the provided parameters. /// /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. /// /// - Parameters: - /// - performDefaultValidation: Determines whether default validation should be performed in addition to - /// evaluating the pinned certificates. `true` by default. - /// - validateHost: Determines whether or not the evaluator should validate the host, in addition - /// to performing the default evaluation, even if `performDefaultValidation` is - /// `false`. `true` by default. - /// - options: The `Options` to use to check the revocation status of the certificate. `.any` - /// by default. + /// - performDefaultValidation: Determines whether default validation should be performed in addition to + /// evaluating the pinned certificates. `true` by default. + /// - validateHost: Determines whether or not the evaluator should validate the host, in addition to + /// performing the default evaluation, even if `performDefaultValidation` is `false`. + /// `true` by default. + /// - options: The `Options` to use to check the revocation status of the certificate. `.any` by + /// default. public init(performDefaultValidation: Bool = true, validateHost: Bool = true, options: Options = .any) { self.performDefaultValidation = performDefaultValidation self.validateHost = validateHost @@ -188,6 +191,35 @@ public final class RevocationTrustEvaluator: ServerTrustEvaluating { } } +#if swift(>=5.5) +extension ServerTrustEvaluating where Self == RevocationTrustEvaluator { + /// Provides a default `RevocationTrustEvaluator` instance. + public static var revocationChecking: RevocationTrustEvaluator { RevocationTrustEvaluator() } + + /// Creates a `RevocationTrustEvaluator` using the provided parameters. + /// + /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use + /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. + /// + /// - Parameters: + /// - performDefaultValidation: Determines whether default validation should be performed in addition to + /// evaluating the pinned certificates. `true` by default. + /// - validateHost: Determines whether or not the evaluator should validate the host, in addition + /// to performing the default evaluation, even if `performDefaultValidation` is + /// `false`. `true` by default. + /// - options: The `Options` to use to check the revocation status of the certificate. `.any` + /// by default. + /// - Returns: The `RevocationTrustEvaluator`. + public static func revocationChecking(performDefaultValidation: Bool = true, + validateHost: Bool = true, + options: RevocationTrustEvaluator.Options = .any) -> RevocationTrustEvaluator { + RevocationTrustEvaluator(performDefaultValidation: performDefaultValidation, + validateHost: validateHost, + options: options) + } +} +#endif + /// Uses the pinned certificates to validate the server trust. The server trust is considered valid if one of the pinned /// certificates match one of the server certificates. By validating both the certificate chain and host, certificate /// pinning provides a very secure form of server trust validation mitigating most, if not all, MITM attacks. @@ -199,7 +231,7 @@ public final class PinnedCertificatesTrustEvaluator: ServerTrustEvaluating { private let performDefaultValidation: Bool private let validateHost: Bool - /// Creates a `PinnedCertificatesTrustEvaluator`. + /// Creates a `PinnedCertificatesTrustEvaluator` from the provided parameters. /// /// - Parameters: /// - certificates: The certificates to use to evaluate the trust. All `cer`, `crt`, and `der` @@ -251,6 +283,36 @@ public final class PinnedCertificatesTrustEvaluator: ServerTrustEvaluating { } } +#if swift(>=5.5) +extension ServerTrustEvaluating where Self == PinnedCertificatesTrustEvaluator { + /// Provides a default `PinnedCertificatesTrustEvaluator` instance. + public static var pinnedCertificates: PinnedCertificatesTrustEvaluator { PinnedCertificatesTrustEvaluator() } + + /// Creates a `PinnedCertificatesTrustEvaluator` using the provided parameters. + /// + /// - Parameters: + /// - certificates: The certificates to use to evaluate the trust. All `cer`, `crt`, and `der` + /// certificates in `Bundle.main` by default. + /// - acceptSelfSignedCertificates: Adds the provided certificates as anchors for the trust evaluation, allowing + /// self-signed certificates to pass. `false` by default. THIS SETTING SHOULD BE + /// FALSE IN PRODUCTION! + /// - performDefaultValidation: Determines whether default validation should be performed in addition to + /// evaluating the pinned certificates. `true` by default. + /// - validateHost: Determines whether or not the evaluator should validate the host, in addition + /// to performing the default evaluation, even if `performDefaultValidation` is + /// `false`. `true` by default. + public static func pinnedCertificates(certificates: [SecCertificate] = Bundle.main.af.certificates, + acceptSelfSignedCertificates: Bool = false, + performDefaultValidation: Bool = true, + validateHost: Bool = true) -> PinnedCertificatesTrustEvaluator { + PinnedCertificatesTrustEvaluator(certificates: certificates, + acceptSelfSignedCertificates: acceptSelfSignedCertificates, + performDefaultValidation: performDefaultValidation, + validateHost: validateHost) + } +} +#endif + /// Uses the pinned public keys to validate the server trust. The server trust is considered valid if one of the pinned /// public keys match one of the server certificate public keys. By validating both the certificate chain and host, /// public key pinning provides a very secure form of server trust validation mitigating most, if not all, MITM attacks. @@ -261,7 +323,7 @@ public final class PublicKeysTrustEvaluator: ServerTrustEvaluating { private let performDefaultValidation: Bool private let validateHost: Bool - /// Creates a `PublicKeysTrustEvaluator`. + /// Creates a `PublicKeysTrustEvaluator` from the provided parameters. /// /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. @@ -315,12 +377,38 @@ public final class PublicKeysTrustEvaluator: ServerTrustEvaluating { } } +#if swift(>=5.5) +extension ServerTrustEvaluating where Self == PublicKeysTrustEvaluator { + /// Provides a default `PublicKeysTrustEvaluator` instance. + public static var publicKeys: PublicKeysTrustEvaluator { PublicKeysTrustEvaluator() } + + /// Creates a `PublicKeysTrustEvaluator` from the provided parameters. + /// + /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use + /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. + /// + /// - Parameters: + /// - keys: The `SecKey`s to use to validate public keys. Defaults to the public keys of all + /// certificates included in the main bundle. + /// - performDefaultValidation: Determines whether default validation should be performed in addition to + /// evaluating the pinned certificates. `true` by default. + /// - validateHost: Determines whether or not the evaluator should validate the host, in addition to + /// performing the default evaluation, even if `performDefaultValidation` is `false`. + /// `true` by default. + public static func publicKeys(keys: [SecKey] = Bundle.main.af.publicKeys, + performDefaultValidation: Bool = true, + validateHost: Bool = true) -> PublicKeysTrustEvaluator { + PublicKeysTrustEvaluator(keys: keys, performDefaultValidation: performDefaultValidation, validateHost: validateHost) + } +} +#endif + /// Uses the provided evaluators to validate the server trust. The trust is only considered valid if all of the /// evaluators consider it valid. public final class CompositeTrustEvaluator: ServerTrustEvaluating { private let evaluators: [ServerTrustEvaluating] - /// Creates a `CompositeTrustEvaluator`. + /// Creates a `CompositeTrustEvaluator` from the provided evaluators. /// /// - Parameter evaluators: The `ServerTrustEvaluating` values used to evaluate the server trust. public init(evaluators: [ServerTrustEvaluating]) { @@ -332,10 +420,34 @@ public final class CompositeTrustEvaluator: ServerTrustEvaluating { } } +#if swift(>=5.5) +extension ServerTrustEvaluating where Self == CompositeTrustEvaluator { + /// Creates a `CompositeTrustEvaluator` from the provided evaluators. + /// + /// - Parameter evaluators: The `ServerTrustEvaluating` values used to evaluate the server trust. + public static func composite(evaluators: [ServerTrustEvaluating]) -> CompositeTrustEvaluator { + CompositeTrustEvaluator(evaluators: evaluators) + } +} +#endif + /// Disables all evaluation which in turn will always consider any server trust as valid. /// +/// - Note: Instead of disabling server trust evaluation, it's a better idea to configure systems to properly trust test +/// certificates, as outlined in [this Apple tech note](https://developer.apple.com/library/archive/qa/qa1948/_index.html). +/// +/// **THIS EVALUATOR SHOULD NEVER BE USED IN PRODUCTION!** +@available(*, deprecated, renamed: "DisabledTrustEvaluator", message: "DisabledEvaluator has been renamed DisabledTrustEvaluator.") +public typealias DisabledEvaluator = DisabledTrustEvaluator + +/// Disables all evaluation which in turn will always consider any server trust as valid. +/// +/// +/// - Note: Instead of disabling server trust evaluation, it's a better idea to configure systems to properly trust test +/// certificates, as outlined in [this Apple tech note](https://developer.apple.com/library/archive/qa/qa1948/_index.html). +/// /// **THIS EVALUATOR SHOULD NEVER BE USED IN PRODUCTION!** -public final class DisabledEvaluator: ServerTrustEvaluating { +public final class DisabledTrustEvaluator: ServerTrustEvaluating { /// Creates an instance. public init() {} @@ -344,9 +456,9 @@ public final class DisabledEvaluator: ServerTrustEvaluating { // MARK: - Extensions -public extension Array where Element == ServerTrustEvaluating { - #if os(Linux) - // Add this same convenience method for Linux. +extension Array where Element == ServerTrustEvaluating { + #if os(Linux) || os(Windows) + // Add this same convenience method for Linux/Windows. #else /// Evaluates the given `SecTrust` value for the given `host`. /// @@ -355,7 +467,7 @@ public extension Array where Element == ServerTrustEvaluating { /// - host: The host for which to evaluate the `SecTrust` value. /// /// - Returns: Whether or not the evaluator considers the `SecTrust` value valid for `host`. - func evaluate(_ trust: SecTrust, forHost host: String) throws { + public func evaluate(_ trust: SecTrust, forHost host: String) throws { for evaluator in self { try evaluator.evaluate(trust, forHost: host) } @@ -364,10 +476,10 @@ public extension Array where Element == ServerTrustEvaluating { } extension Bundle: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType: Bundle { +extension AlamofireExtension where ExtendedType: Bundle { /// Returns all valid `cer`, `crt`, and `der` certificates in the bundle. - var certificates: [SecCertificate] { - return paths(forResourcesOfTypes: [".cer", ".CER", ".crt", ".CRT", ".der", ".DER"]).compactMap { path in + public var certificates: [SecCertificate] { + paths(forResourcesOfTypes: [".cer", ".CER", ".crt", ".CRT", ".der", ".DER"]).compactMap { path in guard let certificateData = try? Data(contentsOf: URL(fileURLWithPath: path)) as CFData, let certificate = SecCertificateCreateWithData(nil, certificateData) else { return nil } @@ -377,8 +489,8 @@ public extension AlamofireExtension where ExtendedType: Bundle { } /// Returns all public keys for the valid certificates in the bundle. - var publicKeys: [SecKey] { - return certificates.af.publicKeys + public var publicKeys: [SecKey] { + certificates.af.publicKeys } /// Returns all pathnames for the resources identified by the provided file extensions. @@ -386,20 +498,20 @@ public extension AlamofireExtension where ExtendedType: Bundle { /// - Parameter types: The filename extensions locate. /// /// - Returns: All pathnames for the given filename extensions. - func paths(forResourcesOfTypes types: [String]) -> [String] { - return Array(Set(types.flatMap { type.paths(forResourcesOfType: $0, inDirectory: nil) })) + public func paths(forResourcesOfTypes types: [String]) -> [String] { + Array(Set(types.flatMap { type.paths(forResourcesOfType: $0, inDirectory: nil) })) } } extension SecTrust: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType == SecTrust { +extension AlamofireExtension where ExtendedType == SecTrust { /// Evaluates `self` after applying the `SecPolicy` value provided. /// /// - Parameter policy: The `SecPolicy` to apply to `self` before evaluation. /// /// - Throws: Any `Error` from applying the `SecPolicy` or from evaluation. @available(iOS 12, macOS 10.14, tvOS 12, watchOS 5, *) - func evaluate(afterApplying policy: SecPolicy) throws { + public func evaluate(afterApplying policy: SecPolicy) throws { try apply(policy: policy).af.evaluate() } @@ -413,7 +525,7 @@ public extension AlamofireExtension where ExtendedType == SecTrust { @available(macOS, introduced: 10.12, deprecated: 10.14, renamed: "evaluate(afterApplying:)") @available(tvOS, introduced: 10, deprecated: 12, renamed: "evaluate(afterApplying:)") @available(watchOS, introduced: 3, deprecated: 5, renamed: "evaluate(afterApplying:)") - func validate(policy: SecPolicy, errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { + public func validate(policy: SecPolicy, errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { try apply(policy: policy).af.validate(errorProducer: errorProducer) } @@ -423,7 +535,7 @@ public extension AlamofireExtension where ExtendedType == SecTrust { /// /// - Returns: `self`, with the policy applied. /// - Throws: An `AFError.serverTrustEvaluationFailed` instance with a `.policyApplicationFailed` reason. - func apply(policy: SecPolicy) throws -> SecTrust { + public func apply(policy: SecPolicy) throws -> SecTrust { let status = SecTrustSetPolicies(type, policy) guard status.af.isSuccess else { @@ -440,7 +552,7 @@ public extension AlamofireExtension where ExtendedType == SecTrust { /// - Throws: `AFError.serverTrustEvaluationFailed` with reason `.trustValidationFailed` and associated error from /// the underlying evaluation. @available(iOS 12, macOS 10.14, tvOS 12, watchOS 5, *) - func evaluate() throws { + public func evaluate() throws { var error: CFError? let evaluationSucceeded = SecTrustEvaluateWithError(type, &error) @@ -458,7 +570,7 @@ public extension AlamofireExtension where ExtendedType == SecTrust { @available(macOS, introduced: 10.12, deprecated: 10.14, renamed: "evaluate()") @available(tvOS, introduced: 10, deprecated: 12, renamed: "evaluate()") @available(watchOS, introduced: 3, deprecated: 5, renamed: "evaluate()") - func validate(errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { + public func validate(errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { var result = SecTrustResultType.invalid let status = SecTrustEvaluate(type, &result) @@ -471,7 +583,7 @@ public extension AlamofireExtension where ExtendedType == SecTrust { /// /// - Parameter certificates: The `SecCertificate`s to add to the chain. /// - Throws: Any error produced when applying the new certificate chain. - func setAnchorCertificates(_ certificates: [SecCertificate]) throws { + public func setAnchorCertificates(_ certificates: [SecCertificate]) throws { // Add additional anchor certificates. let status = SecTrustSetAnchorCertificates(type, certificates as CFArray) guard status.af.isSuccess else { @@ -479,36 +591,36 @@ public extension AlamofireExtension where ExtendedType == SecTrust { certificates: certificates)) } - // Reenable system anchor certificates. - let systemStatus = SecTrustSetAnchorCertificatesOnly(type, true) - guard systemStatus.af.isSuccess else { - throw AFError.serverTrustEvaluationFailed(reason: .settingAnchorCertificatesFailed(status: systemStatus, + // Trust only the set anchor certs. + let onlyStatus = SecTrustSetAnchorCertificatesOnly(type, true) + guard onlyStatus.af.isSuccess else { + throw AFError.serverTrustEvaluationFailed(reason: .settingAnchorCertificatesFailed(status: onlyStatus, certificates: certificates)) } } /// The public keys contained in `self`. - var publicKeys: [SecKey] { - return certificates.af.publicKeys + public var publicKeys: [SecKey] { + certificates.af.publicKeys } /// The `SecCertificate`s contained i `self`. - var certificates: [SecCertificate] { - return (0.. SecPolicy { - return SecPolicyCreateSSL(true, hostname as CFString) + public static func hostname(_ hostname: String) -> SecPolicy { + SecPolicyCreateSSL(true, hostname as CFString) } /// Creates a `SecPolicy` which checks the revocation of certificates. @@ -555,7 +667,7 @@ public extension AlamofireExtension where ExtendedType == SecPolicy { /// - Returns: The `SecPolicy`. /// - Throws: An `AFError.serverTrustEvaluationFailed` error with reason `.revocationPolicyCreationFailed` /// if the policy cannot be created. - static func revocation(options: RevocationTrustEvaluator.Options) throws -> SecPolicy { + public static func revocation(options: RevocationTrustEvaluator.Options) throws -> SecPolicy { guard let policy = SecPolicyCreateRevocation(options.rawValue) else { throw AFError.serverTrustEvaluationFailed(reason: .revocationPolicyCreationFailed) } @@ -565,22 +677,22 @@ public extension AlamofireExtension where ExtendedType == SecPolicy { } extension Array: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType == [SecCertificate] { +extension AlamofireExtension where ExtendedType == [SecCertificate] { /// All `Data` values for the contained `SecCertificate`s. - var data: [Data] { - return type.map { SecCertificateCopyData($0) as Data } + public var data: [Data] { + type.map { SecCertificateCopyData($0) as Data } } /// All public `SecKey` values for the contained `SecCertificate`s. - var publicKeys: [SecKey] { - return type.compactMap { $0.af.publicKey } + public var publicKeys: [SecKey] { + type.compactMap(\.af.publicKey) } } extension SecCertificate: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType == SecCertificate { +extension AlamofireExtension where ExtendedType == SecCertificate { /// The public key for `self`, if it can be extracted. - var publicKey: SecKey? { + public var publicKey: SecKey? { let policy = SecPolicyCreateBasicX509() var trust: SecTrust? let trustCreationStatus = SecTrustCreateWithCertificates(type, policy, &trust) @@ -592,15 +704,16 @@ public extension AlamofireExtension where ExtendedType == SecCertificate { } extension OSStatus: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType == OSStatus { +extension AlamofireExtension where ExtendedType == OSStatus { /// Returns whether `self` is `errSecSuccess`. - var isSuccess: Bool { return type == errSecSuccess } + public var isSuccess: Bool { type == errSecSuccess } } extension SecTrustResultType: AlamofireExtended {} -public extension AlamofireExtension where ExtendedType == SecTrustResultType { +extension AlamofireExtension where ExtendedType == SecTrustResultType { /// Returns whether `self is `.unspecified` or `.proceed`. - var isSuccess: Bool { - return (type == .unspecified || type == .proceed) + public var isSuccess: Bool { + type == .unspecified || type == .proceed } } +#endif diff --git a/Pods/Alamofire/Source/Session.swift b/Pods/Alamofire/Source/Session.swift index aeaeaa6..4588811 100644 --- a/Pods/Alamofire/Source/Session.swift +++ b/Pods/Alamofire/Source/Session.swift @@ -33,6 +33,10 @@ open class Session { /// Underlying `URLSession` used to create `URLSessionTasks` for this instance, and for which this instance's /// `delegate` handles `URLSessionDelegate` callbacks. + /// + /// - Note: This instance should **NOT** be used to interact with the underlying `URLSessionTask`s. Doing so will + /// break internal Alamofire logic that tracks those tasks. + /// public let session: URLSession /// Instance's `SessionDelegate`, which handles the `URLSessionDelegate` methods and `Request` interaction. public let delegate: SessionDelegate @@ -64,7 +68,7 @@ open class Session { /// Internal map between `Request`s and any `URLSessionTasks` that may be in flight for them. var requestTaskMap = RequestTaskMap() - /// Set of currently active `Request`s. + /// `Set` of currently active `Request`s. var activeRequests: Set = [] /// Completion events awaiting `URLSessionTaskMetrics`. var waitingCompletions: [URLSessionTask: () -> Void] = [:] @@ -179,12 +183,15 @@ open class Session { eventMonitors: [EventMonitor] = []) { precondition(configuration.identifier == nil, "Alamofire does not support background URLSessionConfigurations.") - let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue") + // Retarget the incoming rootQueue for safety, unless it's the main queue, which we know is safe. + let serialRootQueue = (rootQueue === DispatchQueue.main) ? rootQueue : DispatchQueue(label: rootQueue.label, + target: rootQueue) + let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: serialRootQueue, name: "\(serialRootQueue.label).sessionDelegate") let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue) self.init(session: session, delegate: delegate, - rootQueue: rootQueue, + rootQueue: serialRootQueue, startRequestsImmediately: startRequestsImmediately, requestQueue: requestQueue, serializationQueue: serializationQueue, @@ -200,7 +207,22 @@ open class Session { session.invalidateAndCancel() } - // MARK: - Cancellation + // MARK: - All Requests API + + /// Perform an action on all active `Request`s. + /// + /// - Note: The provided `action` closure is performed asynchronously, meaning that some `Request`s may complete and + /// be unavailable by time it runs. Additionally, this action is performed on the instances's `rootQueue`, + /// so care should be taken that actions are fast. Once the work on the `Request`s is complete, any + /// additional work should be performed on another queue. + /// + /// - Parameters: + /// - action: Closure to perform with all `Request`s. + public func withAllRequests(perform action: @escaping (Set) -> Void) { + rootQueue.async { + action(self.activeRequests) + } + } /// Cancel all active `Request`s, optionally calling a completion handler when complete. /// @@ -212,23 +234,31 @@ open class Session { /// - queue: `DispatchQueue` on which the completion handler is run. `.main` by default. /// - completion: Closure to be called when all `Request`s have been cancelled. public func cancelAllRequests(completingOnQueue queue: DispatchQueue = .main, completion: (() -> Void)? = nil) { - rootQueue.async { - self.activeRequests.forEach { $0.cancel() } - queue.async { completion?() } + withAllRequests { requests in + requests.forEach { $0.cancel() } + queue.async { + completion?() + } } } // MARK: - DataRequest + /// Closure which provides a `URLRequest` for mutation. + public typealias RequestModifier = (inout URLRequest) throws -> Void + struct RequestConvertible: URLRequestConvertible { let url: URLConvertible let method: HTTPMethod let parameters: Parameters? let encoding: ParameterEncoding let headers: HTTPHeaders? + let requestModifier: RequestModifier? func asURLRequest() throws -> URLRequest { - let request = try URLRequest(url: url, method: method, headers: headers) + var request = try URLRequest(url: url, method: method, headers: headers) + try requestModifier?(&request) + return try encoding.encode(request, with: parameters) } } @@ -236,13 +266,16 @@ open class Session { /// Creates a `DataRequest` from a `URLRequest` created using the passed components and a `RequestInterceptor`. /// /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by default. - /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. - /// `URLEncoding.default` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by + /// default. + /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. + /// `URLEncoding.default` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. /// /// - Returns: The created `DataRequest`. open func request(_ convertible: URLConvertible, @@ -250,12 +283,14 @@ open class Session { parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil) -> DataRequest { + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataRequest { let convertible = RequestConvertible(url: convertible, method: method, parameters: parameters, encoding: encoding, - headers: headers) + headers: headers, + requestModifier: requestModifier) return request(convertible, interceptor: interceptor) } @@ -266,9 +301,11 @@ open class Session { let parameters: Parameters? let encoder: ParameterEncoder let headers: HTTPHeaders? + let requestModifier: RequestModifier? func asURLRequest() throws -> URLRequest { - let request = try URLRequest(url: url, method: method, headers: headers) + var request = try URLRequest(url: url, method: method, headers: headers) + try requestModifier?(&request) return try parameters.map { try encoder.encode($0, into: request) } ?? request } @@ -278,26 +315,30 @@ open class Session { /// `RequestInterceptor`. /// /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Encodable` value to be encoded into the `URLRequest`. `nil` by default. - /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. - /// `URLEncodedFormParameterEncoder.default` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - parameters: `Encodable` value to be encoded into the `URLRequest`. `nil` by default. + /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. + /// `URLEncodedFormParameterEncoder.default` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from + /// the provided parameters. `nil` by default. /// - /// - Returns: The created `DataRequest`. + /// - Returns: The created `DataRequest`. open func request(_ convertible: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil) -> DataRequest { + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataRequest { let convertible = RequestEncodableConvertible(url: convertible, method: method, parameters: parameters, encoder: encoder, - headers: headers) + headers: headers, + requestModifier: requestModifier) return request(convertible, interceptor: interceptor) } @@ -322,35 +363,138 @@ open class Session { return request } + // MARK: - DataStreamRequest + + /// Creates a `DataStreamRequest` from the passed components, `Encodable` parameters, and `RequestInterceptor`. + /// + /// - Parameters: + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - parameters: `Encodable` value to be encoded into the `URLRequest`. `nil` by default. + /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the + /// `URLRequest`. + /// `URLEncodedFormParameterEncoder.default` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` + /// is thrown while serializing stream `Data`. `false` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` + /// by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from + /// the provided parameters. `nil` by default. + /// + /// - Returns: The created `DataStream` request. + open func streamRequest(_ convertible: URLConvertible, + method: HTTPMethod = .get, + parameters: Parameters? = nil, + encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, + headers: HTTPHeaders? = nil, + automaticallyCancelOnStreamError: Bool = false, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataStreamRequest { + let convertible = RequestEncodableConvertible(url: convertible, + method: method, + parameters: parameters, + encoder: encoder, + headers: headers, + requestModifier: requestModifier) + + return streamRequest(convertible, + automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, + interceptor: interceptor) + } + + /// Creates a `DataStreamRequest` from the passed components and `RequestInterceptor`. + /// + /// - Parameters: + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` + /// is thrown while serializing stream `Data`. `false` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` + /// by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from + /// the provided parameters. `nil` by default. + /// + /// - Returns: The created `DataStream` request. + open func streamRequest(_ convertible: URLConvertible, + method: HTTPMethod = .get, + headers: HTTPHeaders? = nil, + automaticallyCancelOnStreamError: Bool = false, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataStreamRequest { + let convertible = RequestEncodableConvertible(url: convertible, + method: method, + parameters: Empty?.none, + encoder: URLEncodedFormParameterEncoder.default, + headers: headers, + requestModifier: requestModifier) + + return streamRequest(convertible, + automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, + interceptor: interceptor) + } + + /// Creates a `DataStreamRequest` from the passed `URLRequestConvertible` value and `RequestInterceptor`. + /// + /// - Parameters: + /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. + /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` + /// is thrown while serializing stream `Data`. `false` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` + /// by default. + /// + /// - Returns: The created `DataStreamRequest`. + open func streamRequest(_ convertible: URLRequestConvertible, + automaticallyCancelOnStreamError: Bool = false, + interceptor: RequestInterceptor? = nil) -> DataStreamRequest { + let request = DataStreamRequest(convertible: convertible, + automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, + underlyingQueue: rootQueue, + serializationQueue: serializationQueue, + eventMonitor: eventMonitor, + interceptor: interceptor, + delegate: self) + + perform(request) + + return request + } + // MARK: - DownloadRequest /// Creates a `DownloadRequest` using a `URLRequest` created using the passed components, `RequestInterceptor`, and /// `Destination`. /// /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by default. - /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. Defaults - /// to `URLEncoding.default`. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by + /// default. + /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. + /// Defaults to `URLEncoding.default`. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. + /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file + /// should be moved. `nil` by default. /// - /// - Returns: The created `DownloadRequest`. + /// - Returns: The created `DownloadRequest`. open func download(_ convertible: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil, to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { let convertible = RequestConvertible(url: convertible, method: method, parameters: parameters, encoding: encoding, - headers: headers) + headers: headers, + requestModifier: requestModifier) return download(convertible, interceptor: interceptor, to: destination) } @@ -359,29 +503,33 @@ open class Session { /// a `RequestInterceptor`. /// /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: Value conforming to `Encodable` to be encoded into the `URLRequest`. `nil` by default. - /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. Defaults - /// to `URLEncodedFormParameterEncoder.default`. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. + /// - parameters: Value conforming to `Encodable` to be encoded into the `URLRequest`. `nil` by default. + /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. + /// Defaults to `URLEncodedFormParameterEncoder.default`. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. + /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file + /// should be moved. `nil` by default. /// - /// - Returns: The created `DownloadRequest`. + /// - Returns: The created `DownloadRequest`. open func download(_ convertible: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil, to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { let convertible = RequestEncodableConvertible(url: convertible, method: method, parameters: parameters, encoder: encoder, - headers: headers) + headers: headers, + requestModifier: requestModifier) return download(convertible, interceptor: interceptor, to: destination) } @@ -451,9 +599,13 @@ open class Session { let url: URLConvertible let method: HTTPMethod let headers: HTTPHeaders? + let requestModifier: RequestModifier? func asURLRequest() throws -> URLRequest { - return try URLRequest(url: url, method: method, headers: headers) + var request = try URLRequest(url: url, method: method, headers: headers) + try requestModifier?(&request) + + return request } } @@ -462,11 +614,11 @@ open class Session { let uploadable: UploadableConvertible func createUploadable() throws -> UploadRequest.Uploadable { - return try uploadable.createUploadable() + try uploadable.createUploadable() } func asURLRequest() throws -> URLRequest { - return try request.asURLRequest() + try request.asURLRequest() } } @@ -475,22 +627,28 @@ open class Session { /// Creates an `UploadRequest` for the given `Data`, `URLRequest` components, and `RequestInterceptor`. /// /// - Parameters: - /// - data: The `Data` to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. + /// - data: The `Data` to upload. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by + /// default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. /// - /// - Returns: The created `UploadRequest`. + /// - Returns: The created `UploadRequest`. open func upload(_ data: Data, to convertible: URLConvertible, method: HTTPMethod = .post, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, method: method, headers: headers) + fileManager: FileManager = .default, + requestModifier: RequestModifier? = nil) -> UploadRequest { + let convertible = ParameterlessRequestConvertible(url: convertible, + method: method, + headers: headers, + requestModifier: requestModifier) return upload(data, with: convertible, interceptor: interceptor, fileManager: fileManager) } @@ -509,7 +667,7 @@ open class Session { with convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil, fileManager: FileManager = .default) -> UploadRequest { - return upload(.data(data), with: convertible, interceptor: interceptor, fileManager: fileManager) + upload(.data(data), with: convertible, interceptor: interceptor, fileManager: fileManager) } // MARK: File @@ -518,22 +676,28 @@ open class Session { /// components and `RequestInterceptor`. /// /// - Parameters: - /// - fileURL: The `URL` of the file to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `UploadRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. + /// - fileURL: The `URL` of the file to upload. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `UploadRequest`. `nil` by default. + /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by + /// default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. /// - /// - Returns: The created `UploadRequest`. + /// - Returns: The created `UploadRequest`. open func upload(_ fileURL: URL, to convertible: URLConvertible, method: HTTPMethod = .post, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, method: method, headers: headers) + fileManager: FileManager = .default, + requestModifier: RequestModifier? = nil) -> UploadRequest { + let convertible = ParameterlessRequestConvertible(url: convertible, + method: method, + headers: headers, + requestModifier: requestModifier) return upload(fileURL, with: convertible, interceptor: interceptor, fileManager: fileManager) } @@ -553,7 +717,7 @@ open class Session { with convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil, fileManager: FileManager = .default) -> UploadRequest { - return upload(.file(fileURL, shouldRemove: false), with: convertible, interceptor: interceptor, fileManager: fileManager) + upload(.file(fileURL, shouldRemove: false), with: convertible, interceptor: interceptor, fileManager: fileManager) } // MARK: InputStream @@ -562,22 +726,28 @@ open class Session { /// `RequestInterceptor`. /// /// - Parameters: - /// - stream: The `InputStream` that provides the data to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. + /// - stream: The `InputStream` that provides the data to upload. + /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. + /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. + /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. + /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by + /// default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided + /// parameters. `nil` by default. /// - /// - Returns: The created `UploadRequest`. + /// - Returns: The created `UploadRequest`. open func upload(_ stream: InputStream, to convertible: URLConvertible, method: HTTPMethod = .post, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, method: method, headers: headers) + fileManager: FileManager = .default, + requestModifier: RequestModifier? = nil) -> UploadRequest { + let convertible = ParameterlessRequestConvertible(url: convertible, + method: method, + headers: headers, + requestModifier: requestModifier) return upload(stream, with: convertible, interceptor: interceptor, fileManager: fileManager) } @@ -597,7 +767,7 @@ open class Session { with convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil, fileManager: FileManager = .default) -> UploadRequest { - return upload(.stream(stream), with: convertible, interceptor: interceptor, fileManager: fileManager) + upload(.stream(stream), with: convertible, interceptor: interceptor, fileManager: fileManager) } // MARK: MultipartFormData @@ -619,8 +789,8 @@ open class Session { /// technique was used. /// /// - Parameters: - /// - multipartFormData: `MultipartFormData` building closure. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. + /// - multipartFormData: `MultipartFormData` building closure. + /// - url: `URLConvertible` value to be used as the `URLRequest`'s `URL`. /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by /// default. @@ -629,6 +799,8 @@ open class Session { /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is /// written to disk before being uploaded. `.default` instance by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the + /// provided parameters. `nil` by default. /// /// - Returns: The created `UploadRequest`. open func upload(multipartFormData: @escaping (MultipartFormData) -> Void, @@ -637,8 +809,12 @@ open class Session { method: HTTPMethod = .post, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: url, method: method, headers: headers) + fileManager: FileManager = .default, + requestModifier: RequestModifier? = nil) -> UploadRequest { + let convertible = ParameterlessRequestConvertible(url: url, + method: method, + headers: headers, + requestModifier: requestModifier) let formData = MultipartFormData(fileManager: fileManager) multipartFormData(formData) @@ -719,6 +895,8 @@ open class Session { /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is /// written to disk before being uploaded. `.default` instance by default. + /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the + /// provided parameters. `nil` by default. /// /// - Returns: The created `UploadRequest`. open func upload(multipartFormData: MultipartFormData, @@ -727,11 +905,14 @@ open class Session { method: HTTPMethod = .post, headers: HTTPHeaders? = nil, interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: url, method: method, headers: headers) - - let multipartUpload = MultipartUpload(isInBackgroundSession: session.configuration.identifier != nil, - encodingMemoryThreshold: encodingMemoryThreshold, + fileManager: FileManager = .default, + requestModifier: RequestModifier? = nil) -> UploadRequest { + let convertible = ParameterlessRequestConvertible(url: url, + method: method, + headers: headers, + requestModifier: requestModifier) + + let multipartUpload = MultipartUpload(encodingMemoryThreshold: encodingMemoryThreshold, request: convertible, multipartFormData: multipartFormData) @@ -770,8 +951,7 @@ open class Session { usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold, interceptor: RequestInterceptor? = nil, fileManager: FileManager = .default) -> UploadRequest { - let multipartUpload = MultipartUpload(isInBackgroundSession: session.configuration.identifier != nil, - encodingMemoryThreshold: encodingMemoryThreshold, + let multipartUpload = MultipartUpload(encodingMemoryThreshold: encodingMemoryThreshold, request: request, multipartFormData: multipartFormData) @@ -807,64 +987,72 @@ open class Session { // MARK: Perform - /// Perform `Request`. - /// - /// - Note: Called during retry. + /// Starts performing the provided `Request`. /// /// - Parameter request: The `Request` to perform. func perform(_ request: Request) { - // Leaf types must come first, otherwise they will cast as their superclass. - switch request { - case let r as UploadRequest: perform(r) // UploadRequest must come before DataRequest due to subtype relationship. - case let r as DataRequest: perform(r) - case let r as DownloadRequest: perform(r) - default: fatalError("Attempted to perform unsupported Request subclass: \(type(of: request))") - } - } - - func perform(_ request: DataRequest) { - requestQueue.async { + rootQueue.async { guard !request.isCancelled else { return } self.activeRequests.insert(request) - self.performSetupOperations(for: request, convertible: request.convertible) + self.requestQueue.async { + // Leaf types must come first, otherwise they will cast as their superclass. + switch request { + case let r as UploadRequest: self.performUploadRequest(r) // UploadRequest must come before DataRequest due to subtype relationship. + case let r as DataRequest: self.performDataRequest(r) + case let r as DownloadRequest: self.performDownloadRequest(r) + case let r as DataStreamRequest: self.performDataStreamRequest(r) + default: fatalError("Attempted to perform unsupported Request subclass: \(type(of: request))") + } + } } } - func perform(_ request: UploadRequest) { - requestQueue.async { - guard !request.isCancelled else { return } + func performDataRequest(_ request: DataRequest) { + dispatchPrecondition(condition: .onQueue(requestQueue)) - self.activeRequests.insert(request) + performSetupOperations(for: request, convertible: request.convertible) + } + + func performDataStreamRequest(_ request: DataStreamRequest) { + dispatchPrecondition(condition: .onQueue(requestQueue)) + performSetupOperations(for: request, convertible: request.convertible) + } + + func performUploadRequest(_ request: UploadRequest) { + dispatchPrecondition(condition: .onQueue(requestQueue)) + + performSetupOperations(for: request, convertible: request.convertible) { do { let uploadable = try request.upload.createUploadable() self.rootQueue.async { request.didCreateUploadable(uploadable) } - - self.performSetupOperations(for: request, convertible: request.convertible) + return true } catch { self.rootQueue.async { request.didFailToCreateUploadable(with: error.asAFError(or: .createUploadableFailed(error: error))) } + return false } } } - func perform(_ request: DownloadRequest) { - requestQueue.async { - guard !request.isCancelled else { return } - - self.activeRequests.insert(request) + func performDownloadRequest(_ request: DownloadRequest) { + dispatchPrecondition(condition: .onQueue(requestQueue)) - switch request.downloadable { - case let .request(convertible): - self.performSetupOperations(for: request, convertible: convertible) - case let .resumeData(resumeData): - self.rootQueue.async { self.didReceiveResumeData(resumeData, for: request) } - } + switch request.downloadable { + case let .request(convertible): + performSetupOperations(for: request, convertible: convertible) + case let .resumeData(resumeData): + rootQueue.async { self.didReceiveResumeData(resumeData, for: request) } } } - func performSetupOperations(for request: Request, convertible: URLRequestConvertible) { + func performSetupOperations(for request: Request, + convertible: URLRequestConvertible, + shouldCreateTask: @escaping () -> Bool = { true }) + { + dispatchPrecondition(condition: .onQueue(requestQueue)) + let initialRequest: URLRequest do { @@ -880,19 +1068,23 @@ open class Session { guard !request.isCancelled else { return } guard let adapter = adapter(for: request) else { + guard shouldCreateTask() else { return } rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) } return } - adapter.adapt(initialRequest, for: self) { result in + let adapterState = RequestAdapterState(requestID: request.id, session: self) + + adapter.adapt(initialRequest, using: adapterState) { result in do { let adaptedRequest = try result.get() try adaptedRequest.validate() - self.rootQueue.async { - request.didAdaptInitialRequest(initialRequest, to: adaptedRequest) - self.didCreateURLRequest(adaptedRequest, for: request) - } + self.rootQueue.async { request.didAdaptInitialRequest(initialRequest, to: adaptedRequest) } + + guard shouldCreateTask() else { return } + + self.rootQueue.async { self.didCreateURLRequest(adaptedRequest, for: request) } } catch { self.rootQueue.async { request.didFailToAdaptURLRequest(initialRequest, withError: .requestAdaptationFailed(error: error)) } } @@ -902,6 +1094,8 @@ open class Session { // MARK: - Task Handling func didCreateURLRequest(_ urlRequest: URLRequest, for request: Request) { + dispatchPrecondition(condition: .onQueue(rootQueue)) + request.didCreateURLRequest(urlRequest) guard !request.isCancelled else { return } @@ -914,6 +1108,8 @@ open class Session { } func didReceiveResumeData(_ data: Data, for request: DownloadRequest) { + dispatchPrecondition(condition: .onQueue(rootQueue)) + guard !request.isCancelled else { return } let task = request.task(forResumeData: data, using: session) @@ -924,6 +1120,8 @@ open class Session { } func updateStatesForTask(_ task: URLSessionTask, request: Request) { + dispatchPrecondition(condition: .onQueue(rootQueue)) + request.withState { state in switch state { case .initialized, .finished: @@ -977,10 +1175,10 @@ open class Session { extension Session: RequestDelegate { public var sessionConfiguration: URLSessionConfiguration { - return session.configuration + session.configuration } - public var startImmediately: Bool { return startRequestsImmediately } + public var startImmediately: Bool { startRequestsImmediately } public func cleanup(after request: Request) { activeRequests.remove(request) diff --git a/Pods/Alamofire/Source/SessionDelegate.swift b/Pods/Alamofire/Source/SessionDelegate.swift index b470381..a794d83 100644 --- a/Pods/Alamofire/Source/SessionDelegate.swift +++ b/Pods/Alamofire/Source/SessionDelegate.swift @@ -50,11 +50,7 @@ open class SessionDelegate: NSObject { return nil } - guard let request = provider.request(for: task) as? R else { - fatalError("Returned Request is not of expected type: \(R.self).") - } - - return request + return provider.request(for: task) as? R } } @@ -95,11 +91,15 @@ extension SessionDelegate: URLSessionTaskDelegate { let evaluation: ChallengeEvaluation switch challenge.protectionSpace.authenticationMethod { + case NSURLAuthenticationMethodHTTPBasic, NSURLAuthenticationMethodHTTPDigest, NSURLAuthenticationMethodNTLM, + NSURLAuthenticationMethodNegotiate: + evaluation = attemptCredentialAuthentication(for: challenge, belongingTo: task) + #if !(os(Linux) || os(Windows)) case NSURLAuthenticationMethodServerTrust: evaluation = attemptServerTrustAuthentication(with: challenge) - case NSURLAuthenticationMethodHTTPBasic, NSURLAuthenticationMethodHTTPDigest, NSURLAuthenticationMethodNTLM, - NSURLAuthenticationMethodNegotiate, NSURLAuthenticationMethodClientCertificate: + case NSURLAuthenticationMethodClientCertificate: evaluation = attemptCredentialAuthentication(for: challenge, belongingTo: task) + #endif default: evaluation = (.performDefaultHandling, nil, nil) } @@ -111,6 +111,7 @@ extension SessionDelegate: URLSessionTaskDelegate { completionHandler(evaluation.disposition, evaluation.credential) } + #if !(os(Linux) || os(Windows)) /// Evaluates the server trust `URLAuthenticationChallenge` received. /// /// - Parameter challenge: The `URLAuthenticationChallenge`. @@ -120,7 +121,7 @@ extension SessionDelegate: URLSessionTaskDelegate { let host = challenge.protectionSpace.host guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, - let trust = challenge.protectionSpace.serverTrust + let trust = challenge.protectionSpace.serverTrust else { return (.performDefaultHandling, nil, nil) } @@ -137,6 +138,7 @@ extension SessionDelegate: URLSessionTaskDelegate { return (.cancelAuthenticationChallenge, nil, error.asAFError(or: .serverTrustEvaluationFailed(reason: .customEvaluationFailed(error: error)))) } } + #endif /// Evaluates the credential-based authentication `URLAuthenticationChallenge` received for `task`. /// @@ -231,12 +233,14 @@ extension SessionDelegate: URLSessionDataDelegate { open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data) - guard let request = request(for: dataTask, as: DataRequest.self) else { - assertionFailure("dataTask did not find DataRequest.") + if let request = request(for: dataTask, as: DataRequest.self) { + request.didReceive(data: data) + } else if let request = request(for: dataTask, as: DataStreamRequest.self) { + request.didReceive(data: data) + } else { + assertionFailure("dataTask did not find DataRequest or DataStreamRequest in didReceive") return } - - request.didReceive(data: data) } open func urlSession(_ session: URLSession, @@ -300,12 +304,14 @@ extension SessionDelegate: URLSessionDownloadDelegate { return } - guard let response = request.response else { - fatalError("URLSessionDownloadTask finished downloading with no response.") + let (destination, options): (URL, DownloadRequest.Options) + if let response = request.response { + (destination, options) = request.destination(location, response) + } else { + // If there's no response this is likely a local file download, so generate the temporary URL directly. + (destination, options) = (DownloadRequest.defaultDestinationURL(location), []) } - let (destination, options) = (request.destination)(location, response) - eventMonitor?.request(request, didCreateDestinationURL: destination) do { @@ -322,7 +328,9 @@ extension SessionDelegate: URLSessionDownloadDelegate { request.didFinishDownloading(using: downloadTask, with: .success(destination)) } catch { - request.didFinishDownloading(using: downloadTask, with: .failure(.downloadedFileMoveFailed(error: error, source: location, destination: destination))) + request.didFinishDownloading(using: downloadTask, with: .failure(.downloadedFileMoveFailed(error: error, + source: location, + destination: destination))) } } } diff --git a/Pods/Alamofire/Source/StringEncoding+Alamofire.swift b/Pods/Alamofire/Source/StringEncoding+Alamofire.swift new file mode 100644 index 0000000..8fa6133 --- /dev/null +++ b/Pods/Alamofire/Source/StringEncoding+Alamofire.swift @@ -0,0 +1,55 @@ +// +// StringEncoding+Alamofire.swift +// +// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) +// +// 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 + +extension String.Encoding { + /// Creates an encoding from the IANA charset name. + /// + /// - Notes: These mappings match those [provided by CoreFoundation](https://opensource.apple.com/source/CF/CF-476.18/CFStringUtilities.c.auto.html) + /// + /// - Parameter name: IANA charset name. + init?(ianaCharsetName name: String) { + switch name.lowercased() { + case "utf-8": + self = .utf8 + case "iso-8859-1": + self = .isoLatin1 + case "unicode-1-1", "iso-10646-ucs-2", "utf-16": + self = .utf16 + case "utf-16be": + self = .utf16BigEndian + case "utf-16le": + self = .utf16LittleEndian + case "utf-32": + self = .utf32 + case "utf-32be": + self = .utf32BigEndian + case "utf-32le": + self = .utf32LittleEndian + default: + return nil + } + } +} diff --git a/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift b/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift index 9ac00ef..455c4bc 100644 --- a/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift +++ b/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift @@ -48,7 +48,7 @@ extension String: URLConvertible { extension URL: URLConvertible { /// Returns `self`. - public func asURL() throws -> URL { return self } + public func asURL() throws -> URL { self } } extension URLComponents: URLConvertible { @@ -76,12 +76,12 @@ public protocol URLRequestConvertible { extension URLRequestConvertible { /// The `URLRequest` returned by discarding any `Error` encountered. - public var urlRequest: URLRequest? { return try? asURLRequest() } + public var urlRequest: URLRequest? { try? asURLRequest() } } extension URLRequest: URLRequestConvertible { /// Returns `self`. - public func asURLRequest() throws -> URLRequest { return self } + public func asURLRequest() throws -> URLRequest { self } } // MARK: - diff --git a/Pods/Alamofire/Source/URLEncodedFormEncoder.swift b/Pods/Alamofire/Source/URLEncodedFormEncoder.swift index 8da3576..dfadc2e 100644 --- a/Pods/Alamofire/Source/URLEncodedFormEncoder.swift +++ b/Pods/Alamofire/Source/URLEncodedFormEncoder.swift @@ -48,15 +48,21 @@ public final class URLEncodedFormEncoder { case brackets /// No brackets are appended to the key and the key is encoded as is. case noBrackets + /// Brackets containing the item index are appended. This matches the jQuery and Node.js behavior. + case indexInBrackets /// Encodes the key according to the encoding. /// - /// - Parameter key: The `key` to encode. - /// - Returns: The encoded key. - func encode(_ key: String) -> String { + /// - Parameters: + /// - key: The `key` to encode. + /// - index: When this enum instance is `.indexInBrackets`, the `index` to encode. + /// + /// - Returns: The encoded key. + func encode(_ key: String, atIndex index: Int) -> String { switch self { case .brackets: return "\(key)[]" case .noBrackets: return key + case .indexInBrackets: return "\(key)[\(index)]" } } } @@ -205,11 +211,11 @@ public final class URLEncodedFormEncoder { } private func convertToSnakeCase(_ key: String) -> String { - return convert(key, usingSeparator: "_") + convert(key, usingSeparator: "_") } private func convertToKebabCase(_ key: String) -> String { - return convert(key, usingSeparator: "-") + convert(key, usingSeparator: "-") } private func convert(_ key: String, usingSeparator separator: String) -> String { @@ -403,7 +409,7 @@ public final class URLEncodedFormEncoder { final class _URLEncodedFormEncoder { var codingPath: [CodingKey] // Returns an empty dictionary, as this encoder doesn't support userInfo. - var userInfo: [CodingUserInfoKey: Any] { return [:] } + var userInfo: [CodingUserInfoKey: Any] { [:] } let context: URLEncodedFormContext @@ -435,19 +441,19 @@ extension _URLEncodedFormEncoder: Encoder { } func unkeyedContainer() -> UnkeyedEncodingContainer { - return _URLEncodedFormEncoder.UnkeyedContainer(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) + _URLEncodedFormEncoder.UnkeyedContainer(context: context, + codingPath: codingPath, + boolEncoding: boolEncoding, + dataEncoding: dataEncoding, + dateEncoding: dateEncoding) } func singleValueContainer() -> SingleValueEncodingContainer { - return _URLEncodedFormEncoder.SingleValueContainer(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) + _URLEncodedFormEncoder.SingleValueContainer(context: context, + codingPath: codingPath, + boolEncoding: boolEncoding, + dataEncoding: dataEncoding, + dateEncoding: dateEncoding) } } @@ -495,7 +501,7 @@ enum URLEncodedFormComponent { /// Recursive backing method to `set(to:at:)`. private func set(_ context: inout URLEncodedFormComponent, to value: URLEncodedFormComponent, at path: [CodingKey]) { - guard path.count >= 1 else { + guard !path.isEmpty else { context = value return } @@ -592,7 +598,7 @@ extension _URLEncodedFormEncoder { } private func nestedCodingPath(for key: CodingKey) -> [CodingKey] { - return codingPath + [key] + codingPath + [key] } } } @@ -640,19 +646,19 @@ extension _URLEncodedFormEncoder.KeyedContainer: KeyedEncodingContainerProtocol } func superEncoder() -> Encoder { - return _URLEncodedFormEncoder(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) + _URLEncodedFormEncoder(context: context, + codingPath: codingPath, + boolEncoding: boolEncoding, + dataEncoding: dataEncoding, + dateEncoding: dateEncoding) } func superEncoder(forKey key: Key) -> Encoder { - return _URLEncodedFormEncoder(context: context, - codingPath: nestedCodingPath(for: key), - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) + _URLEncodedFormEncoder(context: context, + codingPath: nestedCodingPath(for: key), + boolEncoding: boolEncoding, + dataEncoding: dataEncoding, + dateEncoding: dateEncoding) } } @@ -778,6 +784,9 @@ extension _URLEncodedFormEncoder.SingleValueContainer: SingleValueEncodingContai } try encode(value, as: string) + case let decimal as Decimal: + // Decimal's `Encodable` implementation returns an object, not a single value, so override it. + try encode(value, as: String(describing: decimal)) default: try attemptToEncode(value) } @@ -802,7 +811,7 @@ extension _URLEncodedFormEncoder { var count = 0 var nestedCodingPath: [CodingKey] { - return codingPath + [AnyCodingKey(intValue: count)!] + codingPath + [AnyCodingKey(intValue: count)!] } private let context: URLEncodedFormContext @@ -927,8 +936,8 @@ final class URLEncodedFormSerializer { } func serialize(_ array: [URLEncodedFormComponent], forKey key: String) -> String { - var segments: [String] = array.map { component in - let keyPath = arrayEncoding.encode(key) + var segments: [String] = array.enumerated().map { index, component in + let keyPath = arrayEncoding.encode(key, atIndex: index) return serialize(component, forKey: keyPath) } segments = alphabetizeKeyValuePairs ? segments.sorted() : segments @@ -948,11 +957,11 @@ final class URLEncodedFormSerializer { extension Array where Element == String { func joinedWithAmpersands() -> String { - return joined(separator: "&") + joined(separator: "&") } } -public extension CharacterSet { +extension CharacterSet { /// Creates a CharacterSet from RFC 3986 allowed characters. /// /// RFC 3986 states that the following characters are "reserved" characters. @@ -963,7 +972,7 @@ public extension CharacterSet { /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" /// should be percent-escaped in the query string. - static let afURLQueryAllowed: CharacterSet = { + public static let afURLQueryAllowed: CharacterSet = { let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 let subDelimitersToEncode = "!$&'()*+,;=" let encodableDelimiters = CharacterSet(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") diff --git a/Pods/Alamofire/Source/URLRequest+Alamofire.swift b/Pods/Alamofire/Source/URLRequest+Alamofire.swift index b198fe0..be27c8e 100644 --- a/Pods/Alamofire/Source/URLRequest+Alamofire.swift +++ b/Pods/Alamofire/Source/URLRequest+Alamofire.swift @@ -24,14 +24,14 @@ import Foundation -public extension URLRequest { +extension URLRequest { /// Returns the `httpMethod` as Alamofire's `HTTPMethod` type. - var method: HTTPMethod? { - get { return httpMethod.flatMap(HTTPMethod.init) } + public var method: HTTPMethod? { + get { httpMethod.flatMap(HTTPMethod.init) } set { httpMethod = newValue?.rawValue } } - func validate() throws { + public func validate() throws { if method == .get, let bodyData = httpBody { throw AFError.urlRequestValidationFailed(reason: .bodyDataInGETRequest(bodyData)) } diff --git a/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift b/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift index de3e290..292a8fe 100644 --- a/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift +++ b/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift @@ -34,4 +34,13 @@ extension AlamofireExtension where ExtendedType: URLSessionConfiguration { return configuration } + + /// `.ephemeral` configuration with Alamofire's default `Accept-Language`, `Accept-Encoding`, and `User-Agent` + /// headers. + public static var ephemeral: URLSessionConfiguration { + let configuration = URLSessionConfiguration.ephemeral + configuration.headers = .default + + return configuration + } } diff --git a/Pods/Alamofire/Source/Validation.swift b/Pods/Alamofire/Source/Validation.swift index d0def32..1dc3025 100644 --- a/Pods/Alamofire/Source/Validation.swift +++ b/Pods/Alamofire/Source/Validation.swift @@ -36,7 +36,7 @@ extension Request { let type: String let subtype: String - var isWildcard: Bool { return type == "*" && subtype == "*" } + var isWildcard: Bool { type == "*" && subtype == "*" } init?(_ string: String) { let components: [String] = { @@ -66,7 +66,7 @@ extension Request { // MARK: Properties - fileprivate var acceptableStatusCodes: Range { return 200..<300 } + fileprivate var acceptableStatusCodes: Range { 200..<300 } fileprivate var acceptableContentTypes: [String] { if let accept = request?.value(forHTTPHeaderField: "Accept") { @@ -83,7 +83,7 @@ extension Request { -> ValidationResult where S.Iterator.Element == Int { if acceptableStatusCodes.contains(response.statusCode) { - return .success(Void()) + return .success(()) } else { let reason: ErrorReason = .unacceptableStatusCode(code: response.statusCode) return .failure(AFError.responseValidationFailed(reason: reason)) @@ -97,20 +97,27 @@ extension Request { data: Data?) -> ValidationResult where S.Iterator.Element == String { - guard let data = data, !data.isEmpty else { return .success(Void()) } + guard let data = data, !data.isEmpty else { return .success(()) } + return validate(contentType: acceptableContentTypes, response: response) + } + + fileprivate func validate(contentType acceptableContentTypes: S, + response: HTTPURLResponse) + -> ValidationResult + where S.Iterator.Element == String { guard let responseContentType = response.mimeType, let responseMIMEType = MIMEType(responseContentType) else { for contentType in acceptableContentTypes { if let mimeType = MIMEType(contentType), mimeType.isWildcard { - return .success(Void()) + return .success(()) } } let error: AFError = { - let reason: ErrorReason = .missingContentType(acceptableContentTypes: Array(acceptableContentTypes)) + let reason: ErrorReason = .missingContentType(acceptableContentTypes: acceptableContentTypes.sorted()) return AFError.responseValidationFailed(reason: reason) }() @@ -119,12 +126,12 @@ extension Request { for contentType in acceptableContentTypes { if let acceptableMIMEType = MIMEType(contentType), acceptableMIMEType.matches(responseMIMEType) { - return .success(Void()) + return .success(()) } } let error: AFError = { - let reason: ErrorReason = .unacceptableContentType(acceptableContentTypes: Array(acceptableContentTypes), + let reason: ErrorReason = .unacceptableContentType(acceptableContentTypes: acceptableContentTypes.sorted(), responseContentType: responseContentType) return AFError.responseValidationFailed(reason: reason) @@ -145,12 +152,12 @@ extension DataRequest { /// /// If validation fails, subsequent calls to response handlers will have an associated error. /// - /// - parameter range: The range of acceptable status codes. + /// - Parameter acceptableStatusCodes: `Sequence` of acceptable response status codes. /// - /// - returns: The request. + /// - Returns: The instance. @discardableResult public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { - return validate { [unowned self] _, response, _ in + validate { [unowned self] _, response, _ in self.validate(statusCode: acceptableStatusCodes, response: response) } } @@ -164,7 +171,7 @@ extension DataRequest { /// - returns: The request. @discardableResult public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { - return validate { [unowned self] _, response, data in + validate { [unowned self] _, response, data in self.validate(contentType: acceptableContentTypes(), response: response, data: data) } } @@ -184,6 +191,54 @@ extension DataRequest { } } +extension DataStreamRequest { + /// A closure used to validate a request that takes a `URLRequest` and `HTTPURLResponse` and returns whether the + /// request was valid. + public typealias Validation = (_ request: URLRequest?, _ response: HTTPURLResponse) -> ValidationResult + + /// Validates that the response has a status code in the specified sequence. + /// + /// If validation fails, subsequent calls to response handlers will have an associated error. + /// + /// - Parameter acceptableStatusCodes: `Sequence` of acceptable response status codes. + /// + /// - Returns: The instance. + @discardableResult + public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { + validate { [unowned self] _, response in + self.validate(statusCode: acceptableStatusCodes, response: response) + } + } + + /// Validates that the response has a content type in the specified sequence. + /// + /// If validation fails, subsequent calls to response handlers will have an associated error. + /// + /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. + /// + /// - returns: The request. + @discardableResult + public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { + validate { [unowned self] _, response in + self.validate(contentType: acceptableContentTypes(), response: response) + } + } + + /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content + /// type matches any specified in the Accept HTTP header field. + /// + /// If validation fails, subsequent calls to response handlers will have an associated error. + /// + /// - Returns: The instance. + @discardableResult + public func validate() -> Self { + let contentTypes: () -> [String] = { [unowned self] in + self.acceptableContentTypes + } + return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) + } +} + // MARK: - extension DownloadRequest { @@ -198,12 +253,12 @@ extension DownloadRequest { /// /// If validation fails, subsequent calls to response handlers will have an associated error. /// - /// - parameter range: The range of acceptable status codes. + /// - Parameter acceptableStatusCodes: `Sequence` of acceptable response status codes. /// - /// - returns: The request. + /// - Returns: The instance. @discardableResult public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { - return validate { [unowned self] _, response, _ in + validate { [unowned self] _, response, _ in self.validate(statusCode: acceptableStatusCodes, response: response) } } @@ -217,7 +272,7 @@ extension DownloadRequest { /// - returns: The request. @discardableResult public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { - return validate { [unowned self] _, response, fileURL in + validate { [unowned self] _, response, fileURL in guard let validFileURL = fileURL else { return .failure(AFError.responseValidationFailed(reason: .dataFileNil)) } diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 787fe51..ddabf3b 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,5 +1,5 @@ PODS: - - Alamofire (5.0.5) + - Alamofire (5.5.0) - Kingfisher (6.3.1) - RxCocoa (6.5.0): - RxRelay (= 6.5.0) @@ -10,10 +10,10 @@ PODS: - SnapKit (5.0.1) DEPENDENCIES: - - Alamofire (~> 5.0.0) + - Alamofire (~> 5.5.0) - Kingfisher (~> 6.3.1) - RxCocoa (~> 6.0) - - RxSwift (~> 6.0) + - RxSwift (~> 6.5) - SnapKit (~> 5.0.0) SPEC REPOS: @@ -26,13 +26,13 @@ SPEC REPOS: - SnapKit SPEC CHECKSUMS: - Alamofire: df2f8f826963b08b9a870791ad48e07a10090b2e + Alamofire: 1c4fb5369c3fe93d2857c780d8bbe09f06f97e7c Kingfisher: 016c8b653a35add51dd34a3aba36b580041acc74 RxCocoa: 94f817b71c07517321eb4f9ad299112ca8af743b RxRelay: 1de1523e604c72b6c68feadedd1af3b1b4d0ecbd RxSwift: 5710a9e6b17f3c3d6e40d6e559b9fa1e813b2ef8 SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb -PODFILE CHECKSUM: 1b558f44619140af2d32ff330f92dff687a62721 +PODFILE CHECKSUM: c41a595eb47fc44e36c18a98ff4debc2ff429de8 -COCOAPODS: 1.11.3 +COCOAPODS: 1.14.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 46aa994..4c83053 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,976 +7,984 @@ objects = { /* Begin PBXBuildFile section */ - 003529825227D8DD63F0BF82EC1495D3 /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94775AC80AD2CDC009C836D6249E04B5 /* CombineLatest+Collection.swift */; }; - 0044A3FDBB31A48BCEFB440629E55727 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A549A9EB6AF7788C2602ACBFEB019EAF /* DiskStorage.swift */; }; - 006A2002DB7553ED9AB3618CBC63E855 /* Infallible+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32193DD28EB90453567A59F1A182F96D /* Infallible+Operators.swift */; }; - 00BC5B820A644B40EDF5BD3BCFEFA3E9 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E913CE22A6FD9AC2977EE4115A73181D /* Filter.swift */; }; - 00FDD8535AF5C1682B1D2E4F545132F8 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479AC0D0C5CE3FD96E9568934D3C050F /* KingfisherError.swift */; }; - 026D2A43CE05B83568AD0C0A27BE7016 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D75B4BD74A428B33BC3091D935894D4 /* ImageProcessor.swift */; }; - 02D728C97AA23F2F5E00FCF14E27ADCB /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536AE0412E79AAD5D7758292B3B75D0B /* ImageDownloaderDelegate.swift */; }; - 02EFA6ACF4D3AE6304BC14E70446620B /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B12F9ECAACAE51F90B804AABFCBF3650 /* SynchronizedUnsubscribeType.swift */; }; - 038AB96B88DB40E752F02C8FCE7660DD /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B0287E747640F717C72FCFD5602A81 /* SchedulerServices+Emulation.swift */; }; - 03B10230C0061FFC0A8DFEE43D89E34E /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5250B99AAE6D169C5028D00075D20CBA /* Sample.swift */; }; - 057D0EC1E728D714A73210ACAF1FAC6A /* UISearchBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC36F9E06FE49F1F4F80BB1AFA71E98E /* UISearchBar+Rx.swift */; }; - 05B17AA3CBF543D79BB998C04CC622A5 /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA742B9CCC6986A75BCC203D8A301748 /* ScheduledDisposable.swift */; }; - 062FE837FDFE764F1D436E09091F603F /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7085CE1B5550909B6FB91DBF692233F3 /* SingleAssignmentDisposable.swift */; }; - 0711535FB48EC83DBCE90D4E9CCE53DE /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406336451769C4ABD13D928D18C358F6 /* HistoricalSchedulerTimeConverter.swift */; }; - 07550E0A8451CACE9593873C543F1B78 /* RxTabBarControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9060E46ABEBE8DF1C9F5CDBEA8F03188 /* RxTabBarControllerDelegateProxy.swift */; }; - 087E291F962A0417B329954FD7C3F893 /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE696321DE0FE56CB61C37952EE0F2A /* ScheduledItemType.swift */; }; - 08C84EEEE16985BD11B48DE78F6CE6D8 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE614EF7725D1080DC262AA7AF3B9C30 /* Repeat.swift */; }; - 0907413AF1BF312948C6CA8289CE29AE /* ControlProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 709DF0E3B25C0AEE4AAFB24B57499054 /* ControlProperty.swift */; }; - 0AAED9A61C81D9CB80C27AB80B3042F0 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FB0AB5EBB9EAF18968D0715DC6473EF /* AnyObserver.swift */; }; - 0B5BB08F1937AD6324F0ADDD8F9E067B /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D1B38AC6033251DAD312CD6B3A92EC2 /* Driver.swift */; }; - 0C71B7665BA02D8C812B1BAB001AFBF3 /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56F39816D76F06712167096FF3E3A5F /* Single.swift */; }; - 0D5C6C08DC865F5735FFC53083A87E34 /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4932F8F6F0A427742452AC9CF0D58C77 /* BinaryDisposable.swift */; }; - 0D8821DA7F4A20C4E52375DE9EC7B3C8 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129BE48ECDE18236FCECEFF00958A22E /* Alamofire.swift */; }; - 0DDEB8F8134858BFE1BD79BEE1306D5B /* WithUnretained.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B19C706685F1007CFA37D8B72F4A84 /* WithUnretained.swift */; }; - 0EC603595AF7780DCAD4BB7B627429BD /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152DA282A487530C176A0B25C8DF6883 /* DisposeBag.swift */; }; - 0F92B9A07E035FA87974066F7F77324D /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6715A6CAA80600D08EC4B8F2671014AD /* ReplaySubject.swift */; }; - 111810B8652D290C58076B92FCE40A1F /* RxPickerViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8162421B4BB84E20689FE291FFFAF647 /* RxPickerViewAdapter.swift */; }; - 114F6342633413C8BBEC4169F34CFAFD /* RxTextViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F57960FCF66D2D01C89E218FB41DA8 /* RxTextViewDelegateProxy.swift */; }; - 11D7AF9C6C5DF6D54FB9BB57FF95C789 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22FC7E45CD1650C4C37F3C8C97FA02F7 /* HTTPHeaders.swift */; }; - 1274F535FAD2AB23DA7B5D68770F529D /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2BC13603EB21A257F88ADDCDBB022C8 /* Lock.swift */; }; - 144DA93A55A598F5197F10C729FBDD69 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DE2CE1E44745DF7D91F7A5994CE22A6 /* UILayoutSupport+Extensions.swift */; }; - 1451EF8D38345972B7802EC526427399 /* URLEncodedFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B49579A82C0539E33F8DB78641B1E64 /* URLEncodedFormEncoder.swift */; }; - 14CAA40442778EFE3DF8B07CE170CAF7 /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E784C3A6B34056D0BBA3B30E79142A7E /* UITextView+Rx.swift */; }; - 14DD900A869D976EEC05A4813F679F9B /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3315AD200F0B9AD525D212C0C41504 /* Observable+Bind.swift */; }; - 1511A1B3AAE6EA7518B9F27064AED034 /* AlamofireExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83C680BD4FC55B43A8CED179AD14F46 /* AlamofireExtended.swift */; }; - 1637E895C6DF5D03D94B7FB4D4058094 /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE4529CDBEBC039DFAA7036AB45EE30 /* AddRef.swift */; }; - 1676EBFB2688BEF9C5735FC4367BE9AB /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1057D4EB481C24ACA874B22DB4B986C /* Multicast.swift */; }; - 17478E54C6BBAF4457E68255F8AF9438 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A6AE6EEE6FB189C7673B9F58C77757 /* Storage.swift */; }; - 1787EBB3723875770997006509209EDD /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141B4D876D24D86E863F48BAC657EBC7 /* RxTableViewDataSourceProxy.swift */; }; - 17BE0F4E51B0FB968125F1A520607FD8 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E9B3BDCF2E5186E2849A421BD65BA04 /* ConstraintMultiplierTarget.swift */; }; - 18211EE7B495AA06EBBED1D6FD9423C0 /* RxCocoa-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 462935E91ED59AF6B20ADE9631564D6B /* RxCocoa-dummy.m */; }; - 18540C7423267A7B483B5EAC9F2FBB5F /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85637ACD268647B3D9AB2FCF1640346 /* Box.swift */; }; - 1ABA1120B49E8646A878BBFA7C8BB8F1 /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5378FB89697FC8EA7FBC2EFCA76477CB /* ObserverBase.swift */; }; - 1CC3FBF38E35B664C2A003664C58E2D7 /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8500C3892A8916E27BA49771DDC39F84 /* ControlEvent.swift */; }; - 1E9EEA756F2774D73347F1660EEFE3E9 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E896F1E52CD239FF87B9110061B1B63 /* ConstraintView+Extensions.swift */; }; - 1F64C124283555FF5E1944FA37501247 /* Signal+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EBB6166F378B6BA3BA6045513AD0B68 /* Signal+Subscription.swift */; }; - 1F6F0B8C1A8EA633EFEBE64EB781A6B5 /* UINavigationController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86DC6ACB03731C01E7B7EBCE23FB1BE9 /* UINavigationController+Rx.swift */; }; - 1FDAC05CC3009148EDA8F5430102BCFA /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A38E734191D770256D5CA30A7EB1BFE /* SubscriptionDisposable.swift */; }; - 1FFFBA87BB294E55ABCE4D9D0B3A7F0C /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = B041565AEEC2F2E374E5AEA0A1805FBA /* TailRecursiveSink.swift */; }; - 2087DD8278E2FC32F75C947E058EA423 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF91FDC5BD806070B5160246987FD3D5 /* NSObject+Rx+KVORepresentable.swift */; }; - 209DFCE93A5CF41A91DCEC111EB56FB8 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2AE61FD67D2D52D425F6BED79AE568 /* AnonymousObserver.swift */; }; - 2217757B24795601647F0A8F172A4612 /* Infallible+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562B01E7D1CBAA099413E50DB98212AC /* Infallible+Zip+arity.swift */; }; - 22B6F0C1A05920D99B711B48B92C124A /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7737EEE6716D463DA348B99E54B89E6 /* KingfisherManager.swift */; }; - 23C85249FB680DCA52B7BA19476D5CE4 /* Infallible+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5FE232EFFF73B7C3D25288BA3912B7 /* Infallible+Create.swift */; }; - 24A65E78F2118F2166E6B18444780FBE /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACEDFBBA5F76F3B47E6A904879318588 /* Platform.Darwin.swift */; }; - 24B2DFC51D8E53D808B5AC4FEC136A8C /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16AEBDE0AC9FA3063D48EE7921A25B1 /* Generate.swift */; }; - 24C5A0C0ED89D44C92D190198464F891 /* Infallible+CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6D96E71D0D40BFA9ED18FE23078F8F /* Infallible+CombineLatest+arity.swift */; }; - 24C8FC3B11676AD57F3A7914E6621AD0 /* TextInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EE84A906E3B42A400F7A6A21B74204B /* TextInput.swift */; }; - 2513FB19DADC28C9C34578D1E1E4AB49 /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7015A2723C7EB58E15977193C5ADE30A /* AnonymousDisposable.swift */; }; - 252B64A12E2810921E86B78ECD5BDA9D /* UIApplication+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB4873AE1C8F057BB406BD437FEBEC0 /* UIApplication+Rx.swift */; }; - 25D532E8E212D1E6D3A57ADFC56A4BA8 /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AD5FC6299043CD5F0F76E73F4F7411F /* ConcurrentMainScheduler.swift */; }; - 263A6B3B9C8592FC16697D2AB6333AC9 /* RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95488DC7B444610250080F96F0BB9942 /* RxCocoa.swift */; }; - 26415B02C09B34CFEB3027EC9AC305DD /* RxSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A988A7455383F560A9BBAA36315E494 /* RxSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 26462C4BC9EE339C39FB1587BB80AB90 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 412E7CB493D9A51E0BEB16EEB73977AE /* ImageProgressive.swift */; }; - 2662EA3D1400EC4BD90947902CD85670 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 028879668058DF7CB3068D2F773FC498 /* Platform.Darwin.swift */; }; - 27439EC248E4B251AD954321490C7FAE /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1A11CA657EBFC3AE9A5FAA8F50C737 /* AnimatedImageView.swift */; }; - 274DF0E2BF04F6F4F9F1E70CF513A4F2 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBA261C0E4D59E792E2A1E87DA48CD3 /* ConstraintLayoutSupportDSL.swift */; }; - 275C15979C1EC7DB6234974758037906 /* PublishRelay+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95079D39BC909C1A6BAD48240CC1CEBA /* PublishRelay+Signal.swift */; }; - 27F2BE5D6E990841E8DA1DF91CF3623B /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0944E5F4EFFF24A475580B10825367 /* Signal.swift */; }; - 28B20C35F4E1B3DDE716C831B049ADBC /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = 284D083D86D8F6BDAA4B8916E8986BAB /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0044A3FDBB31A48BCEFB440629E55727 /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4ED1922D596A1522D90C5B55D697E8E /* DiskStorage.swift */; }; + 005B319B494ED2DAA239B9939A504DFC /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CC1E8344C026E264D4315EB2020BCB3A /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 00BC5B820A644B40EDF5BD3BCFEFA3E9 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA5D5163A1B894A0D3138DB29FAB037 /* Filter.swift */; }; + 00FDD8535AF5C1682B1D2E4F545132F8 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D17F5C46B8A9F8C14865CEF5914AB30 /* KingfisherError.swift */; }; + 026D2A43CE05B83568AD0C0A27BE7016 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E04658D6282D9191364B13B66A898 /* ImageProcessor.swift */; }; + 02D728C97AA23F2F5E00FCF14E27ADCB /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAD8A267F66DAD110741B2A5847070E /* ImageDownloaderDelegate.swift */; }; + 040F811D74F46D9E5E2E21E279A286BE /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2DF563BC203205607B72B98451BF9AA /* StartWith.swift */; }; + 045DE6EBF9B2F63F60F5BE60C1198E06 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425F7E64E335FA34B416F1317A984EEB /* RedirectHandler.swift */; }; + 04A896288CE3A59B530250337A5F8362 /* Result+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5A231091AC6A99D67423C54E54C73F /* Result+Alamofire.swift */; }; + 057D0EC1E728D714A73210ACAF1FAC6A /* UISearchBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6381EDBFEDA485DF5135E051EF6974B /* UISearchBar+Rx.swift */; }; + 05A8F828C4201F7676F7CF8EB8702202 /* Materialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C646DE8A55223D410F9282227BBE415 /* Materialize.swift */; }; + 05DB3398410D00A29CAB5182BF082F2E /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E98055623D69273DF17B778130628B8 /* SubscriptionDisposable.swift */; }; + 070B0668A4816AA8D209CE03F1AA1745 /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E85E1CDB9FB613F8CE69DCB854E6B399 /* SingleAssignmentDisposable.swift */; }; + 07166547D925FBEA343B0422FD7DEB7E /* ObservableConvertibleType+Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA391D692A854BE386E250FA9D185E /* ObservableConvertibleType+Infallible.swift */; }; + 07550E0A8451CACE9593873C543F1B78 /* RxTabBarControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49839FCD719095B1D043C2DB596E3B40 /* RxTabBarControllerDelegateProxy.swift */; }; + 07582CEA8DC77C25931E0DDACC0C3269 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94DC3DF73BAE5D55802A8D13A41C0AD3 /* PriorityQueue.swift */; }; + 080E0523C9BBA39EF80A71980E51DA5E /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88509CE697A792FDB49CFA1BB4ACA90D /* Disposable.swift */; }; + 0907413AF1BF312948C6CA8289CE29AE /* ControlProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03631B268C3CCC37CED157024CF4D3DD /* ControlProperty.swift */; }; + 0B12E30FD2871EBA945FCB86CC41E19F /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A05DCE6FA0242DB558250D79B85A28 /* ReplaySubject.swift */; }; + 0B5BB08F1937AD6324F0ADDD8F9E067B /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AAF61DCEE7EF17C7D4E598C5194836D /* Driver.swift */; }; + 0BC5830BB75BEEF69930604F6B1B53EE /* Pods-GenderList-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F76B9A485E25F7856CEB67B8CD8B569 /* Pods-GenderList-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0C2471C1F78F47C8696883DA70244567 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDC090E508088FF0C0A3490F4B4AC21F /* Empty.swift */; }; + 0DB401851069F210560BA725D4F4CAF6 /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACFE08527ACEE2E4AA211BEA97F4F2A /* Skip.swift */; }; + 0F4037DBF307AC8058BD0A3D35C7E7E9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; + 10AD2C259E9DECD6516963DB76B0C6E7 /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8005737AEE2B81D048D33A714C51C5 /* ObserveOn.swift */; }; + 10E168448465F345FD4B066137DDE094 /* PrimitiveSequence+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385B3A35B5E22B7F48613B00712041DF /* PrimitiveSequence+Zip+arity.swift */; }; + 111810B8652D290C58076B92FCE40A1F /* RxPickerViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CD2C62A0338F3123A15A325CF410C46 /* RxPickerViewAdapter.swift */; }; + 114F6342633413C8BBEC4169F34CFAFD /* RxTextViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B07F4E91969B4B4290F4E935C528AC4 /* RxTextViewDelegateProxy.swift */; }; + 11C98784D59E26A28BAA5B6C6E124171 /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1E7777904C53C224AD9EC13928AA60 /* HistoricalSchedulerTimeConverter.swift */; }; + 12CB7722128E10A05B97E964648176A9 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A8D5E730EDA418197D591546FAB0A8 /* CurrentThreadScheduler.swift */; }; + 14103A1B6CD67EF986AD72A427DAE05D /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 490A189B6330719AAC1C4AFFF3A4A3F7 /* HistoricalScheduler.swift */; }; + 143B498E689291494AD40758D734F974 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C047D0F4457085742D9DF66A00FACEE0 /* CompositeDisposable.swift */; }; + 144DA93A55A598F5197F10C729FBDD69 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F7056A97FEB5FCB2C86F9686D2C0F8 /* UILayoutSupport+Extensions.swift */; }; + 14CAA40442778EFE3DF8B07CE170CAF7 /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11B01A2390CA2DDDD676D1A67BD0C02D /* UITextView+Rx.swift */; }; + 17478E54C6BBAF4457E68255F8AF9438 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408F9B427B8BCFDAF73895D578D2FF5C /* Storage.swift */; }; + 1787EBB3723875770997006509209EDD /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD31B7D0E44D1C6D267C74B719E9C93E /* RxTableViewDataSourceProxy.swift */; }; + 17BE0F4E51B0FB968125F1A520607FD8 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3578A3CC608B05A5F1CD876FDAE5D161 /* ConstraintMultiplierTarget.swift */; }; + 17FAB8774A648669CA75A478645DF845 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517BDC1669294A148E4DBFD5B37E4CA0 /* DisposeBag.swift */; }; + 18211EE7B495AA06EBBED1D6FD9423C0 /* RxCocoa-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C7070925A0D5B91896AFBB46ADB57F /* RxCocoa-dummy.m */; }; + 18540C7423267A7B483B5EAC9F2FBB5F /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8975545EC3285FA17F23C282511FAF50 /* Box.swift */; }; + 1976BB7D7E26A12E29283E71154B63B3 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 276D3909A04A45FFEFE39B92A608A913 /* SessionDelegate.swift */; }; + 19BADD00C75B7763A633262950845DAD /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = FADFCB60B88A2B9122979E57337B8D47 /* SynchronizedUnsubscribeType.swift */; }; + 1A332D930FE477DE8318B47F7803A563 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C103FEEAA25720139580FD379B94F4C /* Zip.swift */; }; + 1B7FA91C59963D6D4ACFEAE8A4A57346 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C42A7163BD5ADE05A3340C6B8B5D22 /* Using.swift */; }; + 1CC3FBF38E35B664C2A003664C58E2D7 /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9738AD838D2B289843146F132AB003E9 /* ControlEvent.swift */; }; + 1E9EEA756F2774D73347F1660EEFE3E9 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E1371BA56D60F8CA446C7DA1840DDF /* ConstraintView+Extensions.swift */; }; + 1EE44196E7BCE57AD96A2C751651EF40 /* AlamofireExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0874EF395F89BC8B395CAD49E98ECE8 /* AlamofireExtended.swift */; }; + 1F64C124283555FF5E1944FA37501247 /* Signal+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BAD09D260831792CA65A8C5971A26C /* Signal+Subscription.swift */; }; + 1F6F0B8C1A8EA633EFEBE64EB781A6B5 /* UINavigationController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8292E3BE05ACD436F29CF9A67287A8DF /* UINavigationController+Rx.swift */; }; + 2087DD8278E2FC32F75C947E058EA423 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E8EEC36578F8DBF0309DD73B87D4329 /* NSObject+Rx+KVORepresentable.swift */; }; + 224AAE0A17EFBA22B5BB1C6ED639F402 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = E70B523D086F737CC0FC6FF2968EF50C /* Deferred.swift */; }; + 22B6F0C1A05920D99B711B48B92C124A /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E0A84821DDFA668496084FB50DA7526 /* KingfisherManager.swift */; }; + 244D5334C89FF0F1985C9D808A76BAAB /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B8074DCF34AA82F470D83BE9AFA22EA /* Delay.swift */; }; + 24C8FC3B11676AD57F3A7914E6621AD0 /* TextInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4724C270B204A600A8253615CC123F48 /* TextInput.swift */; }; + 252B64A12E2810921E86B78ECD5BDA9D /* UIApplication+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D2324A70BFC56DC0C74F69EC2072986 /* UIApplication+Rx.swift */; }; + 253D546E5EB89E7C442A752B69564D13 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC8A68F8FC8A03F8C5839FD7419DFC46 /* Rx.swift */; }; + 262D15F6C2011395F33AB0501C7461E1 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF943837465A8C84EE5469F9C9938D3F /* Debug.swift */; }; + 263A6B3B9C8592FC16697D2AB6333AC9 /* RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7449A6095EB1BA269B3C2B73CBDB28D /* RxCocoa.swift */; }; + 26462C4BC9EE339C39FB1587BB80AB90 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649025AAC69E92BE8E9ABB1A2DDF2FB8 /* ImageProgressive.swift */; }; + 2662EA3D1400EC4BD90947902CD85670 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB22C6A389B7E966F793D95F308B669C /* Platform.Darwin.swift */; }; + 272DA99C6C6A82CCEF70E8CF8B873D94 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F81CBB69E8A5AE33C9EBECB5F6529AC5 /* LockOwnerType.swift */; }; + 27439EC248E4B251AD954321490C7FAE /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE61D79694AAA7EB29E379C8487EE71 /* AnimatedImageView.swift */; }; + 274DF0E2BF04F6F4F9F1E70CF513A4F2 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = C711A78D09F3C9ED05DD103F20ED97F8 /* ConstraintLayoutSupportDSL.swift */; }; + 275C15979C1EC7DB6234974758037906 /* PublishRelay+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71DE11D37B0EB2DC6721E198C5B7BB94 /* PublishRelay+Signal.swift */; }; + 27BA74FBFD8AD9ADF754DF034688F72E /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DE826C87D74FA780918D4C7EA87B7AE /* ScheduledItemType.swift */; }; + 27F2BE5D6E990841E8DA1DF91CF3623B /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E502569324A3191D2009A6E9CD8CAF3 /* Signal.swift */; }; + 28B20C35F4E1B3DDE716C831B049ADBC /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = 87C197CF31D13B491047064857E79C4E /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2908872F21FB19B361D3652D0056DFDB /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E32787F7DBEBBED4C99A7FFD8F195D /* DispatchQueueConfiguration.swift */; }; 2987A730911012C32AF6695D7B54E35C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 2A0CB23553025DF5BB5B60EFFFFEA7C2 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA67DA9621D034A48C86105DBADC18FE /* Zip+arity.swift */; }; - 2AC794BEBE17BA6257A13065584EC5DF /* UIDatePicker+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E153A1EECE82F48D2805239759A549A /* UIDatePicker+Rx.swift */; }; - 2BA426F407BDD206249741EE13AB5B96 /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB8FFF121EEF33CEBB22766BD88B0155 /* DisposeBase.swift */; }; - 2C73603918E898CEA2BF2FDFF18D2647 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB53906BE6B2C9E6204708B943C66E8 /* Result.swift */; }; - 2DA79588D9A8DEC192452C4A212F821F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 2E73AAE2F6805B99206072ED5F1277D3 /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDF289925E0A8E8FE110FC2EE0FC5BC /* Reactive.swift */; }; - 2EB095DFF0B594D56E26FE6B1F74EB4E /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5240A0E2DBF5D9ECEF0F5D53B084DDF2 /* Do.swift */; }; - 2EBACF29960484C3DD698ED9CE49DE8B /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7DB5BA65C1FFABAEC78D90F6FDC6C8 /* CombineLatest+arity.swift */; }; - 2EFF6DCB0FC66EB564B96A35840D5016 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9991701AA0379D8817CEDBF9CAEDE1A4 /* RxTableViewDataSourcePrefetchingProxy.swift */; }; - 2F07689706119A5D6B3CC81E5016828B /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B2E58EF22EE740478AB6EAD4AA54A3 /* Kingfisher.swift */; }; - 2F576B42FE853AEF2C4676FAF09A833E /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C9BA669A8F668C0A88722EACEF84AF /* ImageDataProcessor.swift */; }; - 2FCB2ACD70577ABB671FE45F3C9070BB /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = C26EC0D0D63F0FB850F30A10CBE850E2 /* Sink.swift */; }; - 2FCCAB4BA1D71EDB993309159D5DFA7C /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39921C9633DF11B9BEB63A732BCC0FDB /* RecursiveLock.swift */; }; - 32339670CD2AA246DD7A83E12958CB32 /* ParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84BB4804259F96248E7DB341FCDFDC8 /* ParameterEncoder.swift */; }; + 2A7A4AA32A47E5F76D5852627E847709 /* Infallible+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6886B33994444A6EB9CAC1264FF0D5C /* Infallible+Concurrency.swift */; }; + 2AC794BEBE17BA6257A13065584EC5DF /* UIDatePicker+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB614DA2D2E0151F1A14D72578F6B1B /* UIDatePicker+Rx.swift */; }; + 2BB7186EA78C0BEA6074FA94DC89EF93 /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F31398DA34BA86AB6669FCF1628199E /* ConcurrentMainScheduler.swift */; }; + 2C73603918E898CEA2BF2FDFF18D2647 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450683C53D82531C94866107D76A268D /* Result.swift */; }; + 2CBE3651CA006E19F5D64A2DE9B9A028 /* CachedResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E40213495C29B7EC0897128E18347B9 /* CachedResponseHandler.swift */; }; + 2CCD13099063CD560E3067BD132914FA /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3E9FBB96DD375A4691E77F12BAD394 /* Notifications.swift */; }; + 2E54617FA1E9EC5685D2A4B074AC6933 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AF170ACB6E5383A95764D1A3DA168A /* Error.swift */; }; + 2EFF6DCB0FC66EB564B96A35840D5016 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0C7B81DA43217A2842F181A0413B81 /* RxTableViewDataSourcePrefetchingProxy.swift */; }; + 2F07689706119A5D6B3CC81E5016828B /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCD8F726BA2E1ED840CB2402B98E783 /* Kingfisher.swift */; }; + 2F576B42FE853AEF2C4676FAF09A833E /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39AD7A483064C6E2459F057D93C37603 /* ImageDataProcessor.swift */; }; + 2FCCAB4BA1D71EDB993309159D5DFA7C /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6335C0CBDFEB0A267F383DF5A5D0E209 /* RecursiveLock.swift */; }; + 30861AE693796F9D18ADE3D3C5035775 /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A338F46E55BB4522632D9A50330DE81 /* PublishSubject.swift */; }; 3315E95E92C3EC0D0D28A68819FFCC38 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 872D7EFA572ECEE8EF993C27196E16DD /* CFNetwork.framework */; }; - 3480362213CE1B3E13CA6FAFFD8BF9AE /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44272824E10DE63C3D91E362DAC954CE /* Scan.swift */; }; - 363FBBAD311FC8F84AF4559B3EC7E675 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803AA769B8BDFAFF27D2D09489678DE4 /* FormatIndicatedCacheSerializer.swift */; }; - 371CD58570B89DE6A3090CC6CE16AEE7 /* UIControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6D3755550E71F3C4ED3DBF77FDAF45 /* UIControl+Rx.swift */; }; - 3765A7BB07948D911C3967CA00ABD8D8 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C78AA19DC4AE9B2EE6F6022F07E84E07 /* Rx.swift */; }; - 377229136C0061FE2FABE71862C2070F /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = B42016A0131B39159AFDAD957DB09CD6 /* ItemEvents.swift */; }; - 3779F674B0AEC1D521014BCE5F6F3848 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D2664CB995F0C4C70CC1ABB49CC79A /* NSTextAttachment+Kingfisher.swift */; }; - 38931F9E5F98AA760F597D471120E2D8 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67DD57B81172C762BFE739FC04F4D21E /* BehaviorSubject.swift */; }; - 39C9D0DD86007D936C1EF580BBCBECD8 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF013F915831C54C604373BFD7FF75D /* CombineLatest.swift */; }; - 3A379670D0CFBC0FCC9D0F66E944D074 /* RxTextStorageDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91C7499695875934CFF0EAC81F7E26C5 /* RxTextStorageDelegateProxy.swift */; }; - 3A4BE47A7EA1BFB1F541C2CD484DBF00 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448120BB0477A55852FA955184FE5616 /* Timer.swift */; }; - 3A6190395ABD4FAB0D01396D60ECEE90 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B578AF8941617056FE4E294D356E78 /* SingleAsync.swift */; }; - 3A65F4B7F9CB8CEB5AC5EE4BE071F147 /* GroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6DDE21B51F954F2DCA17A42FA6C7DF9 /* GroupBy.swift */; }; - 3A9561E1B5358D977E435B6EB6A4F6CB /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F00B9A5E2C77D491F42C7A323D89434 /* ConcurrentDispatchQueueScheduler.swift */; }; - 3B60C02F6E42FD06B128473E00A94224 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = D529B43DBB7B1DA17E601A091D5305BB /* ConstraintLayoutSupport.swift */; }; - 3CD5FAFC746A76D73C3F501734199DFF /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66CA00697CC0D00401E693CB52991330 /* Typealiases.swift */; }; - 3DEDFA52B3A196F6D3E1F0937617628A /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C004D11372137CC8A4B3C27854344E /* ConstraintLayoutGuide+Extensions.swift */; }; - 3E77C4C09A0F4336872981489D54B383 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F413AB8BC1E3A11E7767EE9B3B3B0E /* CurrentThreadScheduler.swift */; }; - 3EE7A29FCEE9B2A257B977E7137BC44C /* UITabBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A3BCDC3D9A45F0A36083EB4A32CBB59 /* UITabBar+Rx.swift */; }; - 3EFE8454C7301C05A00EC9870F47968B /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E16C9210350E4CF9F59ED55DE6C2EAE7 /* RxTableViewDataSourceType.swift */; }; - 3FDCE9C2E56ABA304C073C50BAD9D846 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C96CEE8260D1D4000BBBEDFB62CD8D3 /* ElementAt.swift */; }; - 4053ECC897CAC1F62BC99C732FCF580B /* RequestTaskMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61070FC24D3DD3C05630D2FD00ECF898 /* RequestTaskMap.swift */; }; - 4064E1BA55209CB585990AC94219994A /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9884F54F21ABFA557C53E40DD34E35B3 /* SerialDispatchQueueScheduler.swift */; }; - 40F3DAF1936046738D56C2C9756233B9 /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE24B1808CCB08EBA787BC2F6C8C9C2 /* SchedulerType.swift */; }; - 419A11A8F7797E02FA5AAC6D8B4B3C2F /* UIStepper+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A5BE2F78CB18678F6C66C43494879 /* UIStepper+Rx.swift */; }; - 4251CDB971A8B94270E34381974BC9F8 /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 77A079F61C4AB9506A8A7123727E58A3 /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 426C76C68C9FA3582F26BBB9E96316E4 /* _RX.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CB6D05E236E726EBA220EB8AD8AB58 /* _RX.m */; }; - 42BB3620C4E2FBAB5B2C7FCD6DF2E4A3 /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042A5EC597C796CAE77BFA7517A5593C /* Take.swift */; }; - 436E17890492213E314F4522A84066E9 /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF937DC1BF9020E271091491FB8CF954 /* DelaySubscription.swift */; }; - 43863B6D6A0E47B6648BB7B469736EDD /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D6EC6EA4C2491D9C1946FFC2D0F77D /* LayoutConstraint.swift */; }; - 440A52575362065AC7D7277BC268D6E6 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86414347BF96F3CB7BBEE331C50AE90 /* ImageFormat.swift */; }; - 45B5AB484F2602A280ADA0A58F37DC44 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E049D95E456C13016DBD029DF097E38B /* DispatchQueue+Extensions.swift */; }; - 45F6BA1117D64D98B32E0C77670EF906 /* RxCocoaRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = B7EA47329CE7C48C537F13F781A9FAAB /* RxCocoaRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 47D3FBF90386DABCAB70AA2CA176C8EB /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7477F9282D2B4E4714DD0ADEEAC8A14C /* ControlEvent+Driver.swift */; }; - 481AEC9854D434ABFCBDA297619AB35F /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A002EFCC8C0346E39E3DB06B1725881C /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4831619FAA4A43853E9C48F30BDDED66 /* Observable+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BF9BDC107FFB51F0879071F69E589A6 /* Observable+Concurrency.swift */; }; - 488B94782314042614F1FB7620407FCC /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86C98B190BBB18095371820610FFBA9 /* AuthenticationChallengeResponsable.swift */; }; - 495D9476F1A771F92F04EB5B3D41A38A /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF8BDA55CB353142EEB66AD26161D10 /* VirtualTimeScheduler.swift */; }; - 4B20D5B43F5C7A0643124D1C40FB5EE8 /* ServerTrustEvaluation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C4D9B07775F92146D1E794C6D3572B /* ServerTrustEvaluation.swift */; }; - 4B9A3ACA475440CCA081FD2829B1B2E4 /* ObservableConvertibleType+Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0A868C9971CDD7B0B6C688E3643774 /* ObservableConvertibleType+Infallible.swift */; }; - 4BB57F93FFEE136168CE36C6FE8FD36A /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBF80ED92B3DEF5D9EE1A157A9E17442 /* Merge.swift */; }; + 335964ACF4856C6B63F2B31C4FE80C0D /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F9DB5DEEFE0943EE6183585AD693D22 /* CompactMap.swift */; }; + 33A7D0F2D03004CE256A75E03DF33C70 /* RetryPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E856C87271A41592E12866CE3C9A668 /* RetryPolicy.swift */; }; + 33F9D0BE9DCCCD1D5CD5E031DA5658AA /* Infallible+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF143D5E04FC312AF48745F2677C319 /* Infallible+Create.swift */; }; + 34105401692F3D13E36B351C7DC642F8 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38AC16752A18BFD36B7F4F543811879B /* ObservableConvertibleType.swift */; }; + 34CBBF97D5515146BBA198F412D71863 /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A399BE3081439D0BFC62B91BF9FC4F /* RetryWhen.swift */; }; + 35ED77A85463DDBF1675121107B5CFF6 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19DF06221A11CCCC94FF2CFB37647CDD /* Observable.swift */; }; + 363FBBAD311FC8F84AF4559B3EC7E675 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DA8D267F3F3C52824DB85F2A4558754 /* FormatIndicatedCacheSerializer.swift */; }; + 371CD58570B89DE6A3090CC6CE16AEE7 /* UIControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944092E0A468F6032639BB3DEFC353BD /* UIControl+Rx.swift */; }; + 377229136C0061FE2FABE71862C2070F /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF58036EDA6186C6EC1D8BC6D74DB5AC /* ItemEvents.swift */; }; + 3779F674B0AEC1D521014BCE5F6F3848 /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433B692C89197DA2819292E7CB2E4ACD /* NSTextAttachment+Kingfisher.swift */; }; + 3953280F8C27DD40045ECE5587F04113 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B81CC2EC16DFF3718AF037BFE08AF4F7 /* AnonymousObserver.swift */; }; + 3A379670D0CFBC0FCC9D0F66E944D074 /* RxTextStorageDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA53E0135F75F3243B0F36720469A22 /* RxTextStorageDelegateProxy.swift */; }; + 3AD67A2DC04944CE5AE9B9BD8721542E /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED61B9E9979F042340DD70C4160F7A62 /* ObservableType.swift */; }; + 3B192E4F4FD9236B7377A1E736B252F5 /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E4B80AD9F51FD88A2D7B3262518209 /* Bag+Rx.swift */; }; + 3B60C02F6E42FD06B128473E00A94224 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FE6F6768DE4B073C442DFEB4EA7C4D /* ConstraintLayoutSupport.swift */; }; + 3C4059621E23842C19D4EB5D35B41989 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5D8D6E3DFEDC6651C6B2F9C4FA1FBD /* Validation.swift */; }; + 3CD5FAFC746A76D73C3F501734199DFF /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74E4D3E1255D7FA3A2EC241B99432FEF /* Typealiases.swift */; }; + 3DEDFA52B3A196F6D3E1F0937617628A /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED03E92814E6B1D4872D7FE4343DBFF /* ConstraintLayoutGuide+Extensions.swift */; }; + 3EE7A29FCEE9B2A257B977E7137BC44C /* UITabBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7CFF041D4E96A90F3CCF914CB009E40 /* UITabBar+Rx.swift */; }; + 3EFE8454C7301C05A00EC9870F47968B /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F473180FF0C50A1E0367E1B7E8F08373 /* RxTableViewDataSourceType.swift */; }; + 40B0E9A4872CE86561E028853C812D79 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4870B4A362118D2BB176E9219C5BB1 /* Optional.swift */; }; + 419A11A8F7797E02FA5AAC6D8B4B3C2F /* UIStepper+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEF374C7E373EFFF865471106A1FCEC /* UIStepper+Rx.swift */; }; + 4251CDB971A8B94270E34381974BC9F8 /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = EB9D81BE5A997A78B7964B8E92CE0B93 /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 426C76C68C9FA3582F26BBB9E96316E4 /* _RX.m in Sources */ = {isa = PBXBuildFile; fileRef = D4656B8E22754A0978FDFCBB4C67A0B4 /* _RX.m */; }; + 43863B6D6A0E47B6648BB7B469736EDD /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9007FC5024FD1C48B575F77C8E3B1865 /* LayoutConstraint.swift */; }; + 43E32A0D5CFF0E59D7A2182666D07FCF /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8A5CEB9207F34477DCBCE05CA0329FE /* SynchronizedOnType.swift */; }; + 440A52575362065AC7D7277BC268D6E6 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = A72B315AB5C66F8B157BAB601E734E3E /* ImageFormat.swift */; }; + 45F6BA1117D64D98B32E0C77670EF906 /* RxCocoaRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 9044CC20197AD853A260B3EA7AA3E5B5 /* RxCocoaRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 46A64A43AFA057B6B63C8F0C12F509B4 /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91D56807DC7DF84CD3BB6C0208B64E31 /* Combine.swift */; }; + 47BBB96A017E25A9A46FB25B67005A0A /* Infallible+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8423330216C0F1793ABF4D8864F9C3E1 /* Infallible+Zip+arity.swift */; }; + 47D3FBF90386DABCAB70AA2CA176C8EB /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0A930E95F275B6B5E02AE3F3FF030D /* ControlEvent+Driver.swift */; }; + 484F54DC8118EEE2B1A4C75255E7F8B7 /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = B340DB018799D7AFF781F5CEADCC06F6 /* Take.swift */; }; + 488B94782314042614F1FB7620407FCC /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F5ED8C35455EBE258F138A1802D306 /* AuthenticationChallengeResponsable.swift */; }; + 48E7D5060B8D84903A3B3ED21E4B5AB8 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB14F660CC08F53BE651CF4ECBEF658 /* InvocableScheduledItem.swift */; }; + 4955DFA99D7133906B964B9EE450AF0B /* Infallible+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D87C46D3D423E94BC72155D7A5B5A2D /* Infallible+Operators.swift */; }; 4BEFD05346081CE7797BBA2F6C9DC363 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52554E1C9731D5352FDE9E63F8C5466B /* Accelerate.framework */; }; - 4BFD24472E22B70B71809D3B63DCFDCC /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE28AA56B38DACFBC04F7C8F4EA5984 /* Optional.swift */; }; - 4CA13A0527BC57DE2C54A0F3B5ED8652 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A501DBEFDB319841EFCB339196BD2087 /* LayoutConstraintItem.swift */; }; - 4D2795A04C8D7F78E90CE57F8E46D2DE /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CFD4EB1A0879E8DE5C3EE9C693DAA55 /* MainScheduler.swift */; }; - 4DA118246E671CAB8B8FB2328BB13935 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = F938BFD201DD51B234CDAF2A7BE97279 /* ImageTransition.swift */; }; - 4E4FA63E47752799E2D6C2FD52174D25 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C59DF271C27008DD3524AB8E849C53F /* ResponseSerialization.swift */; }; - 4F315C18FC854325DD5D062DD7A363D5 /* ObservableConvertibleType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E162D330CF2CEF9DF0AF20E78638F8 /* ObservableConvertibleType+SharedSequence.swift */; }; - 501191C24EA7EF2F675F90E12EC61B0E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 51A4A1046676D304410544EB56732A49 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F3AB7D268A9352EE6910E3C8DCC29D /* Constraint.swift */; }; - 51F6DE8F86098D052F18DB94A0B591DF /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A91950D5DC29F11BD39F3AD4EE89E6B /* NopDisposable.swift */; }; - 5230B70A7B448918B83D3B983533D29A /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE4579792A54E5559A9DAEDD992456D /* KVORepresentable+CoreGraphics.swift */; }; - 52BC0E84656F7A31868BE9E1E826B861 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5663CC614EDF46B43CD113FE47D9B9AD /* HTTPMethod.swift */; }; - 541417E3C2DE409F8EB4EEB0DA9E94AE /* PrimitiveSequence+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE032E5A6B45556B1CE4035AB8300BC7 /* PrimitiveSequence+Concurrency.swift */; }; - 5435E924E7CE7B05B7F650C078A12F5B /* UITabBarController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 665B7D600A93931F9FC0056B47D815E1 /* UITabBarController+Rx.swift */; }; - 543824E1170EF49570C40DAE54604F21 /* _RXDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CA9A671658EDC6000F285EBAF057106 /* _RXDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5555A48DF687EEBE895890FD5FA283C9 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12BD7A4C979860972136F7BA019630B /* RetryStrategy.swift */; }; - 55713DE36F28B0D078ADAD60D5EE7FF4 /* ObservableConvertibleType+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D8A73A39785C42B97E613D0CFA6BDD0 /* ObservableConvertibleType+Driver.swift */; }; - 557AE7547352CEA86AEE5518CC1A503E /* RxCocoa-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 01122E4C4E6E936C13650AB5930C1599 /* RxCocoa-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5649197507A7DAB892FD0A7B5A9D6D4F /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3838BCB07EFD1D203AA7CCD91DE9C2E5 /* ImageCache.swift */; }; + 4C9977C27EEB2F70FC2960A8F25F20E1 /* AsyncSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DCE52506087CF4CC559E58DD403801 /* AsyncSubject.swift */; }; + 4CA13A0527BC57DE2C54A0F3B5ED8652 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816B43767B379812F884C578D631E88 /* LayoutConstraintItem.swift */; }; + 4DA118246E671CAB8B8FB2328BB13935 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 328871EC5F47DC34D9B0224D74DA7E30 /* ImageTransition.swift */; }; + 4DD16CA967818B2FEB373D8CA1F7EBBE /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 661995B1014D4EFB67154575503A2A88 /* Event.swift */; }; + 4F315C18FC854325DD5D062DD7A363D5 /* ObservableConvertibleType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD98DA4FED7C52AA2D77259CBF98E81D /* ObservableConvertibleType+SharedSequence.swift */; }; + 50009D0F858892024A16085E8B346B17 /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F00C8521C329190BE365BA5A431237 /* CombineLatest+arity.swift */; }; + 50462A7E9A48D23F5CFE2064EE003681 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C925288023BDC18E74D66D6E1BBFDAF3 /* Zip+arity.swift */; }; + 50472850F81811172F8C41BFAB77D6DC /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D907EC9C19B69B73A37BF27C30B38F05 /* MainScheduler.swift */; }; + 5050D694CF073366EC942B2D517ED517 /* ShareReplayScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BE01FA5A76FD95281BCF21AB650B8E0 /* ShareReplayScope.swift */; }; + 51A4A1046676D304410544EB56732A49 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8882B3B9AE691A21883DDA845199981A /* Constraint.swift */; }; + 5230B70A7B448918B83D3B983533D29A /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0765B4EEB54FAC58B8234A058FA33E51 /* KVORepresentable+CoreGraphics.swift */; }; + 52E98DC0EC5189A4A8979FCAA0C329AB /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF13E01C557A0B7AA31D6B77F42EB22B /* Window.swift */; }; + 5435E924E7CE7B05B7F650C078A12F5B /* UITabBarController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCE3665D6C88438C0AC4433967269C3F /* UITabBarController+Rx.swift */; }; + 543824E1170EF49570C40DAE54604F21 /* _RXDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D23B36396D7AB021DB60C837EB036FE1 /* _RXDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 54F25F05FDC2C9ED679D2F07D5918CA6 /* Infallible+CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FBFC0CBBF3385F74EA898D58C65B4B3 /* Infallible+CombineLatest+arity.swift */; }; + 5555A48DF687EEBE895890FD5FA283C9 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70EB884AE386D32AAF63E0A0FAA7AC5C /* RetryStrategy.swift */; }; + 55713DE36F28B0D078ADAD60D5EE7FF4 /* ObservableConvertibleType+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF69ED1FA9497A9E9861EBDB2ABF203 /* ObservableConvertibleType+Driver.swift */; }; + 557AE7547352CEA86AEE5518CC1A503E /* RxCocoa-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E3E9BDD5EBA375AF48858939A1673F76 /* RxCocoa-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 55AABB1FB38F61A3369ACC555FF3046D /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D7B5A7AD167A4C224BA967C65613F9E /* Alamofire-dummy.m */; }; + 5649197507A7DAB892FD0A7B5A9D6D4F /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D586379F42484F03DE243BA460D48E9F /* ImageCache.swift */; }; 566E1BD667CCAEF237B605D80A10C5E3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 567036FB455293CCC0BFC215CA915B4A /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67131024C7367F11A6414DE7CA82CF0 /* CacheSerializer.swift */; }; - 56773BCCC6027789CC30E65B945FE7D5 /* AsSingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7555D68AECBE9EC9B6D36A0AD9B6038 /* AsSingle.swift */; }; - 567E2B1BAE575E6556A2E57191BA2DA7 /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B1049D115F74C6C48B9BF7B975E5F3 /* DelegateProxyType.swift */; }; - 58BC77C4865C8C2A99EC1D93BF2B3E55 /* RetryPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C000E2E307CBE72910B6A0E5625A6AC /* RetryPolicy.swift */; }; - 58FF69B2022DF80F0CFE59CB5DC1169C /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = A926E0571C383DCF3CA9610A7DD2A439 /* MultipartUpload.swift */; }; - 598CCA9A622AB8C28137F88F2F81946A /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A52FCBFBDBFDA727757BADAC2FE4D7D /* Maybe.swift */; }; - 59C20AD81D8A3D0D24C365BE682D2044 /* BehaviorRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEF7A990982D57F3CF18103B53C623BA /* BehaviorRelay.swift */; }; - 5A225B75EBBF38DEA451267FA35A4A4B /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9F047AFE79DA1C753989691948402E8 /* InfiniteSequence.swift */; }; - 5A39F3F258372FA025F08ECAFFFCF71D /* NSTextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4F78CF439D58FD5F821B8196123351 /* NSTextField+Rx.swift */; }; - 5A3DE5038C0E8C2BAFC3316589D0F918 /* NotificationCenter+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3212B74DA6E8E30143526455790A11A7 /* NotificationCenter+Rx.swift */; }; - 5AAE664159A7CE1263984D03D674CC57 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBABFFF76C76A9D5D8DADB1EDE58F23E /* CompositeDisposable.swift */; }; - 5CB24643A7A71F1C5B71662C275DD1B1 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002820526DCF691DEE139BFF1455D570 /* Disposable.swift */; }; - 5CFA5A0140CC19B2DAC917D2B7FE50F1 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17FE795BFDF8716FCE863719F88C915 /* ParameterEncoding.swift */; }; - 5D7B4063F1AC165B647C2ACFA8781BAF /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABE22BF2DF69287E362BE1D2C88D65C /* CallbackQueue.swift */; }; - 5E8BA529DFB4529006967624044FEC1C /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5F8993766833E3FBAE79C7D917DA71 /* ConstraintViewDSL.swift */; }; - 5F4B289996241A41EDFCA1A3C849045A /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2E3307EAC0D40402CF75CA99E59080 /* String+MD5.swift */; }; - 5F9AECE565196E2EB2CEF43694CDAC08 /* Completable+AndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0410C906661C5ECBB5A94E5BEDBA52 /* Completable+AndThen.swift */; }; - 604CEEDB74A6AD3269EC939A3FEF5065 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0752E2033E127DDECCBE3EBF5AED6438 /* VirtualTimeConverterType.swift */; }; - 608DC0C8110DDFF5D8E5A43BB48A6A86 /* UISlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 739DC6301DF1F2FA1A37C23C38EAACB3 /* UISlider+Rx.swift */; }; - 610044A23AE8E11EBFDADF534B1521A1 /* URLSessionConfiguration+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8374B2F9307524AA49B8C180B751A0 /* URLSessionConfiguration+Alamofire.swift */; }; - 61158247CA68DF1C2AA169178DFD43AB /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFEDC3D329D65E48B3BC7FCA14CDED97 /* EventMonitor.swift */; }; - 614CA46720B2B8D58EBBD2CF26E2FEAB /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE864F413CB764E2D3840B6A04F5C8BB /* ImagePrefetcher.swift */; }; - 61EB40AB5F1BB5E6FDC8C5CDE06C3DE9 /* RxPickerViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB2F5D8F493BEAFE9EFA5E3E5EA0027 /* RxPickerViewDataSourceType.swift */; }; - 62312BD25740FFB6F894687787F19895 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6EDE4C2E94C7299D615D4615B12B896 /* InvocableScheduledItem.swift */; }; - 62F299B4704A7C95FB5866C6CDE2E2FD /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E52CD081388CCB8E6485B2504337448 /* ConstraintOffsetTarget.swift */; }; - 62F7E0692A2C56BA6C97B3B1673865C0 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96399A3F19C97048BD73AC6C016447AA /* Debug.swift */; }; - 6468384FBFE289485D6B3C17A072948C /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93865933C5B3EEC7A6744968D58B8B1 /* Window.swift */; }; - 65012CCC998A71F7171507D3D9926743 /* Infallible+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852B3F5F7CAC90F024AD13ABCCFB986C /* Infallible+Concurrency.swift */; }; - 650D5723A58F1250568D3E47E7423564 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C240573DDD75AB5F81D423C5E2EFA0A /* ObservableType.swift */; }; - 654D9C29A846E7ED4DD5BF0BFC8D64B8 /* UISwitch+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA4834DA4941D7863F0CBE2128F1621 /* UISwitch+Rx.swift */; }; - 65D3F59FCA86FA9AE473EA080B95FFDA /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E7B9C74BBBFA3CF7A52FD8918555C8E /* ObserverType.swift */; }; - 660E73ECB1E50185B9D21BAA127DC3A0 /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44404E8C9D38627A655B2CEC007AAA80 /* UIRefreshControl+Rx.swift */; }; - 67302797A1DCF1062DD228DD59D58CAB /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53223FF13560EBEA779AD3723F9BBA00 /* ImageDataProvider.swift */; }; - 67C3CC2453D19199BC14F0E8BD183F3A /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D07AA6A24B29A203133E60FC50D7BB /* Completable.swift */; }; - 6809F42AF2E7EF87D708DB9257980AF2 /* RequestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2466F41844E51F2D29DFCDEE4E4AD3C5 /* RequestInterceptor.swift */; }; - 6923E83262B245A9B8FF71B89ECC8155 /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3311B6D4D057AD143CB7E74A0B1E1E5 /* RefCountDisposable.swift */; }; - 6927E0A61FCF762B43C75325110C3D77 /* Infallible+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40C6BA6CDC6B229E81A833B34FC0605 /* Infallible+Bind.swift */; }; - 694F385519AE5B93B76AA6B631A3FE6D /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF0A54173D4CF241D535F100AB21A1C /* DistinctUntilChanged.swift */; }; - 69657DEC11BB7E4F9F5B6DE8E1148B3E /* _RXObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C44F364482EB4F6905DAF107341E243 /* _RXObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6BBFC14EA40F3BC8986B26D5B75573C3 /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB1D196B882ED38EFB67CDB8058A6DA /* RecursiveLock.swift */; }; - 6BDA2BC21E394076C2E58E9269F4AABD /* SchedulerType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B025DF756635BB8334DED4384ABB6D8B /* SchedulerType+SharedSequence.swift */; }; - 6C45AF088F0853A8BAAB07D760346418 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E3B733BCCBB62B59FD06B8C437FF95 /* Delay.swift */; }; - 6CD459A51DEC60BFE1BEEEA5B7AE9A1F /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49867C97EAB05F3879541A4853891A4B /* Never.swift */; }; - 6D0F7BA524BBC46B5AA273E74D1F1350 /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3B739A608F0DDAD0F2DE37083707A /* HistoricalScheduler.swift */; }; - 6DB19BEE9C42CBE8101A114524B38CE7 /* NSView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 492C5CAD0304480DBF304ACC718D8A62 /* NSView+Rx.swift */; }; - 6DDAA0D48EB19B7474873856BEF70E60 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB3D593961945959F1A44BE5C05C5A58 /* Disposables.swift */; }; - 6DFB5C921332D5E14BF251A5ADA46473 /* RxNavigationControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3612035A1538C3A1A8AF7D1DBB4D0184 /* RxNavigationControllerDelegateProxy.swift */; }; - 6F803B4767FE50C12E3F0402DC0A3BE5 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A64114D53C625813C2D26E4677BCF7 /* PriorityQueue.swift */; }; - 6FA433B7C87F256B163EF3D148C91836 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A2C3C1D0E6D7A4FE37D9A983BD28417 /* NSButton+Kingfisher.swift */; }; - 6FB7A5C90343ED969159858AEA885639 /* AsyncSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F34C3DFEA45CA618A7BD11A7ED48D9 /* AsyncSubject.swift */; }; - 6FE1C0099BB8E039449105BC0820A834 /* Binder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED812CC3A0ED3E6BCCFCA3EA27368A3 /* Binder.swift */; }; - 7081BAD4BC8B8755EBECEF3D62807B17 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D8BAA943C277F25473B01F1832BA866 /* Placeholder.swift */; }; - 7154F93C879B0E4CB11874AC95F6FF3E /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2089866320AF70B3661336D75B57BC0 /* Source.swift */; }; - 72EE3F69E6154EF5C5524DE4F4EE0B5C /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFB1D3357C9D51B861167D08229FD122 /* Queue.swift */; }; - 72FCE0D3F5EA7EB908C108DFD468B267 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782CA0710D423EBD97794817C8359075 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; }; - 731CF1B7C9778F1758FB8E444C847E69 /* PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA03DC4A3F895B6A381043F1C17753B7 /* PrimitiveSequence.swift */; }; - 739248AE796F5C0C2EE3B203A588F053 /* Enumerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B99BA47A5EBF3E66630684A8F212DD /* Enumerated.swift */; }; - 740659793E5D906F5A508155ED8895DF /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1573A89C0E571C1C7A874625F7E9 /* ImageDrawing.swift */; }; - 74A20606A8ABFD4E9EA4072EAE731A0D /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8EBCDD6EB54DCDDCA65563CF324CDA /* BooleanDisposable.swift */; }; - 7580FAAB1BDA52F5A969E5571D1A5973 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04EA0D88E6C540AA57372D94CA178C71 /* ConstraintAttributes.swift */; }; - 76016889CAF09F56BDCBAF164A7BD69E /* Protector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF7AA432C0E4C80D47EEF000590D957 /* Protector.swift */; }; - 768A33DCEB41CBC5C7ECF5F0220B1A97 /* SharedSequence+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F04911873952BD6300007242C0F1EF4 /* SharedSequence+Concurrency.swift */; }; - 76DBB416ED9F7C7E50A8D77BCF6A9E39 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B9D54BE7D34A5488B42DC19D10A403 /* Image.swift */; }; - 76F9B7217220321AF3343F7F2C5781D4 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5CBA1DB958A279FE0C629D26B7185 /* KFImageOptions.swift */; }; - 7764AA5F6BBFC6ECE43959923DD007D3 /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965B3A6BE185B4673A5F58FF419A00AE /* ConstraintDirectionalInsetTarget.swift */; }; - 782082D9F5529E63F249E8811BA6FD10 /* RxPickerViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54C1F19A76D740FCD01B0FFE8B8B52D /* RxPickerViewDataSourceProxy.swift */; }; - 78DE8DE64F023B0ACE1099C30C79CE59 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877A2FD7746750C7EEA0776F7100ED51 /* MemoryStorage.swift */; }; - 7BA5D9B38DAEDD6A5166ECF2A498D194 /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 741F949E7A59F3DDA438594A62CF0B5B /* RxCollectionViewDataSourceType.swift */; }; - 7C9C0D2AB5BB6670928CC95B4DA46814 /* RxSearchBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E90FF704D8B7C423ED6AF884FEC88E6 /* RxSearchBarDelegateProxy.swift */; }; - 7C9CEB951E1388233F0617DD97837946 /* TakeWithPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 410747E8F9D1164844C9D33F86671DD5 /* TakeWithPredicate.swift */; }; - 7E28AE7A43EB26775F385138B147CDC9 /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CA874964DCD7DA61F687EC29CF0182D /* Throttle.swift */; }; - 7FFF6C6E9ECB38992B4BE97E686DF2E0 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF6BA90952A9B09B459D0A010FFF4CB /* SynchronizedOnType.swift */; }; - 81148E8E0935476F92B10881A023D0DC /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84983A505E8934C5AD701FE2D31FB770 /* ControlTarget.swift */; }; - 817E128FA1E910EC38D6B727766A2AFD /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07F26138B76C48A68119CBAD2AC7F749 /* SubscribeOn.swift */; }; - 81B51CA6E417CF7D14C7BB733506C7DF /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF507A128B1048F9A9506E5EF8DD94E5 /* Zip+Collection.swift */; }; - 822B70E128AA35F7DED0473AD11C89E4 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1D5E99178DC6039AA64BA30DEC3D54 /* AFError.swift */; }; - 825062025906CE93C5D124E1FD9A811E /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AD9E34263C1FD6F837368810D9B6B6 /* ConstraintMakerExtendable.swift */; }; - 829B41365DFC653EE4B09C3ABAAF2EC9 /* Date+Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9F98E08158E504E673C919AF746700 /* Date+Dispatch.swift */; }; - 8449EB1DFD43E222D687D5A8D2088D2D /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1C288444CD932974293E8EF6BDDACD6 /* ConstraintLayoutGuideDSL.swift */; }; - 84AEE29F4E7DDA962C49D6FAC6044EBC /* RxCocoaObjCRuntimeError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92302766ED87489DC4556A56CD10A5B9 /* RxCocoaObjCRuntimeError+Extensions.swift */; }; - 87D4D0B024FB3E0DB6AA42AE272922A1 /* ShareReplayScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 509C092A271A374B7335A91F29349033 /* ShareReplayScope.swift */; }; - 89A2957DD94EE24A18A5CE0D99DA9B8C /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C954C71FA7E915CF61F045E29B4866 /* SkipWhile.swift */; }; - 8A8AD24A8CE75FBE807EB5A9FC11E62A /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 216434676B68D96B04E6DDDA0D1D5A83 /* Bag.swift */; }; - 8A9103B004B8EBE5AB836433B9662E16 /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49961095D3E6AA7114010352F9D8D866 /* ToArray.swift */; }; - 8AEE5B74A5BAC274D6589F229D867768 /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47AF1800496AAD9455F26513BBA496B /* UITableView+Rx.swift */; }; - 8BF59E920DC561A9F071F6D2860A9B99 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 8C6546C1EF4F153DF3795CC6FE189E5B /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49309CED1FF1518FC6DA6FB30AED2314 /* ConstraintInsets.swift */; }; - 8CDD7DDE4746E8DB08FD5347452EAB88 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08DC1AE8E928801CE8A4CF42E28E6F03 /* Validation.swift */; }; - 8D8BA9FB2C1FDE670C3B999DB1F42A67 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - 8E788A72E56879B3ED1A70D386AB95F4 /* OperationQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E69EBCE3389722923E118788F3FF7A /* OperationQueue+Alamofire.swift */; }; - 8EAF6BAB0FAC544040F4D9525886B4F0 /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45144499497DB482329E52115E128E3 /* InvocableType.swift */; }; - 8ED2643A0938F45F07DC3FFDAB9E87BF /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C3BE0AFF952A3AAA8373E044BBADAE7 /* StartWith.swift */; }; - 8F68369EEC708827854493097B84E7BE /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFBE121C04BB773EBAADCF4FEF232E49 /* Reduce.swift */; }; - 8FD9CD608C4EAAFDE6AC7B8B9EF0FF5E /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DA099226DE912F6804ED601DCE54DA7 /* ConstraintDescription.swift */; }; - 90585B3B5526DB8ECBD1AB8EF2C4D5A2 /* UISegmentedControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 601BAA3A79806B156A41056A73088AE8 /* UISegmentedControl+Rx.swift */; }; - 90A13F35A0D225B2FC6A5FE32F656CCD /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B8B6B28C084865856AD6D49550E430 /* Concat.swift */; }; - 90FD5AE525E138A473723FD79AF73273 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EE251BF5CC611B7D07507D0B79D416 /* ConstraintDSL.swift */; }; - 93209671B01B76711F6E2022CADBAC9A /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F2A6298A6E44AC15ECABBDBC9D11D79F /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 944AF90199777093145684047F9B6EF0 /* ReplayRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA58654B4430250D86C1BCBD63DE43A8 /* ReplayRelay.swift */; }; - 95401E770FE8BA7DFC627DD4E0DF9332 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 687E155797AF351961D6BEEF1A2766F2 /* Cancelable.swift */; }; - 956D43D9E3DB5A3A4AE69E9F412D1112 /* RxSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 55CB4877246F52FF87A8C244384E4E42 /* RxSwift-dummy.m */; }; - 961B5042F0BFBD2C5FCDCCF40E2EA7CD /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F080CD3AE644C4BB12664E9BE553B42 /* UIButton+Rx.swift */; }; - 968B4874A9F12D67C8B901136C9C8157 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 987EC0DD92EE020800E3E03D74818D35 /* SnapKit-dummy.m */; }; - 96F9E4762C05BF7B009FA52FC18C18C5 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F266CB0FCD269EE6A8449BC282D0187D /* NSObject+Rx+RawRepresentable.swift */; }; - 971CE56718BB8172DB2971C46C43D4A8 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1486B81E13CE29D01C4B7BB2C76A9BF8 /* SessionDelegate.swift */; }; - 98E063B537BCA078F9EFF48CD9189E11 /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFD28848184CFC8F2669F9C7B6F3ECA9 /* Skip.swift */; }; - 9A151985A3D24023E8B2996BF3EBA2BB /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A895508CA44EE9BFFB139EBD5DCA92E /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9ADE1DD7C6AD8B57FD158350A66EF8D0 /* SharedSequence+Operators+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB6515374F67729417916635301BE41 /* SharedSequence+Operators+arity.swift */; }; - 9B4D9E5E699A755F9013731FB60B7307 /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB73CA1C3F8B703DE2C884659A31C2D7 /* Bag+Rx.swift */; }; - 9BB83D2CE954C1BCC44121855A24C138 /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 267A04DBC3322B5D3D8402EC66199CD1 /* Catch.swift */; }; - 9BCBD89FB47D8651F43CC3038F478D08 /* PrimitiveSequence+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 004354BDA07A0416EB9F2950BD343B6A /* PrimitiveSequence+Zip+arity.swift */; }; - 9CABA1A19C31DE6C3584C3401C92AF51 /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8830E829C546878488B268DCE7DDB4D /* DispatchQueue+Alamofire.swift */; }; - 9D7E94CA1A80F71F0F36935EBD962BA6 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C954F6DF8FF162D446F5C12EB53E01AA /* RedirectHandler.swift */; }; - 9E3B20F28C8C31E0394B6D493B31CB43 /* RxRelay-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 517A605109B9601443F76406285A2E74 /* RxRelay-dummy.m */; }; - 9E8BA4FB802EDCD492DAF618CA7BFCE8 /* SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFAF4546BEC4051969C1020917C3FB33 /* SharedSequence.swift */; }; - 9F370B3928A333AD7E41680A29B1F051 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090F56B03C1EA838E662190E3D064532 /* RxCollectionViewReactiveArrayDataSource.swift */; }; - 9FC98D1BF3A981BB349E26D712298FA1 /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1500F0CCD24A6A49C7EB584E63BCF842 /* UIButton+Kingfisher.swift */; }; - 9FE18707EB6166A53076FE3CC036593C /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149A0E263DF818421EFE73AA49E3FEC2 /* ExtensionHelpers.swift */; }; - A0208B623442A26CB9157F193CBB4A7F /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 888140F08408B7B3271F6544822DD56D /* Platform.Linux.swift */; }; - A08D8736FE6C8059C87375D944E21CCE /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5668586C4F1FBED7320E57E20FEF2209 /* Alamofire-dummy.m */; }; - A0F754C88A64972A40A9008B0AD52109 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBA68C43E44294E2A8A0ED20C0BDF200 /* ConstraintDirectionalInsets.swift */; }; - A20321979D272B922CD60B531BD05F7F /* UIPickerView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E134AA052C1FF8D939096469FC59AE78 /* UIPickerView+Rx.swift */; }; - A214A653E430C9079AA7B1090169262D /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581ECB7EB510001F013CEE44FAD7CB93 /* UICollectionView+Rx.swift */; }; - A3BF27E4FF783118AF78BEA42B84F276 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2395D2D816592B47A30CF5C10787ECC7 /* Error.swift */; }; - A4467357581E8345DD348683CC4111AF /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 85293B8B83659B656B1ABF20EF57E4F1 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A4ABC2AEBD37D5B207258ECEEF37262B /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE62662A2D55BF8E43A8AE661CC6EDE4 /* Just.swift */; }; - A53D3AF15CE8D348306EF11619C5D166 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88C9CBE328FA6D027532F2845F170D6F /* ConstraintMakerEditable.swift */; }; - A6A82B7640E18944A6FFC4BE7348E7F3 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1797BF7FAA53FCA78CC60F983304176D /* SizeExtensions.swift */; }; - A71A6D16F682FE7F5B81B16462F6C016 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673EDC2A7995B2775EF3A3D7B1F1D50C /* ImageModifier.swift */; }; - A7DB13E49A7C583C9162D51AF461A42B /* Debounce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F565743D0E0A3EFD781A8F8A9B51CD /* Debounce.swift */; }; - A93FC5BCB5B02182D27377A3724A60B1 /* RxSearchControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD31C27FDA4BDB820AE3811BBF0F3289 /* RxSearchControllerDelegateProxy.swift */; }; - A9AD1FE8379356D400C79DCCFE944E03 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8E0DF3B5987F629AE2237546036058 /* KingfisherOptionsInfo.swift */; }; - AAA7A11591D6E4B06124708291C37698 /* RxTabBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2D10146397CCBBA9C236D37BB87BAB9 /* RxTabBarDelegateProxy.swift */; }; - AAACC4639E0E182F756173EBEA4494F0 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90B9C4250086CFB7483AAD87B1C4989 /* GIFAnimatedImage.swift */; }; - AAE9191316FB42B81F0D4A976E9ECB34 /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5FAACB2F1EFDF21330936154BF6DFA /* Delegate.swift */; }; - AB88D7A71BA82D3BAF097C992BFB221B /* UISearchController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F5D93D2A26CF9078B252BF264AABC60 /* UISearchController+Rx.swift */; }; - ACA3DBC73A19F3CDF9C4FAB09988D0E6 /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF09656ED4D86E85CD578AF13D73744 /* RxScrollViewDelegateProxy.swift */; }; - ADC265B95181064F5E1C8FA0F1978B0F /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6203B0A1D8270B6CE3B525E6F7ECE3 /* ScheduledItem.swift */; }; - AF82ABAD5431E3BF68E7F7EEE6703790 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = E618A494A482B3DEC86B81C1AD1D365F /* Map.swift */; }; - B00B8088EB50EA3F0F875993C675F421 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460862A1D5FAE753536EE93A4D4A90E /* UITextField+Rx.swift */; }; - B1ACEE046056D3B9457C03BF28B1AA4A /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390343B0F0437A9ED750B8657080C49C /* Utils.swift */; }; - B1B2DF0164DB3B361FAD1518990042F4 /* Result+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7705F997A86550CBD50E3A0EF7D891 /* Result+Alamofire.swift */; }; - B3167FEDC691D1DDF267F855CFF33636 /* DelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923A02BEB70212483E3F31C6FA05C4E3 /* DelegateProxy.swift */; }; - B322C801FA13AE9AA91938FB19632FE5 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 690CBA6B46BCDC28457F1D7848E98E4F /* ImageDownloader.swift */; }; - B389BAA9DDADE0C535CD9EB2EE2406E7 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D441519852483871764E8CCA75F4A95 /* KF.swift */; }; - B39E291F03ACB2AB079AE475BB6DADC1 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B96619905B442A12C1F2C65DCC72F9D /* Sequence.swift */; }; - B3C7C0BD02306392F5842FD94F4E0963 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A57FC897450D14CF6F70161A3AB95BC /* Session.swift */; }; - B3F14F1B196B5858BD951366FA89FA6D /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 610390D4044731D1CFB686687A81F305 /* RxWKNavigationDelegateProxy.swift */; }; - B48F081B2FF54539CC191A120592F17E /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = A102DCE673A0A9A983D6DE36965791A1 /* Range.swift */; }; - B543FD108C1C6AF6129CB4991553218B /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A8A341317A3DFABDA1E41E20BEF985 /* ConstraintConfig.swift */; }; - B59095D5EF330419B3ADFBAD7EBC2B1F /* NSButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03956BA3890ABF298FBA26FBF08B4E67 /* NSButton+Rx.swift */; }; - B5ACECCDD52AF69EBA2E11666BBAEB42 /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A21AC031138F500D867B1A15877ED9C /* RxCollectionViewDataSourceProxy.swift */; }; - B6AF48158CE1D31ACA8A57437E3EFD1F /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 872D7EFA572ECEE8EF993C27196E16DD /* CFNetwork.framework */; }; - B6AFF30D6B83658083BB0EB7F85B31CA /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E679291E767C8D0045D70F6E1FE6558 /* Bag.swift */; }; - B6CD84CFA3C7E07113D00386C040154B /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53AD78AE798D875C99318D5D0912F543 /* Buffer.swift */; }; - B7DAC534D4F0A31CD95FF6613317D4E8 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC8262350C75698D71BEC19D863D711 /* AVAssetImageDataProvider.swift */; }; - B991B7EFAB91CF6280270C2E939EEDBF /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90FD593F6533CBAE30159E9909FB238D /* ConnectableObservableType.swift */; }; - BA5658B6C27A81FA4665E507A1ED88DA /* Driver+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98ED6A1FB741868720BC377FA293B9A0 /* Driver+Subscription.swift */; }; - BA6758186158F65AE8730D5E20374A6A /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3CBFB2E2A7835AFFD9AF09F49AB44DB /* RequestModifier.swift */; }; - BAD3834746DAB3C038417D16101B29A2 /* NSControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E16592D918033D6F1FCACB9C70EBDEC7 /* NSControl+Rx.swift */; }; - BB72FC9215BD907A82AE928782813D6C /* NSObject+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6D4CBB22DC0338D091547BC40AA631 /* NSObject+Rx.swift */; }; - BBD437FE6BFF63452E6B7E08DFAB4DD9 /* UIBarButtonItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC182783F31B0D1DD816939B95155F5D /* UIBarButtonItem+Rx.swift */; }; - BBEB88D4196A5F8621F2D16DF91C251A /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AEF96291CDC473DD230EFDC04E3745A /* GraphicsContext.swift */; }; - BD333CDBCF5D2FD55920336FC271DF33 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF398D151AA3B4AE228DC8266D3719 /* ConstraintItem.swift */; }; - BD37ABCE3F0BD0C29FDEFC3874E5A0F6 /* SwitchIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F6B34177CDA13EEC9692109D9630D5 /* SwitchIfEmpty.swift */; }; - BEBF920FEB959B46A76BAADF22E5CD15 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3166ABA859436ACB43784064BA94408 /* ConstraintInsetTarget.swift */; }; - C09DE156BA8C2313CD4FCA9F2D78066E /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 491B41F720BE34BE7F38E64B20E5F772 /* PriorityQueue.swift */; }; - C12DCA02D36C5C6167F566AFC96A6057 /* _RXObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 824686CA707E4A0205D584D7D80A548C /* _RXObjCRuntime.m */; }; - C1EAEBA09776DA989D99A07A34029DE0 /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFCFD51497C9110708C858EA2C19368C /* Platform.Linux.swift */; }; - C2A71FE4B9A99CB90127EC09B40CEFE7 /* Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFBAFDA9E115C3FA592178ABCB160FA /* Create.swift */; }; - C2D4FEEAF01038DB5C31CA401C105476 /* _RXDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 359E0E617AC6252C020ECD81C27A0569 /* _RXDelegateProxy.m */; }; - C33927F838E5C40F86F8A1AF4E09908B /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF9F7C0C096008AB17EA43C33758716D /* ImageView+Kingfisher.swift */; }; - C36D23C03A0ECE1CF1807CEB233F822D /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1E7581C086DB0A3C8E579FB4664B3 /* SerialDisposable.swift */; }; - C378AC3DF57A41F6F16D01BBD7A1BB02 /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7210D187331A95A56DFC067B911061D8 /* UIActivityIndicatorView+Rx.swift */; }; - C38A6B82ECB3F38D79C0CD50A8F5314F /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6283F9E56EB235587468C6A23E30BFE0 /* RedirectHandler.swift */; }; - C61D3BC32A28A405C934C00039AD2583 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 590ED942605473B4D25BE44D9207DDDE /* ConstraintConstantTarget.swift */; }; - C6A1AF1239CD2F0D4745BAA097E1E63F /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24F87871E996DBDC20A4F578217123E /* RxCollectionViewDelegateProxy.swift */; }; - C784A7AAD94DD830A9EB5ADDEE6DE1BB /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC95CABB41414838A5CA49BCCBA6D914 /* KVORepresentable.swift */; }; - C9B8095CA60D3719A0E3E5B20E7317BA /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BF605F4199BEDA7DC3DCD3BE09331AE /* SessionDelegate.swift */; }; - CA5984DF04522F23CBDC05BD8D26CB46 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = C294FFEA094D34D45BC84CEF61CF1C49 /* Response.swift */; }; - CB194156C900B767B0160AF72EDF354D /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243B068FE5F3750321AB4D1D90CDF047 /* ConstraintMaker.swift */; }; - CB3ACAC0625702DEC5BBB5F9AC0CC737 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB28A30D5E28A968807FF91682435113 /* RxTableViewReactiveArrayDataSource.swift */; }; - CB8E4BF0D710970BE2CB4C87ED1043E4 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D36596C01773C3C3FC96979AD8726C1 /* ConstraintMakerRelatable.swift */; }; - CBEC736105CA647913890C03225F8A02 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE7855AE606E5E11D3FBFEB5F9269BD /* Indicator.swift */; }; - CC3A80A9DCB4EBE43A7E6CF0BFBFAF40 /* DefaultIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837D68EC9B5FF19849A4309C9D50C12F /* DefaultIfEmpty.swift */; }; + 567036FB455293CCC0BFC215CA915B4A /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1156F9304249B4AC44D03B40EB30F69A /* CacheSerializer.swift */; }; + 567E2B1BAE575E6556A2E57191BA2DA7 /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15A5CB1859AE914F9A4883C909C1D04 /* DelegateProxyType.swift */; }; + 5684D133C829112C7ADF363416BE1023 /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0846BC731037DE3BA116292847C91021 /* VirtualTimeScheduler.swift */; }; + 58291D4289D4B0CC40B2C905DA32D991 /* RxSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B9242504B8D42D2180847C1D02DD74 /* RxSwift-dummy.m */; }; + 58E22287DB9EDE093A147780A1F65203 /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C91A18F51E4CC6B9E6968EE21EDCF94 /* WithLatestFrom.swift */; }; + 59E4C80E4BFC34BBDC3843468E7F5C9F /* Debounce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F97DD8D894161C3532CA0B9B171A9FB /* Debounce.swift */; }; + 5A39F3F258372FA025F08ECAFFFCF71D /* NSTextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DFFF2012F5791E774C912AC86DDCE0D /* NSTextField+Rx.swift */; }; + 5A3DE5038C0E8C2BAFC3316589D0F918 /* NotificationCenter+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E3773C87AB71FEFF099FBBC70AB837 /* NotificationCenter+Rx.swift */; }; + 5B958EBBC4FFF8E0E4FC78DB49E09C68 /* PublishRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0027F0EFDE7EF07B89CC7DD7A26BBC04 /* PublishRelay.swift */; }; + 5D7B4063F1AC165B647C2ACFA8781BAF /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AC886A405B78BA6458877730E1591B /* CallbackQueue.swift */; }; + 5E5A0F9120F5C46656492BBD936C1C35 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42663476A9313F46565756E7E95ED5AB /* DispatchQueue+Extensions.swift */; }; + 5E73FEAB8A1545E0C163D1839944F0A1 /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10DBF9FA38BA3CFBEB34E19F6953E864 /* DisposeBase.swift */; }; + 5E8BA529DFB4529006967624044FEC1C /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE5CD5014A09A8B5FEF6D3E30B7B776D /* ConstraintViewDSL.swift */; }; + 5F3F75D02881D26486C189483E69ACA8 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF638C997821B67CFD87ED2784B2BCF1 /* Filter.swift */; }; + 5F4B289996241A41EDFCA1A3C849045A /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF05C45A2F67138ECA96FE19A456DA92 /* String+MD5.swift */; }; + 60283BFFCB1E70EFF8D69CA3012E4D6C /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F4864853C931D994403E262406562F /* SchedulerServices+Emulation.swift */; }; + 608DC0C8110DDFF5D8E5A43BB48A6A86 /* UISlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACCBD4C0C85A487DCD856558486F38E2 /* UISlider+Rx.swift */; }; + 614CA46720B2B8D58EBBD2CF26E2FEAB /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF741934484C2FF24397B93BA6FE6709 /* ImagePrefetcher.swift */; }; + 61EB40AB5F1BB5E6FDC8C5CDE06C3DE9 /* RxPickerViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D6F90B890CCCC1B401070F43B61779C /* RxPickerViewDataSourceType.swift */; }; + 62F299B4704A7C95FB5866C6CDE2E2FD /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C763C3301F4A9D71EA67289A30CCA5C2 /* ConstraintOffsetTarget.swift */; }; + 633A41FA0728734F44C49A443754C45D /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16207E1B4EEA0AF791AE4F11AF03C42A /* CombineLatest+Collection.swift */; }; + 638A599E130C01F966B9CC278E8F03A2 /* DefaultIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41D6582E0936ACC2199801C4FE13E4DD /* DefaultIfEmpty.swift */; }; + 654D9C29A846E7ED4DD5BF0BFC8D64B8 /* UISwitch+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 230C05CE94222C563407E135A09FE52B /* UISwitch+Rx.swift */; }; + 660E73ECB1E50185B9D21BAA127DC3A0 /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C326389654418C163F0542532BC17110 /* UIRefreshControl+Rx.swift */; }; + 6621E9558615DCE7B0D32A0FA29D1591 /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2E6CC487F38F5A6D12B359D6AFB09A6 /* Multicast.swift */; }; + 67302797A1DCF1062DD228DD59D58CAB /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796DC31A2574F842FC44B7D07E24A722 /* ImageDataProvider.swift */; }; + 68627C9B9C94CBE9310082E5F3B80CB8 /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBE52AF7E852F29CE60E348DA19F51F /* Single.swift */; }; + 68C8CB4EEC0D15EBBD6EFE6E11CD2BA9 /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 177EDA0B76DEF69DB8E291B1F864EE04 /* SchedulerType.swift */; }; + 68FB2DCB4C77DBCAF9A6037E470F2BDE /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B50EE591E7052D97A3A53393B0232A6 /* ParameterEncoding.swift */; }; + 6927E0A61FCF762B43C75325110C3D77 /* Infallible+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C4B6FEBA77235BB4623831F8AED445 /* Infallible+Bind.swift */; }; + 69657DEC11BB7E4F9F5B6DE8E1148B3E /* _RXObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = EAA5A2FDD88E02447CE131F7C5675472 /* _RXObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6B4D7AE51568761741BACB3CE30BC275 /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40312C667A21EB4D9E6C8005CD1B164 /* RefCountDisposable.swift */; }; + 6BDA2BC21E394076C2E58E9269F4AABD /* SchedulerType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2F7D87FA65948E65985C245E90F30D /* SchedulerType+SharedSequence.swift */; }; + 6DB19BEE9C42CBE8101A114524B38CE7 /* NSView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA0F4A1959721B796E0302A27F5EEDAA /* NSView+Rx.swift */; }; + 6DFB5C921332D5E14BF251A5ADA46473 /* RxNavigationControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C7D6CA2E239A1CAAB0805B3EDBDD3F /* RxNavigationControllerDelegateProxy.swift */; }; + 6E12D7E0202CB4077514D77014910636 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA5D1BD0FAEAB4E04B446CB9E483DDE /* Range.swift */; }; + 6F803B4767FE50C12E3F0402DC0A3BE5 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B5A237F228CBE682B896D5145A8F585 /* PriorityQueue.swift */; }; + 6FA433B7C87F256B163EF3D148C91836 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2341A179F0C231C4BC79A8F07E8B04E /* NSButton+Kingfisher.swift */; }; + 6FF209306C29489DF512C727B4E4DCC3 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 939BBB23FED848AEA8A9A3782F5BB566 /* BooleanDisposable.swift */; }; + 7081BAD4BC8B8755EBECEF3D62807B17 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148FCE152B9AD264C77EA952ACA5B376 /* Placeholder.swift */; }; + 7154F93C879B0E4CB11874AC95F6FF3E /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2CDA3A4DDF9E4D7E37FC3A32090E715 /* Source.swift */; }; + 726CC8E67AEF2AECA324D73D91F86E5E /* Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3A590980F39515643092D1F757109A1 /* Create.swift */; }; + 72EE3F69E6154EF5C5524DE4F4EE0B5C /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6663C48732F86BE136321DAE5C8CB4D /* Queue.swift */; }; + 72FCE0D3F5EA7EB908C108DFD468B267 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE870C8AB56EBCF98D6D45D93FC0603 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; }; + 740659793E5D906F5A508155ED8895DF /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3270291C59FE54F4233693ADDE644C7 /* ImageDrawing.swift */; }; + 74834D7DA6CD66CF130C58E3E08994EB /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22955779FC97B3947D45B4CA2A3C5926 /* ObservableType+Extensions.swift */; }; + 7483E5327027263F7E4B94A2997191C4 /* AuthenticationInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA261BD733B0E7D34A8B8C53BAF08E5 /* AuthenticationInterceptor.swift */; }; + 7580FAAB1BDA52F5A969E5571D1A5973 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68B4D2046A60FAA56B043EF6DBFDE4FE /* ConstraintAttributes.swift */; }; + 75966A9262648D4647D764E3E76BC6AC /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66053C44365424146EEB9240C16BAF31 /* Response.swift */; }; + 759FF7C6BA173954BA0BE5F3B5D77E24 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 165933865EF401961B5BB6932BC66E8C /* SingleAsync.swift */; }; + 768A33DCEB41CBC5C7ECF5F0220B1A97 /* SharedSequence+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99427CA80A669FE028CF88825B36EACF /* SharedSequence+Concurrency.swift */; }; + 76DBB416ED9F7C7E50A8D77BCF6A9E39 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F0123AEE5FF35F7AC3D76D8ABBF3F69 /* Image.swift */; }; + 76F9B7217220321AF3343F7F2C5781D4 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33267D6278C73D35763DC6851211D419 /* KFImageOptions.swift */; }; + 775E21559F53F43E4718A6702A8E14D9 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6411610C892550E50F787ECE3AC4475 /* Errors.swift */; }; + 7764AA5F6BBFC6ECE43959923DD007D3 /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B43583C37157540C0BAC4B4E7AEA76A /* ConstraintDirectionalInsetTarget.swift */; }; + 782082D9F5529E63F249E8811BA6FD10 /* RxPickerViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06041DE6F931C543695D7F87CD91C6C9 /* RxPickerViewDataSourceProxy.swift */; }; + 782D51D7299EA0505DF697FF0E1A5D2D /* BehaviorRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF9A1F6E5E6B9C758E8ECEB280377DF /* BehaviorRelay.swift */; }; + 78DE8DE64F023B0ACE1099C30C79CE59 /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33BA2B6551160A572CB11661696B838A /* MemoryStorage.swift */; }; + 792F9356B8A8971A54A4AB8AA8D0A917 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CEC7002B9A3286DF431B186F07F0E50 /* Scan.swift */; }; + 7930C94414B4C661867AC4FBE82E996C /* URLEncodedFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AA2DA550B097827DA12AE1415B11B4 /* URLEncodedFormEncoder.swift */; }; + 7AF4F47073D13BB9B24AC26CED06E503 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 783CF62358B7156761CAE141432059EC /* VirtualTimeConverterType.swift */; }; + 7B068137A8925891446203B5D3D6A4ED /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 872D7EFA572ECEE8EF993C27196E16DD /* CFNetwork.framework */; }; + 7BA5D9B38DAEDD6A5166ECF2A498D194 /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07A793D684FC253E04E29A6CA931906E /* RxCollectionViewDataSourceType.swift */; }; + 7BCA04E89CE537D96BC53943ACDDD305 /* RxRelay-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D956866F9C4CFFCB478A2F597636FEC /* RxRelay-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BD154ABB5889C5A57C73038BC1046AF /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A132226945BC922F96DF66A1385592F /* Repeat.swift */; }; + 7C9C0D2AB5BB6670928CC95B4DA46814 /* RxSearchBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 549CAA2B2EDE8AD94C5988D95A8829E5 /* RxSearchBarDelegateProxy.swift */; }; + 7D6988D0E6DAFBFD5F7653036BAD1172 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B229B8631DFEA25BD56F9A5330D76F9E /* Producer.swift */; }; + 7E02F5B62BE00E97847DF549FFED2490 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD17068C473F46FDDA345E0B8F45A14E /* HTTPHeaders.swift */; }; + 7F1BB526AAE3ECDCE90127D9D0E10261 /* StringEncoding+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1022AEF0BFB392161D650BF9E00A3D8F /* StringEncoding+Alamofire.swift */; }; + 7FE695DA8EE7FF1286556E06B692009B /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7AF374BE13CA7EF6CEF091D12B06E2 /* MultipartFormData.swift */; }; + 808C960C82D708FC1A42C581D6CB4940 /* URLSessionConfiguration+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3291F34A83BABC8CAB3AF78E427484F /* URLSessionConfiguration+Alamofire.swift */; }; + 81148E8E0935476F92B10881A023D0DC /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE9BBA6EBB5DF07D0B176CF85B2686 /* ControlTarget.swift */; }; + 81B8D2B7CEB25C2448B0BC9B33591A65 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = D002139C96A6306EE9B058F61088B34D /* Session.swift */; }; + 824D816B1EE404F2DD400EE678695CBE /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5751604115D39C388D1C4A1612A40 /* ResponseSerialization.swift */; }; + 825016F72360D2F15B9E6C5B26E8C5FE /* Dematerialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B6D7EC7AFB179E41E13D4BD2C664704 /* Dematerialize.swift */; }; + 825062025906CE93C5D124E1FD9A811E /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0BB8711A19D4B872ADBAE7977F2D55 /* ConstraintMakerExtendable.swift */; }; + 82599CDDE7F5D00506446BDB932AEB5C /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8890470F000AFACA77AF03D583016B43 /* SubscribeOn.swift */; }; + 8449EB1DFD43E222D687D5A8D2088D2D /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC48DB40E7345B46179098B3B1AA269C /* ConstraintLayoutGuideDSL.swift */; }; + 84AEE29F4E7DDA962C49D6FAC6044EBC /* RxCocoaObjCRuntimeError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5532071B77604F3BDCDCAD049CC3294 /* RxCocoaObjCRuntimeError+Extensions.swift */; }; + 84FB94B98DBAD3F0C0100684A1688F8E /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A7F6C8121A6FA3F53FCA8F53EA8FA /* DelaySubscription.swift */; }; + 857B833BCB63CD49D92586E88C015EFD /* GroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D56845A1D247158DDA408F45DAA35E /* GroupBy.swift */; }; + 86DD807C261B13BFB5EDA57B449D255E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; + 8A8AD24A8CE75FBE807EB5A9FC11E62A /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = A71FF01397BCF8E5126F7DB2781F9A19 /* Bag.swift */; }; + 8AEC3BF02D80F6C75FB754802E1641DB /* Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FFFAEA9D04F0A584135382514690C3C /* Infallible.swift */; }; + 8AEE5B74A5BAC274D6589F229D867768 /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69679F318A371FDD8C42439C3FE25586 /* UITableView+Rx.swift */; }; + 8B7AE8992E8C60B42CE14F1872BD4C45 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7146CCCBE0B9901F601E355C2966BD1E /* AtomicInt.swift */; }; + 8BB2A01CEAD519EFCA788C230C4CE749 /* Enumerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005BC5B30DAB73C72CFA4D0B90F85194 /* Enumerated.swift */; }; + 8BCD24C9CB7B9B8C7E9A5E67C33D7474 /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C1BE9E50D4CDA794129A973C8D1103C /* RxMutableBox.swift */; }; + 8C6546C1EF4F153DF3795CC6FE189E5B /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB8779B59592C7549ADBF5AB5110B0BB /* ConstraintInsets.swift */; }; + 8D75FC8D7476C9674234F39F1A820D8C /* URLConvertible+URLRequestConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475798275244D376C942E726734ADF1F /* URLConvertible+URLRequestConvertible.swift */; }; + 8E1AB4F2C63A8078B1C5C2922465AF7E /* Binder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11B4424ED13C46FF58813926D87E872 /* Binder.swift */; }; + 8FB6F81C2CAD8C37AED9FAE35CC8F8CB /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94BE1EE9EBCA5538B271C44C0D2C3061 /* Switch.swift */; }; + 8FD9CD608C4EAAFDE6AC7B8B9EF0FF5E /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 441B4B5DF69FFFA7DADD198084C7105C /* ConstraintDescription.swift */; }; + 90585B3B5526DB8ECBD1AB8EF2C4D5A2 /* UISegmentedControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191771D857A79C686B98B8202157674F /* UISegmentedControl+Rx.swift */; }; + 90FD5AE525E138A473723FD79AF73273 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = B75D4359FA407C5BFDCA84D5DC68698E /* ConstraintDSL.swift */; }; + 93209671B01B76711F6E2022CADBAC9A /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8987AD5E008F7FF45922286EB79F0 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 93AA229451CA5480337B1EE292631D31 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92425124E34B67695B33DCE332AA82EC /* Map.swift */; }; + 94DD2520F1E5BDC7BAE2AA9414929AB8 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9D6C9CF4A996C73FDDD4AC8781A22F7 /* Observable+Bind.swift */; }; + 958EBCEB7DDEAE24ED5FCAF0F89A3AAF /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3CEEAC4F4177C22F2015BD3FF1F24 /* Just.swift */; }; + 961B5042F0BFBD2C5FCDCCF40E2EA7CD /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DCCFFDB2CB96005F27FBF226FC2802 /* UIButton+Rx.swift */; }; + 968B4874A9F12D67C8B901136C9C8157 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B431141CBD5FDEE892FB07B93CFD1D51 /* SnapKit-dummy.m */; }; + 96F9E4762C05BF7B009FA52FC18C18C5 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70A10D5A2BD6546E0640BE73E3A4B3D2 /* NSObject+Rx+RawRepresentable.swift */; }; + 971CE56718BB8172DB2971C46C43D4A8 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D250D8F7946F2AB945B56880B4CDD35F /* SessionDelegate.swift */; }; + 99D058E53EFEE3AC4857CDE3DBA5C004 /* ParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D96C8448CD7962AF26C90A25D4D1294E /* ParameterEncoder.swift */; }; + 9A151985A3D24023E8B2996BF3EBA2BB /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 20804B3A6BAEA5B63222084242339F53 /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9A4DAB9C0D2A74A496D10C7A648E3162 /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C95DFD2CA4362C4313EBE5596AD65F /* ObserverType.swift */; }; + 9ADE1DD7C6AD8B57FD158350A66EF8D0 /* SharedSequence+Operators+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8ABD7704AF8D558B05DBFE563C8BFB8 /* SharedSequence+Operators+arity.swift */; }; + 9B4F0DB0CEA7727BBC0843626D2348DD /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E35174A2243D3E1CDC3F2518EBBCEB7A /* AnonymousDisposable.swift */; }; + 9BAAAA76EE3244511BBD43460DE1AAB6 /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26ADDE7E696F04B30C9DC8A393455CC5 /* Reduce.swift */; }; + 9C9030DEDB0DF955B16FE08C50892D57 /* Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29A289EF7C91591D808694C7F3473ED /* Concurrency.swift */; }; + 9CE4F36B67C9DAEC1DC2DE6CA692D0C4 /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA78242DC744444804153FB317B7E2E8 /* RecursiveScheduler.swift */; }; + 9D647894171B5678D7B8D4F0DD977E46 /* AsMaybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22728DB59B0890DE4D0BFC938A5E5319 /* AsMaybe.swift */; }; + 9D68AB68528E2196882E63F5253B803A /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E5E13511F0AF2F8A7C637D0B1E5CE61 /* Reactive.swift */; }; + 9E8BA4FB802EDCD492DAF618CA7BFCE8 /* SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BA94ED52F0795DC30B8EDF36697174 /* SharedSequence.swift */; }; + 9F370B3928A333AD7E41680A29B1F051 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8EA5BC052FE1348FF54A000FECB7186 /* RxCollectionViewReactiveArrayDataSource.swift */; }; + 9FC98D1BF3A981BB349E26D712298FA1 /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F76798AA7C42A64C4EB6B59DC95A77 /* UIButton+Kingfisher.swift */; }; + 9FE18707EB6166A53076FE3CC036593C /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB92E87126CB99BA3210A3EC1AE61DF3 /* ExtensionHelpers.swift */; }; + A0208B623442A26CB9157F193CBB4A7F /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2424AF78DDEE23C54679665B2E11CECA /* Platform.Linux.swift */; }; + A026156F75FE82816C8564F0189D3E66 /* RxSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AABBF71F11B9315AE1BF54B313097F7E /* RxSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A0EAE575DF5FE7FF693B676BD39D1628 /* Date+Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCFBB65EFC4BB3B34271DEEEF799093 /* Date+Dispatch.swift */; }; + A0F754C88A64972A40A9008B0AD52109 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5422501686FAC3E64A8018D8F903CD57 /* ConstraintDirectionalInsets.swift */; }; + A1219B093051C45CDB7785A418B9F2E1 /* First.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438DCEC5FA002C1C232C8B944C833102 /* First.swift */; }; + A20321979D272B922CD60B531BD05F7F /* UIPickerView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 748BD5FEAE0F1BDC45114CB14C6322A4 /* UIPickerView+Rx.swift */; }; + A214A653E430C9079AA7B1090169262D /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FDF6CD75C1834270FDEB7F5D0F2BCB1 /* UICollectionView+Rx.swift */; }; + A29100AA1876DDEFF6F54694A51FDB0E /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460CC31FF924BBE87297386FE46558DC /* NetworkReachabilityManager.swift */; }; + A35744339D7CDDB79F14A079F613690F /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 052B51BC168C7D6CF8335F93AF4A67A5 /* SerialDispatchQueueScheduler.swift */; }; + A43E1C231F1C28313CF575404CEE0545 /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C3484BA91ADC6B89669375A948E937 /* SkipWhile.swift */; }; + A4467357581E8345DD348683CC4111AF /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F20EB9BFC1006360D8A179A92D3A514 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A53BDE589BDD6483F3EEDCE5EA1DCCD3 /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 054144A7760E716E29603EEDFFBA5AFF /* Protected.swift */; }; + A53D3AF15CE8D348306EF11619C5D166 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB4AC18518632E482B180EC7A9807907 /* ConstraintMakerEditable.swift */; }; + A56DD9B245C6C527525315654E2AD44C /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85D6B6C09F3FA02098B1204C99334CA /* ImmediateSchedulerType.swift */; }; + A6A82B7640E18944A6FFC4BE7348E7F3 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F77858A4515CB188A0008E88C302846 /* SizeExtensions.swift */; }; + A71A6D16F682FE7F5B81B16462F6C016 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D8E8D89BA483ED17D2EFDD71921594 /* ImageModifier.swift */; }; + A93FC5BCB5B02182D27377A3724A60B1 /* RxSearchControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C300A4562E606959DBC2D95A38D347E /* RxSearchControllerDelegateProxy.swift */; }; + A94A3108B2C0BF641D8844073D6AA4E5 /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078321DA8756A79AA1EBDF1D3DFBA9BB /* ObserverBase.swift */; }; + A9AD1FE8379356D400C79DCCFE944E03 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F82EB30ACBF25A82505A35ACDCE2A96 /* KingfisherOptionsInfo.swift */; }; + AAA7A11591D6E4B06124708291C37698 /* RxTabBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F01D8505DC894677CE2FB4DC24B4018C /* RxTabBarDelegateProxy.swift */; }; + AAACC4639E0E182F756173EBEA4494F0 /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0DA1708C5DB689CED1BB733A6202C2 /* GIFAnimatedImage.swift */; }; + AAE9191316FB42B81F0D4A976E9ECB34 /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AFFFA4F985B09306F6EB74771AA77D9 /* Delegate.swift */; }; + AB39D86F22CEF5983E1DAFFEAEEEB62E /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7776F5D697B91DC2D5C6C66F4B6D0C6E /* Maybe.swift */; }; + AB88D7A71BA82D3BAF097C992BFB221B /* UISearchController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC08F9FA24E20B061964BC084936292 /* UISearchController+Rx.swift */; }; + AC0F2D4998FF0301C35D35076221D223 /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B8F16D2904D429E2EF80FBC37D8B531 /* Throttle.swift */; }; + ACA3DBC73A19F3CDF9C4FAB09988D0E6 /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 579FA3521C9FD6CB4DCCB1B2CEF7982D /* RxScrollViewDelegateProxy.swift */; }; + AD0DA93E31995012541F4FB0C826E7D1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; + ADD49C3CC3A47AC337AF803D2B5B4FE4 /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3076DD5597EABB5CD920CFF6E4ACC7 /* Amb.swift */; }; + B00B8088EB50EA3F0F875993C675F421 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98553727E761D8D5A0BC081285ADE9E /* UITextField+Rx.swift */; }; + B3167FEDC691D1DDF267F855CFF33636 /* DelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 741FCF6FD88310101424A7ED16D279BF /* DelegateProxy.swift */; }; + B322C801FA13AE9AA91938FB19632FE5 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9705F4FFEB198353334C91129FD3C7B6 /* ImageDownloader.swift */; }; + B3658C29BBDE1033F6269A92E612CB30 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9070D35DDE49A9987567E3F308BB5221 /* Request.swift */; }; + B389BAA9DDADE0C535CD9EB2EE2406E7 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D5C72E2C612EAA4B4CEF7A4D0D3479 /* KF.swift */; }; + B3F14F1B196B5858BD951366FA89FA6D /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4715F04958933344007626908174565 /* RxWKNavigationDelegateProxy.swift */; }; + B41169CFD62EFFFE57DA3CA725B8461A /* TakeWithPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD5108531A657F7454879387DFB795 /* TakeWithPredicate.swift */; }; + B4738CD9680FAC78FE01FF5BBC400038 /* WithUnretained.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E0BD09EF34AC741CDB014F457C2EB6 /* WithUnretained.swift */; }; + B47E0A20015DE86B789B6A3E4FA754EB /* AsSingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25AA7B62A9465F5790FFF2F2F453B872 /* AsSingle.swift */; }; + B543FD108C1C6AF6129CB4991553218B /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D22CAA3D66865CE1343FDADF4776379 /* ConstraintConfig.swift */; }; + B59095D5EF330419B3ADFBAD7EBC2B1F /* NSButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA689679D51D3F44B5448DA52B49346 /* NSButton+Rx.swift */; }; + B5ACECCDD52AF69EBA2E11666BBAEB42 /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE60A9AB9690D6EC4D6CB050F76F0AD /* RxCollectionViewDataSourceProxy.swift */; }; + B704B198B9B520D449260877E300D821 /* ServerTrustEvaluation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD233B7BE3779DE6C50056326BC19F22 /* ServerTrustEvaluation.swift */; }; + B7073CAE42F064FE8640EC42C0C02C94 /* PrimitiveSequence+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3AD1926FB78B2FA344D6CFDA19C5F93 /* PrimitiveSequence+Concurrency.swift */; }; + B7C50E1B30639A2AEA990DAEA803D877 /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32AA4A86EE5313C95E3669CE9DA5FDC8 /* Platform.Linux.swift */; }; + B7DAC534D4F0A31CD95FF6613317D4E8 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F469F47D809A2E852FFAB72BFFE46D9E /* AVAssetImageDataProvider.swift */; }; + B88BD26F9E6E1815FD277AA2EAA42A6B /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22F549E90893E8656AD2EEF4F9779A50 /* DistinctUntilChanged.swift */; }; + B969B7566F02943CD0E6225B99046B7A /* ObservableType+PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD67BADF711C03B22878143404E08FCB /* ObservableType+PrimitiveSequence.swift */; }; + BA5658B6C27A81FA4665E507A1ED88DA /* Driver+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1FEE76912A6E8FC2242C3F48DC49D8B /* Driver+Subscription.swift */; }; + BA6758186158F65AE8730D5E20374A6A /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE75E6B4CC424ABF9C8A7EC4DD4517C7 /* RequestModifier.swift */; }; + BAD3834746DAB3C038417D16101B29A2 /* NSControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB4260CF2A46B845613C59B79940D4E /* NSControl+Rx.swift */; }; + BB4D9C116889C08F6B6D1B54C39FC843 /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A464E4AFB2F136E06330E8CDEE738CC /* Sample.swift */; }; + BB72FC9215BD907A82AE928782813D6C /* NSObject+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10D5ADFC37FC97F51CA8E4B68AC314C9 /* NSObject+Rx.swift */; }; + BB80D663FC32A2B643E8EFE8671A8AF9 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92C6D703ECB03FF623920A2ABBA1C984 /* BehaviorSubject.swift */; }; + BBD437FE6BFF63452E6B7E08DFAB4DD9 /* UIBarButtonItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA0DB41F8746732351623A4D6285F83 /* UIBarButtonItem+Rx.swift */; }; + BBEB88D4196A5F8621F2D16DF91C251A /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE5C37C514852C880072749300AF8A5 /* GraphicsContext.swift */; }; + BC0ECA8F22DEDE8886E189CD0EAA1197 /* URLRequest+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5DC8DF1D5F1FD3FFAD27AF5B10C367A /* URLRequest+Alamofire.swift */; }; + BD333CDBCF5D2FD55920336FC271DF33 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 928A9C7117C36D7FD359DDFE7E4D8CD7 /* ConstraintItem.swift */; }; + BDBD294E7476703843206D8CF206FAE1 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898579A8710C12A1F5B70B4A455D8F6 /* Disposables.swift */; }; + BEBF920FEB959B46A76BAADF22E5CD15 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6107C17D2C9AC490E84B09E3E310181 /* ConstraintInsetTarget.swift */; }; + BED0BB02AEC5E805083AB1C27FFABD47 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FAB2E960EAC19A564D96AC83373912 /* Sequence.swift */; }; + BFAFD7E071AA3B256C9DD2FD4FE462D3 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA9A617FFE3AADE8D62793D1CFD5C6 /* SynchronizedDisposeType.swift */; }; + BFBB09BD0FC31CA7FC9FAF63F25EAB49 /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FE0EBD2D580EC665875B83BE0B38369 /* Buffer.swift */; }; + C12DCA02D36C5C6167F566AFC96A6057 /* _RXObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 65E38C9F179F1817B63D21E6B8042079 /* _RXObjCRuntime.m */; }; + C2C5D8B4AF75769B70EB40321609D4E5 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C119DBAA7D6E7B3882D1CC7B760256E2 /* ElementAt.swift */; }; + C2D4FEEAF01038DB5C31CA401C105476 /* _RXDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEA69A88EF4071C8F5957A614F62B71 /* _RXDelegateProxy.m */; }; + C33927F838E5C40F86F8A1AF4E09908B /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB7DC60BEE1C9BDE9A6AFE88497F85E /* ImageView+Kingfisher.swift */; }; + C378AC3DF57A41F6F16D01BBD7A1BB02 /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 807ADE91E070BDDFA8FC7E6D0CAAD435 /* UIActivityIndicatorView+Rx.swift */; }; + C38A6B82ECB3F38D79C0CD50A8F5314F /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C76BFDCF0D1D12711765650CA1E6C6F /* RedirectHandler.swift */; }; + C3B55E6E14235355F0D858809F96318F /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C234656CE4C4E9C9ADB150EC38A6316F /* Catch.swift */; }; + C4D8634C6869EB91981E145F18775A64 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B425BCF674CEF3AA80353C753E6527DB /* AnyObserver.swift */; }; + C61D3BC32A28A405C934C00039AD2583 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798CB81E1C040FD4AF4AEBB9C9FD0A3 /* ConstraintConstantTarget.swift */; }; + C6A1AF1239CD2F0D4745BAA097E1E63F /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9076DC103CA5FE5AAA229FA6D4F12EF /* RxCollectionViewDelegateProxy.swift */; }; + C6BC5D2F6DBEFF403E7C9FB77DF5CFA1 /* Pods-GenderList-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7738ACDE4C2E00BC16AF9185E123A3DF /* Pods-GenderList-dummy.m */; }; + C784A7AAD94DD830A9EB5ADDEE6DE1BB /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444654C800FF5388EA6EAFCE09425593 /* KVORepresentable.swift */; }; + C80C3B232CDBC4596819D48611CD3F3C /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42BFDE3D268FD1437C5660BC87A65B82 /* Lock.swift */; }; + CB194156C900B767B0160AF72EDF354D /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D242FB48AEB035B24741F5EF5D470D9 /* ConstraintMaker.swift */; }; + CB3ACAC0625702DEC5BBB5F9AC0CC737 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B8AB683D3CE1BC246D1C753622BC4FC /* RxTableViewReactiveArrayDataSource.swift */; }; + CB8E4BF0D710970BE2CB4C87ED1043E4 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D05715E1C746DA8A57A002AD77320E2 /* ConstraintMakerRelatable.swift */; }; + CBEC736105CA647913890C03225F8A02 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06D41EF68321F25F5DF29DCA66512232 /* Indicator.swift */; }; CCA22C9F421C9E8C13009947816D8C82 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; - CDA2A03D0C1CB2DA6C6C155F4A6B4DC6 /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4C951A1EF580FD0454E47472A52DEA /* OperationQueueScheduler.swift */; }; - CE08483A41A5535019BE5E198792480B /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = D13859A2CFBD9C9E8B504BEAA461B51A /* KVORepresentable+Swift.swift */; }; - CE2DEFBFB3BE1FCBDE3F2E31E31523B8 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4169B421DBD9C0157729FCA9836C9DAE /* Empty.swift */; }; - CEA1126250329AC5A8181BBCBA80CD5A /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = E21D0733C912FD68451BD423ADC83E4D /* CompactMap.swift */; }; - CF32140300489AD5D6D5A74E4605FDAF /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 446ACEEA7E8F01C4AE5F13F8715B075D /* DispatchQueue+Extensions.swift */; }; - D088CDD616285144B06805DAC3E47543 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B35807BDF3E02C1B736BA4C9C9358C7 /* Notifications.swift */; }; - D09D3D5580E233C6F91C67602EDCCAEA /* First.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCE1CAEA27D5FDE3D9D901415378A20 /* First.swift */; }; - D1176BD914607FCC189C844DCD985300 /* Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B47FE5B477CC9C18416010929166F7DC /* Infallible.swift */; }; - D13D417B236E736EEAE7217B5CE3EC5C /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDD7993237F89658783EA88C8FA4924F /* ConstraintMakerFinalizable.swift */; }; - D180D3EC24CE4493964AB67D1D6AD011 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0527510AA2DB17EAC9D3E218CAA163 /* ObservableConvertibleType.swift */; }; - D2004A03ADD62CD0C4649710F32A91F5 /* NSTextStorage+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70EB53F90BC2C2B55771AB42C6359FA6 /* NSTextStorage+Rx.swift */; }; - D25D7C8E973E45E6C0FBFE4DB9C8766C /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D6A0775465C48A70C1EEAA247354EC /* ImageBinder.swift */; }; - D2C293D847E95B01671EB3E6A32F11C7 /* WKWebView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D7887303BCD625A3E1124F82E25F6D2 /* WKWebView+Rx.swift */; }; - D318EAAE231337A1B12B985FFC561C8C /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9583D07CFEC32E9B920EC112BDCF8F1E /* ObservableType+Extensions.swift */; }; - D3AB490FA372E1922315D4F2E5709254 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA169B7E5D3DEAD4224D444953FAFD3 /* InfiniteSequence.swift */; }; - D3BC528010D39EB2D79585A671FD80B6 /* UIScrollView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91722A08B7BCDFD99580E9A0199DF3F4 /* UIScrollView+Rx.swift */; }; - D4281D376BB29F2F96DF52757BA89912 /* PublishRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A368B9BE806FE43AF910196519FC5D /* PublishRelay.swift */; }; - D47B1058991EEC007A109B8E354EDB80 /* ObservableConvertibleType+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0272514C0FECA114FCAA610EC7667C /* ObservableConvertibleType+Signal.swift */; }; - D4933D17DC286C3DABCFD930BED56DD9 /* UIGestureRecognizer+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED3E0D1A2B19426FEBE08684BE7EB997 /* UIGestureRecognizer+Rx.swift */; }; - D59C2826AD288ECFF576B2AFA312716C /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D10CFF2702506F9BC66AFA9CB1A285 /* ConstraintRelation.swift */; }; - D62994E37E5361799FAED88CB599F54C /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53773ECF7488C9D01CE5D439FCC2F8A /* Switch.swift */; }; - D6789C85077D096CA8207A1D9506855A /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1695D8C618F845EEE48F2BB9379A7BF4 /* Event.swift */; }; - D6FDE9DFAC4AA548A9A4E2D6BBCE54FC /* ControlProperty+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76A603A5E56D14C1699BCAF85E537B /* ControlProperty+Driver.swift */; }; - D7485F98CA583821F27B453525AE3FC4 /* URLConvertible+URLRequestConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46DDD7887D41973B96666E7A02C9ABF7 /* URLConvertible+URLRequestConvertible.swift */; }; - D80F8F9C519042D5C4963C3C6EB38EDB /* URLRequest+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = B91BFE5181BE61CE32BA2259CFA60B89 /* URLRequest+Alamofire.swift */; }; - D86E9AA28F30B9D4F2DB59F1CB006BDB /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9781B0EC24FD1296469FF205F8FB810 /* Queue.swift */; }; - D94A213784584A035BCBD920F5523BED /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 545F2DDE7D8FF39935F86D5FE27C8CC4 /* Filter.swift */; }; - DA0B42F2B99DE08DA649A2D34E014EDF /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F67A58719C517741D63F9EAC3F24D6 /* Observable.swift */; }; - DA5010F0D48E5F17A1354FE9A04A54B0 /* GroupedObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2453D0762FE79905E9AA9C5F5C3A5E75 /* GroupedObservable.swift */; }; - DAFDAD884F67D6AA40088987D130DC69 /* AsMaybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D335E71CC0ADA589EE65F467A506799 /* AsMaybe.swift */; }; - DBF30FEB15CAB9CFE1DC70FF95DD03ED /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3816ADA06410A6B7793234D38F84D5 /* Amb.swift */; }; - DC309086C2612291A6B8D6A8D9A94836 /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A70846FD158CE4ABA153F2AB82F1051 /* RetryWhen.swift */; }; - DC3B023EC3C6BE247CB08313FD0E2483 /* Pods-Bunjang-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 81596965EC2DAB2BF48389645FC00166 /* Pods-Bunjang-dummy.m */; }; - DE71610B229DF6E2B65A8574BAF21414 /* SectionedViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D83223BDC370C77F9850BB2A6C8742F /* SectionedViewDataSourceType.swift */; }; - DEEB75010ED18CFCC5FA49B8AFF4F58F /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED95C7C562A3738CF2D4BF66BADF61F5 /* LockOwnerType.swift */; }; - E14E0F5CD9A3C6D97ABE3593D74A675E /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0FC9E7F5D5E10E8BA353C0F145507D /* SkipUntil.swift */; }; - E1A94B0C5B6CA70F75CDE21D3B5AC03B /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7016AF1EC96543C2911C96C8D525402B /* Kingfisher-dummy.m */; }; - E1FC31214C2340E23E72E185CC628C9D /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCCF2EE2D7FDC0AD69FBC3A1B95A1486 /* RxMutableBox.swift */; }; - E2DD0D46EBDC369F2679C8652EFF57D3 /* Decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8502AB6F24119364EC6FFAC9C51D8B72 /* Decode.swift */; }; - E36244E8BF4AC941E82DAF16DDF4BBC2 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD09C5F6714AD9AE9D5F476B1B38822D /* ConstraintPriorityTarget.swift */; }; - E461634A31671B2A3C2C987D3980899E /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42216AFFF59E357B6AF1F1378A785AFF /* KFOptionsSetter.swift */; }; - E4991F3EEC8667D7EF0298765B0D7615 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0096AB1EA15E66D9C5112DE4712A1426 /* Producer.swift */; }; - E4A1B4245A2BA9C2F2F5F5CE2DF9D42B /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13717D0A33898D0C1E1121E04A69AACF /* Runtime.swift */; }; - E66514C0F6827614A173DAC5EE6A488E /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B439B367CC6C89C100ED8B736E470FA /* ImmediateSchedulerType.swift */; }; - E6E9A5BB0387E3074B7BA055474CDE59 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC362006304825F3407E5280F369197F /* NetworkReachabilityManager.swift */; }; - E714A429777E3DC4B0FD85923B8152E0 /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87C76EEE158FB9F89ADF843A9FDC6ED /* Timeout.swift */; }; - E74C07C3ADC2EC1297C9DD792F4705EA /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E18733EF8F0BF82670E3C3E41AD6A82 /* SynchronizedDisposeType.swift */; }; - E7F5132BB0CB075F62DE7233B1E8D815 /* CachedResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A84C5BEA876D4A87BEB5E63B35C885AC /* CachedResponseHandler.swift */; }; - E8B4B88BF0241821B81503E1BBE639F3 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC109E1398391D4E301F805F761BC5B2 /* SessionDataTask.swift */; }; - E8EAADACF3BAE33BDECBC7214EAE9CD2 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D4E5B389FE76E8E5A9C151697E1E3A /* ConstraintRelatableTarget.swift */; }; - E9EE1BCFE7318EFF181D763503311830 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7C1CDFAC10807BB2B956A999969A0FF /* TVMonogramView+Kingfisher.swift */; }; - EA5FE4B4B3BF04976C37430E4F3721EF /* RxPickerViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C6D9986152A06D2ADC0063B133E754 /* RxPickerViewDelegateProxy.swift */; }; - EB0B3FE0AC29ABE1F29157FF00372579 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CE79655B8A34D6270A73B843CF2271 /* Errors.swift */; }; - EC96B25961BF365B71E26EC3A3DC2E74 /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B3A7C706BF0A33310C00DB4E7422EF6 /* PublishSubject.swift */; }; - ED3EFCEEC0DECC4B0075A3590045C90F /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38F45BA184E5E0716F4908F767BD7B3A /* TakeLast.swift */; }; - ED81033ECA0A6C579EE97116D225C11B /* Pods-Bunjang-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 45740A99F06B13415E6AB7855CA64512 /* Pods-Bunjang-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EE2101E9CCE79962CDBD4DC80820F0B5 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420B4C2C25E8A2AF22506AAC158F2AD3 /* Request.swift */; }; - EE6C364198A763EBBF49237035D86439 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDD4A751EE1628FD6964148586377853 /* ConstraintLayoutGuide.swift */; }; - EE97D2B2E79237770CE018342B9F86E7 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A785ADAF5C7B8D666BB4ED42943A8662 /* Resource.swift */; }; - EEA7A2B1F6816985A1E409C674EE8D64 /* RxRelay-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4A33D4EBD87311076E540A7ABFA143 /* RxRelay-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EF6DD06709E5EFD67031FF9B5901A827 /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5D8C38F674F50CB23E901928ABBFA5 /* RxTableViewDelegateProxy.swift */; }; - F06F8EFE57A2F601B0D79E47A80DD6C7 /* ObservableType+PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B79B95D1B2DDEC221F61E2BACEDAF527 /* ObservableType+PrimitiveSequence.swift */; }; - F10586462FB54CEA169A1A7A469A926D /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2863AA3C3F0EBF54E3EA897B0EB74C7 /* Debugging.swift */; }; - F24D06C23DAB2F52A30C886A7A8177C7 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0739409A23BACA2BE8DD8A961490989 /* ConstraintView.swift */; }; - F2C817C166B2DE613222C41015A586C9 /* ConstraintMakerPriortizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63004A6A6B9BEFDAA58B7FA062278C43 /* ConstraintMakerPriortizable.swift */; }; - F2DDF679DF721DDA14A53744DD540092 /* NSSlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5BA2237796BAC05B2E72B417F5A80A /* NSSlider+Rx.swift */; }; - F343BA4E457FFDB0165492AECAEF0BCC /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = A60CCCC9B71B8257E82BB6A53357E35F /* ConstraintPriority.swift */; }; - F3B4A826460EF6A9B19849D1E7AF6A52 /* ControlEvent+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87FF9A89CEA3BE638D492B4D2861FC5 /* ControlEvent+Signal.swift */; }; - F3DAFB3407F9AA3DC771780393571F44 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = E02491ED736B233DE2EA307C1EB3E2B9 /* SwiftSupport.swift */; }; - F5AF27692F3A5C9087F015B5C40A35E7 /* RxTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89A1E4268C8D59F48FC54DA5809ACC7 /* RxTarget.swift */; }; - F60E2B85B28D1E27FD52F9B0D62A50C8 /* _RXKVOObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5401FDAB1CBADE2FD2AC91D65EBBD4DC /* _RXKVOObserver.m */; }; - F76AEE9A262B7167CA91A6D655B5E1ED /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADB2003C180AFB52A18317561E6EC5CE /* WithLatestFrom.swift */; }; - F7774F70F3F7CD7E11F01BD8B62FFF15 /* URLSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4BC0F2018503D8002E78FCE926EE3DB /* URLSession+Rx.swift */; }; - F86B6E741E98823EFF48A83143AB2DE5 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C475814CC7778BF88A47494A1117A28 /* DispatchQueueConfiguration.swift */; }; - F9821B669566BA01F845426DC6834E76 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3E2A7B51D1978B92017963C55349295 /* Observable+Bind.swift */; }; - F99C7F747D5923B1FA1BD0391689DD02 /* Dematerialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A72DC794794857921D83CFBABFD01B /* Dematerialize.swift */; }; - FA716F33C3239E937506439FE68C732B /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E23433B6C5425020E1F9ABB659C33A82 /* AsyncLock.swift */; }; - FA912508169DBC6AE52589B4499BE6A2 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348AE3FD864F7622AB84B36307F89F84 /* MultipartFormData.swift */; }; - FA9A2BA92C72AFEF5E1E8F2141B792B1 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682485D6700D5F4F209B3D7E8409414A /* AtomicInt.swift */; }; - FAF7C9C4F9B6AE2CE9F5866B210D9275 /* SharedSequence+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C930E38E9AB3484081BAF76C727EC9 /* SharedSequence+Operators.swift */; }; - FAFC45EC2A1770619807DFC5722F4B6A /* Materialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60ED99EA71CABA14574423D41AB0E5A3 /* Materialize.swift */; }; - FB10CE2650787118D7250EA1A14A157B /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FDE8944CE97206B2673253F9C20298B /* ObserveOn.swift */; }; - FB780B6BCB35FF39AD890C2EA6A643D6 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA51397293F7F7DE9320460FD4C14042 /* Zip.swift */; }; - FC07184FF229E4890E76F265656AAC27 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501297031677D31F36A769809D7584A1 /* WKInterfaceImage+Kingfisher.swift */; }; - FCD9660A73D7E00EA19E2F2295876E04 /* NSTextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892593379667A23952F2CC74685738E3 /* NSTextView+Rx.swift */; }; - FDBED395B752051186CD060058C112A2 /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 037BD3F6EA04A1FC02F2B43610E6A808 /* RecursiveScheduler.swift */; }; - FE30D82C6943E1BFE447A6401F60F9C7 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EB20F3A45D6B29A3E978F87182B9C0 /* SubjectType.swift */; }; - FE3FB93D29E138FEF654FB00C5427502 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = A44A26151470999E8036AC468A9C1372 /* Using.swift */; }; - FE9261A1344AF922C1EFCB457B938425 /* BehaviorRelay+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C3BB98B0EF87EC7B8B22703000ACA9E /* BehaviorRelay+Driver.swift */; }; - FFE11DF8D55C540876E9DDDC8AEEF5F4 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFD8B7C287CE97937818BB36E6D0F7C /* Deferred.swift */; }; - FFE42C0183B7DB7FB6A69CD174BB9A8B /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C078D8BDF198136B167BED30F8A82E0 /* KFImage.swift */; }; + CD5F9A08105A83748118F9C42AE9A59B /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF86AE6F99EFEC9B7B0DCA289F5D3DF7 /* Sink.swift */; }; + CD7328672FB232064C60AF7F5846F2AC /* SwitchIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D2E9A71B82298E7CEB37848357F768 /* SwitchIfEmpty.swift */; }; + CE08483A41A5535019BE5E198792480B /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 291F7C069F9E079F932FDD60D8FEFA7D /* KVORepresentable+Swift.swift */; }; + CEBFFEED65D877702B2F36102528CF6D /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC6172868C69E6D61153FD817422A036 /* EventMonitor.swift */; }; + CF32140300489AD5D6D5A74E4605FDAF /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF28982DEBE7F0803BB0597AA1C3FB2 /* DispatchQueue+Extensions.swift */; }; + CFDB98312025EA51DD6FF7F4BF65EB53 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EF4A1F3526BE0CAA711E9BD807894D /* InfiniteSequence.swift */; }; + D0EA90FBF83350C49E6EF6C8A98D6F00 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0809DCB644EA1525EA9CFEE9018507 /* AFError.swift */; }; + D10AD22245405AE890465C359AE813DC /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D74B49F8F212BDF24A91CA248B5EFD1 /* ConnectableObservableType.swift */; }; + D13D417B236E736EEAE7217B5CE3EC5C /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60A77062CC86E62ABF59F12FCA57E196 /* ConstraintMakerFinalizable.swift */; }; + D2004A03ADD62CD0C4649710F32A91F5 /* NSTextStorage+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B9A7E0A2CEEFFF576B51280B8D3A4B /* NSTextStorage+Rx.swift */; }; + D25D7C8E973E45E6C0FBFE4DB9C8766C /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952EC55F4C5F9DE9E5C6CEA37ACFE65D /* ImageBinder.swift */; }; + D2C293D847E95B01671EB3E6A32F11C7 /* WKWebView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A1D01CFC7263F1507C121415A60F10 /* WKWebView+Rx.swift */; }; + D3AB490FA372E1922315D4F2E5709254 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 806A2A4C9A4D1D5500BE72BFA6B13F91 /* InfiniteSequence.swift */; }; + D3B02ADE07B83FE23250F00B136ECD4D /* GroupedObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E447DD75B5DFC0A94F8F3AA082F16DC8 /* GroupedObservable.swift */; }; + D3BC528010D39EB2D79585A671FD80B6 /* UIScrollView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4604F79F3B7F16F870C0140292283C /* UIScrollView+Rx.swift */; }; + D47B1058991EEC007A109B8E354EDB80 /* ObservableConvertibleType+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E65E3AAF488477C388FE9A469DDD299 /* ObservableConvertibleType+Signal.swift */; }; + D4933D17DC286C3DABCFD930BED56DD9 /* UIGestureRecognizer+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94D54A724CBA85DBF90033986466C60 /* UIGestureRecognizer+Rx.swift */; }; + D5345CAD9E5F5AF025A6DC493CC5012F /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86EBEFE81557E00B7289D083294B013A /* SkipUntil.swift */; }; + D59C2826AD288ECFF576B2AFA312716C /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3161196A1725FB042806502C2CEC58A9 /* ConstraintRelation.swift */; }; + D6B4751CED01D53E4A1B6A571AAA2F83 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = F934FE3C0472E89EDA71BECB5FC29245 /* HTTPMethod.swift */; }; + D6FDE9DFAC4AA548A9A4E2D6BBCE54FC /* ControlProperty+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D25D7E510A6EBB96395707104EF360C /* ControlProperty+Driver.swift */; }; + D716934FDB93FCCC0BA121FC16F86003 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5097A478504A238C6105200FB47B7522 /* AsyncLock.swift */; }; + D7FFB20DEF62B5311AA24C09E90C5696 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6484BB20C4A334B3CA255803D52D0AF7 /* Cancelable.swift */; }; + D8AD61EB551C0149A4E73B329453A728 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79F42263D865156D4945BFDBF0A4CFE4 /* SerialDisposable.swift */; }; + D8EDE74BEBFFF3EA4FB0A6223EF2E1C8 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6EB7CA5E10FC28F6095BE8C836B9DA2 /* Timer.swift */; }; + DA34899BEF0668D76CBCE8C4CE47B97B /* RequestTaskMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF147A0D663689C5F262DA7E61709115 /* RequestTaskMap.swift */; }; + DAA64B0B05454217B68219FE3382E2FF /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15311C960C78890DFEF8D4F4193F6359 /* Platform.Darwin.swift */; }; + DAB3CB1F3375E2DF78FED00410552E18 /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6A4941C676635405DF83466B0BC26 /* RecursiveLock.swift */; }; + DB065281A8ACCBF9F5AFB9C5CD5C488E /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1040B8497C8CA28E0B37F77BDC2744F2 /* BinaryDisposable.swift */; }; + DB8C1AD404036A35DDED5CD6660BAB39 /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E991AAB3675553011A566D7D5890A76 /* Never.swift */; }; + DBAB6D10C12919914BDDFB9F0B4C51AF /* RxRelay-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 587647AE89A8323AA8669B5ACA6201BE /* RxRelay-dummy.m */; }; + DC6376BDCF34BB4FACC68A1787340936 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A910CC14D263A3C2DBCBBF8AE936A9B2 /* SwiftSupport.swift */; }; + DCA42663650B6F75040B37A900E2C869 /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C579C36CDD6CF5A9A0BB547AA750D5 /* Zip+Collection.swift */; }; + DD902FE8D6824681C929D028655AE121 /* RequestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E4760342B9E9A2D2585A3A124C49345 /* RequestInterceptor.swift */; }; + DE71610B229DF6E2B65A8574BAF21414 /* SectionedViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BB1AECA99796B254CE53707A66D22E /* SectionedViewDataSourceType.swift */; }; + E0523EFFB9B91BFE897AF4EA59992528 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5376CA15D3279EF75237B1C406400270 /* CombineLatest.swift */; }; + E099A76F2AF38F26409311E143CD92EC /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDE30B01C6DAD0D5FD8C972F98DE288 /* Timeout.swift */; }; + E0A9ED57BC88DF643279F8146984E452 /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68251CF4FE3622BA12120AFDF13FA1C4 /* Do.swift */; }; + E1A94B0C5B6CA70F75CDE21D3B5AC03B /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E724CE2180A86CA9D4D2A7FEF873464B /* Kingfisher-dummy.m */; }; + E36244E8BF4AC941E82DAF16DDF4BBC2 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D559333329A32BD7831F2E45D4FF16A7 /* ConstraintPriorityTarget.swift */; }; + E408A0761AF60EC8947CF34CBACBAF83 /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA6E66779D1E9F9B8001B7D359D02EA /* Completable.swift */; }; + E461634A31671B2A3C2C987D3980899E /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C2E3D4A19A01D0F46AB591C32690E98 /* KFOptionsSetter.swift */; }; + E49F560E9968AD5B0333FB656D6E0454 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 477B069BB8F7AFF056C4DFCDCB34D983 /* Utils.swift */; }; + E4A1B4245A2BA9C2F2F5F5CE2DF9D42B /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D0D84CA1B759F7250F1F55706122246 /* Runtime.swift */; }; + E4DDB40B82C96C4FCB820E5B2ED5EC2F /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4D9CCB4A1A5C3EBC1BF99BDB5F37B /* Queue.swift */; }; + E54654D504A42C24F284A68F87F7671D /* OperationQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43FD0858967BD8005F603DA65EEBD563 /* OperationQueue+Alamofire.swift */; }; + E54F0E7CEDDAC5664A8C83E4686D6CBB /* Observable+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FA35F270AE53C737F4FF7A4879A13B /* Observable+Concurrency.swift */; }; + E8B4B88BF0241821B81503E1BBE639F3 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E0AE7C857ED5E9B5ECF6AD1EED8E82 /* SessionDataTask.swift */; }; + E8BDED8DBAE36031B05D2F2BDF8B72F3 /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F86EDE0DE4C642283ED4E5E4CDFBE0 /* InvocableType.swift */; }; + E8EAADACF3BAE33BDECBC7214EAE9CD2 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EA73D174336145C16B4581B24C09AE /* ConstraintRelatableTarget.swift */; }; + E94BCEDFF9A03206CFEBBE8F3F432C68 /* PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E26F802520E48824E02912593B726AE /* PrimitiveSequence.swift */; }; + E9B4C89E7EB3B27D46AFCA452C3D426F /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74E5079BE8E238BED74E89B731D5157 /* MultipartUpload.swift */; }; + E9BCADF22375CC2F8E6EB4E0B1BC565C /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9DEC06B67A85AA48A2118481BCF5D38 /* Merge.swift */; }; + E9EE1BCFE7318EFF181D763503311830 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09EAE66CA22F356DDEAEC53B2972D9DB /* TVMonogramView+Kingfisher.swift */; }; + EA5FE4B4B3BF04976C37430E4F3721EF /* RxPickerViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D865B2EF3338D285050AFD9717880B6 /* RxPickerViewDelegateProxy.swift */; }; + EC225E6F8AF67896298772E4C76F724D /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A3AEC537D3BE26C51D6045A4BE0659 /* OperationQueueScheduler.swift */; }; + ED1E4EBA6AC82C9BE22E8E05FF04B00F /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0257C7F85074973CEFF9BB412C5B41D /* ConcurrentDispatchQueueScheduler.swift */; }; + EE5C6659976F87DF6888948A75E58F45 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15C5A7079392E548086A0C4C9D64BB20 /* Bag.swift */; }; + EE6C364198A763EBBF49237035D86439 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5264EDC8D0DB10A5282A04C71579F2AC /* ConstraintLayoutGuide.swift */; }; + EE82D9114F96C918AA152FA0B7AA597C /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E79E25C1CD7ABF6BE187033583F968 /* TakeLast.swift */; }; + EE97D2B2E79237770CE018342B9F86E7 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE04B2773B47F444AD15B2D3ED195A0C /* Resource.swift */; }; + EEC150B66BCCD6C80FDA7E4D1975166B /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964EB3E2D2B380D91FE17EA3BD81849A /* DispatchQueue+Alamofire.swift */; }; + EED0FA7D328B5BCC64D1F1A1C07F4F17 /* Completable+AndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F1E6B2FA0343E7E89E81C88CC672A3 /* Completable+AndThen.swift */; }; + EF6DD06709E5EFD67031FF9B5901A827 /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F821FA477D5CBC2A029AB6C504983C90 /* RxTableViewDelegateProxy.swift */; }; + F036F4A375A2DC7D0E02A9FD523B3BEB /* ReplayRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 447E398F3949913B7D8AC3A555E97D6E /* ReplayRelay.swift */; }; + F10586462FB54CEA169A1A7A469A926D /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2FBB746560DC1E971E2EA40E423CDFB /* Debugging.swift */; }; + F17A4CA4664CABB331D39FE902E06843 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9281DB73C863EE56557931C895FA070 /* Alamofire.swift */; }; + F24D06C23DAB2F52A30C886A7A8177C7 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABEBCBC6DFDA3EC47F7B3B22548DAC5 /* ConstraintView.swift */; }; + F2637EBEAB45BA2D52A80EB3BE34D0F0 /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1AE195A397C30921EED304B8BADF132 /* Concat.swift */; }; + F2C817C166B2DE613222C41015A586C9 /* ConstraintMakerPriortizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F257D204D4CB255CCFEDD0564D96D030 /* ConstraintMakerPriortizable.swift */; }; + F2DDF679DF721DDA14A53744DD540092 /* NSSlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08A61FACE4DC58B6D63CDA2105EE1C2F /* NSSlider+Rx.swift */; }; + F343BA4E457FFDB0165492AECAEF0BCC /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885975EFA59BAE09779F812C3088B554 /* ConstraintPriority.swift */; }; + F34578BEEDA58C8BDF8702399A238306 /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E252F71811BA2A0DF5FAEDA77B3D86D /* AddRef.swift */; }; + F3B4A826460EF6A9B19849D1E7AF6A52 /* ControlEvent+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D761FAD304D3B41BD183F4BF6B6CF99 /* ControlEvent+Signal.swift */; }; + F4455C957BC8D1C80898FDC9E0D93465 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */; }; + F4AECC16327D7D58BC13201D44914534 /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7880A9F133272877D5749E9DA11537EB /* ScheduledDisposable.swift */; }; + F5AF27692F3A5C9087F015B5C40A35E7 /* RxTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153B6B55AB85C7976FD527FD7D896CFE /* RxTarget.swift */; }; + F60E2B85B28D1E27FD52F9B0D62A50C8 /* _RXKVOObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EB34FAA6EAA0B3F9D1FDB51584A5A76 /* _RXKVOObserver.m */; }; + F6DA3B5199D0556BBF9D1EFF83ACE7F6 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BF636A803D82E59DA4ADF71F7AA4027 /* SubjectType.swift */; }; + F731500D5D34F172EB459E8ADEE76116 /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803BC476D5564A4FA5CD5F0275CFB254 /* ScheduledItem.swift */; }; + F73ED54E02EC026FB2F7DC28629E1E7C /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BE22EC0538EA1CEC12B1DB18C24A184 /* Generate.swift */; }; + F7774F70F3F7CD7E11F01BD8B62FFF15 /* URLSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B0156512CBF5584A1DB161E180766E1 /* URLSession+Rx.swift */; }; + F789D652321ABC8CADCF962C85B1B80C /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6133281F47EC6817A2F139A120E864AE /* ToArray.swift */; }; + F93C4E366639FD5D2A32446038DD7E60 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923B236039A70B1F88907A3F82BFE2AE /* NopDisposable.swift */; }; + F9821B669566BA01F845426DC6834E76 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 776DFD1F3CBB65E70DE70D6103601433 /* Observable+Bind.swift */; }; + FAF7C9C4F9B6AE2CE9F5866B210D9275 /* SharedSequence+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F28559ECB31ED01EBF30485A89354E9 /* SharedSequence+Operators.swift */; }; + FBD01C51DBA0CD35DA12E49D3A67CB7A /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 770297B28D90456712801DCBAB3F3D4E /* TailRecursiveSink.swift */; }; + FC07184FF229E4890E76F265656AAC27 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35E4ECAE1002E961A1C69F1D04E24EFD /* WKInterfaceImage+Kingfisher.swift */; }; + FC24217137CD93C7004E0FE6C888C711 /* Decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C06A78851D368C99335C77AE88F54C2 /* Decode.swift */; }; + FCD9660A73D7E00EA19E2F2295876E04 /* NSTextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9E473E4E1B5852EBD81E325E2B5C4D /* NSTextView+Rx.swift */; }; + FE9261A1344AF922C1EFCB457B938425 /* BehaviorRelay+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0A095E2B75D2E3DB3B274F8F8A4CF92 /* BehaviorRelay+Driver.swift */; }; + FFE42C0183B7DB7FB6A69CD174BB9A8B /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CA535D550AC90898448FAC2B3E839E8 /* KFImage.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 0B478B41E95A2DC5598F23099F3895FB /* PBXContainerItemProxy */ = { + 173BC9B3F5881CACC0CE1437A920FF38 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; - remoteInfo = Kingfisher; - }; - 81F5647B19920D027D25D5BB99ED534E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; - remoteInfo = RxSwift; + remoteGlobalIDString = 4622BFEF3DC16E8BD15EEFC30D4D0084; + remoteInfo = RxRelay; }; - 854F098BFBDFA3723D6AEF7777467E06 /* PBXContainerItemProxy */ = { + 1D024D715351BD74D6E027FF9CE20970 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 4622BFEF3DC16E8BD15EEFC30D4D0084; remoteInfo = RxRelay; }; - C6BB5C37F54D38D25E46826777F121DC /* PBXContainerItemProxy */ = { + 22A1E6E92313779CBA6A3900B2D0CFE7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; remoteInfo = RxSwift; }; - C7F5300CAF31ED6AFE918DD939CA64D7 /* PBXContainerItemProxy */ = { + 79BFB001A8D6A44190A7FD4F46F046A1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = EAAA1AD3A8A1B59AB91319EE40752C6D; remoteInfo = Alamofire; }; - C836154FF498635455AFF8CCEC9B2B7C /* PBXContainerItemProxy */ = { + 8D7FCB7443BE2C836E75E00DE584C139 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; - remoteInfo = SnapKit; + remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; + remoteInfo = RxSwift; }; - D1C5985FCB75FF02E43174AB01BAC0C1 /* PBXContainerItemProxy */ = { + 93E0660CA03CCFC2E35AEA166761669E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; remoteInfo = RxSwift; }; - D6D10408CDC0FF1FE5DCB07182FCA8E9 /* PBXContainerItemProxy */ = { + 96478020010384C4399E507618699E23 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6; - remoteInfo = RxCocoa; + remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; + remoteInfo = Kingfisher; }; - E50211E3BFDF1DA64DB10E833C1B626E /* PBXContainerItemProxy */ = { + AF3BA24C3AF41AF3F89BF553B16F8FBE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4622BFEF3DC16E8BD15EEFC30D4D0084; - remoteInfo = RxRelay; + remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; + remoteInfo = SnapKit; + }; + C6778CF39955835DA559F05115A4D9BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6; + remoteInfo = RxCocoa; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 002820526DCF691DEE139BFF1455D570 /* Disposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposable.swift; path = RxSwift/Disposable.swift; sourceTree = ""; }; - 004354BDA07A0416EB9F2950BD343B6A /* PrimitiveSequence+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PrimitiveSequence+Zip+arity.swift"; path = "RxSwift/Traits/PrimitiveSequence/PrimitiveSequence+Zip+arity.swift"; sourceTree = ""; }; - 0096AB1EA15E66D9C5112DE4712A1426 /* Producer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Producer.swift; path = RxSwift/Observables/Producer.swift; sourceTree = ""; }; - 01122E4C4E6E936C13650AB5930C1599 /* RxCocoa-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-umbrella.h"; sourceTree = ""; }; - 028879668058DF7CB3068D2F773FC498 /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; - 037BD3F6EA04A1FC02F2B43610E6A808 /* RecursiveScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveScheduler.swift; path = RxSwift/Schedulers/RecursiveScheduler.swift; sourceTree = ""; }; - 03956BA3890ABF298FBA26FBF08B4E67 /* NSButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Rx.swift"; path = "RxCocoa/macOS/NSButton+Rx.swift"; sourceTree = ""; }; - 042A5EC597C796CAE77BFA7517A5593C /* Take.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Take.swift; path = RxSwift/Observables/Take.swift; sourceTree = ""; }; - 04EA0D88E6C540AA57372D94CA178C71 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Source/ConstraintAttributes.swift; sourceTree = ""; }; - 0752E2033E127DDECCBE3EBF5AED6438 /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeConverterType.swift; path = RxSwift/Schedulers/VirtualTimeConverterType.swift; sourceTree = ""; }; - 0798F4AC31E16088DC2EB1526116B10F /* SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SnapKit-Info.plist"; sourceTree = ""; }; - 07F26138B76C48A68119CBAD2AC7F749 /* SubscribeOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscribeOn.swift; path = RxSwift/Observables/SubscribeOn.swift; sourceTree = ""; }; - 08DC1AE8E928801CE8A4CF42E28E6F03 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; - 090F56B03C1EA838E662190E3D064532 /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift; sourceTree = ""; }; - 09F6B34177CDA13EEC9692109D9630D5 /* SwitchIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwitchIfEmpty.swift; path = RxSwift/Observables/SwitchIfEmpty.swift; sourceTree = ""; }; - 0A5F8993766833E3FBAE79C7D917DA71 /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Source/ConstraintViewDSL.swift; sourceTree = ""; }; - 0A895508CA44EE9BFFB139EBD5DCA92E /* RxCocoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoa.h; path = RxCocoa/RxCocoa.h; sourceTree = ""; }; - 0C240573DDD75AB5F81D423C5E2EFA0A /* ObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableType.swift; path = RxSwift/ObservableType.swift; sourceTree = ""; }; - 0C44F364482EB4F6905DAF107341E243 /* _RXObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXObjCRuntime.h; path = RxCocoa/Runtime/include/_RXObjCRuntime.h; sourceTree = ""; }; - 0C8E0DF3B5987F629AE2237546036058 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; - 0CA874964DCD7DA61F687EC29CF0182D /* Throttle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Throttle.swift; path = RxSwift/Observables/Throttle.swift; sourceTree = ""; }; - 0CFD4EB1A0879E8DE5C3EE9C693DAA55 /* MainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MainScheduler.swift; path = RxSwift/Schedulers/MainScheduler.swift; sourceTree = ""; }; - 0D75B4BD74A428B33BC3091D935894D4 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; - 0E7DB5BA65C1FFABAEC78D90F6FDC6C8 /* CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+arity.swift"; path = "RxSwift/Observables/CombineLatest+arity.swift"; sourceTree = ""; }; - 0E9B3BDCF2E5186E2849A421BD65BA04 /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Source/ConstraintMultiplierTarget.swift; sourceTree = ""; }; - 0FAF398D151AA3B4AE228DC8266D3719 /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Source/ConstraintItem.swift; sourceTree = ""; }; - 12098C2818AEF2B5F2BF1C8B8C14E647 /* RxSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.debug.xcconfig; sourceTree = ""; }; - 129BE48ECDE18236FCECEFF00958A22E /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; - 12C4D9B07775F92146D1E794C6D3572B /* ServerTrustEvaluation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustEvaluation.swift; path = Source/ServerTrustEvaluation.swift; sourceTree = ""; }; - 13717D0A33898D0C1E1121E04A69AACF /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; - 141B4D876D24D86E863F48BAC657EBC7 /* RxTableViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift; sourceTree = ""; }; - 1486B81E13CE29D01C4B7BB2C76A9BF8 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; - 149A0E263DF818421EFE73AA49E3FEC2 /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; - 1500F0CCD24A6A49C7EB584E63BCF842 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; - 152DA282A487530C176A0B25C8DF6883 /* DisposeBag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBag.swift; path = RxSwift/Disposables/DisposeBag.swift; sourceTree = ""; }; - 1695D8C618F845EEE48F2BB9379A7BF4 /* Event.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Event.swift; path = RxSwift/Event.swift; sourceTree = ""; }; - 1797BF7FAA53FCA78CC60F983304176D /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; - 17C9BA669A8F668C0A88722EACEF84AF /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; - 18D10CFF2702506F9BC66AFA9CB1A285 /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Source/ConstraintRelation.swift; sourceTree = ""; }; - 191B10FB8FC2B7DDBC84A8208CA00B22 /* Pods-Bunjang.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Bunjang.debug.xcconfig"; sourceTree = ""; }; - 1A52FCBFBDBFDA727757BADAC2FE4D7D /* Maybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Maybe.swift; path = RxSwift/Traits/PrimitiveSequence/Maybe.swift; sourceTree = ""; }; - 1A988A7455383F560A9BBAA36315E494 /* RxSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-umbrella.h"; sourceTree = ""; }; - 1D335E71CC0ADA589EE65F467A506799 /* AsMaybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsMaybe.swift; path = RxSwift/Observables/AsMaybe.swift; sourceTree = ""; }; - 1D441519852483871764E8CCA75F4A95 /* KF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KF.swift; path = Sources/General/KF.swift; sourceTree = ""; }; - 1D7705F997A86550CBD50E3A0EF7D891 /* Result+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Result+Alamofire.swift"; path = "Source/Result+Alamofire.swift"; sourceTree = ""; }; - 1D83223BDC370C77F9850BB2A6C8742F /* SectionedViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SectionedViewDataSourceType.swift; path = RxCocoa/Common/SectionedViewDataSourceType.swift; sourceTree = ""; }; - 1D8BAA943C277F25473B01F1832BA866 /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; - 1E90FF704D8B7C423ED6AF884FEC88E6 /* RxSearchBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift; sourceTree = ""; }; - 1ED812CC3A0ED3E6BCCFCA3EA27368A3 /* Binder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Binder.swift; path = RxSwift/Binder.swift; sourceTree = ""; }; - 1F6D4CBB22DC0338D091547BC40AA631 /* NSObject+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx.swift"; path = "RxCocoa/Foundation/NSObject+Rx.swift"; sourceTree = ""; }; - 1FB0AB5EBB9EAF18968D0715DC6473EF /* AnyObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyObserver.swift; path = RxSwift/AnyObserver.swift; sourceTree = ""; }; - 216434676B68D96B04E6DDDA0D1D5A83 /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; - 229AF565F8AF87313E01A4E75691BF96 /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; - 22FC7E45CD1650C4C37F3C8C97FA02F7 /* HTTPHeaders.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPHeaders.swift; path = Source/HTTPHeaders.swift; sourceTree = ""; }; - 2395D2D816592B47A30CF5C10787ECC7 /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = RxSwift/Observables/Error.swift; sourceTree = ""; }; - 241D7299EBA5825B66091F231253D7E1 /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; - 243B068FE5F3750321AB4D1D90CDF047 /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Source/ConstraintMaker.swift; sourceTree = ""; }; - 2453D0762FE79905E9AA9C5F5C3A5E75 /* GroupedObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupedObservable.swift; path = RxSwift/GroupedObservable.swift; sourceTree = ""; }; - 2466F41844E51F2D29DFCDEE4E4AD3C5 /* RequestInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestInterceptor.swift; path = Source/RequestInterceptor.swift; sourceTree = ""; }; - 24DE341833137F7E412379EA3C5B44B6 /* Pods-Bunjang.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Bunjang.modulemap"; sourceTree = ""; }; - 267A04DBC3322B5D3D8402EC66199CD1 /* Catch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Catch.swift; path = RxSwift/Observables/Catch.swift; sourceTree = ""; }; - 284D083D86D8F6BDAA4B8916E8986BAB /* _RX.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RX.h; path = RxCocoa/Runtime/include/_RX.h; sourceTree = ""; }; - 28F3AB7D268A9352EE6910E3C8DCC29D /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Source/Constraint.swift; sourceTree = ""; }; - 2A38E734191D770256D5CA30A7EB1BFE /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscriptionDisposable.swift; path = RxSwift/Disposables/SubscriptionDisposable.swift; sourceTree = ""; }; - 2A57FC897450D14CF6F70161A3AB95BC /* Session.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Session.swift; path = Source/Session.swift; sourceTree = ""; }; - 2A91950D5DC29F11BD39F3AD4EE89E6B /* NopDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NopDisposable.swift; path = RxSwift/Disposables/NopDisposable.swift; sourceTree = ""; }; - 2B7CB3FCA9A4B086818B0611E2E9A449 /* RxRelay.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.debug.xcconfig; sourceTree = ""; }; - 2BF9BDC107FFB51F0879071F69E589A6 /* Observable+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Concurrency.swift"; path = "RxSwift/Observable+Concurrency.swift"; sourceTree = ""; }; - 2C0272514C0FECA114FCAA610EC7667C /* ObservableConvertibleType+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Signal.swift"; path = "RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift"; sourceTree = ""; }; - 2C0944E5F4EFFF24A475580B10825367 /* Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signal.swift; path = RxCocoa/Traits/Signal/Signal.swift; sourceTree = ""; }; - 2C3BE0AFF952A3AAA8373E044BBADAE7 /* StartWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StartWith.swift; path = RxSwift/Observables/StartWith.swift; sourceTree = ""; }; - 2C59DF271C27008DD3524AB8E849C53F /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; }; - 2D5BA2237796BAC05B2E72B417F5A80A /* NSSlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSSlider+Rx.swift"; path = "RxCocoa/macOS/NSSlider+Rx.swift"; sourceTree = ""; }; - 2D76A603A5E56D14C1699BCAF85E537B /* ControlProperty+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlProperty+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlProperty+Driver.swift"; sourceTree = ""; }; - 2D8EBCDD6EB54DCDDCA65563CF324CDA /* BooleanDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BooleanDisposable.swift; path = RxSwift/Disposables/BooleanDisposable.swift; sourceTree = ""; }; - 2DA4834DA4941D7863F0CBE2128F1621 /* UISwitch+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISwitch+Rx.swift"; path = "RxCocoa/iOS/UISwitch+Rx.swift"; sourceTree = ""; }; - 2E679291E767C8D0045D70F6E1FE6558 /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; - 2FE7855AE606E5E11D3FBFEB5F9269BD /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; - 30D6A0775465C48A70C1EEAA247354EC /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; - 31A72DC794794857921D83CFBABFD01B /* Dematerialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Dematerialize.swift; path = RxSwift/Observables/Dematerialize.swift; sourceTree = ""; }; - 3212B74DA6E8E30143526455790A11A7 /* NotificationCenter+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NotificationCenter+Rx.swift"; path = "RxCocoa/Foundation/NotificationCenter+Rx.swift"; sourceTree = ""; }; - 32193DD28EB90453567A59F1A182F96D /* Infallible+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Operators.swift"; path = "RxSwift/Traits/Infallible/Infallible+Operators.swift"; sourceTree = ""; }; - 348AE3FD864F7622AB84B36307F89F84 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; }; - 34CB6D05E236E726EBA220EB8AD8AB58 /* _RX.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RX.m; path = RxCocoa/Runtime/_RX.m; sourceTree = ""; }; - 34F34C3DFEA45CA618A7BD11A7ED48D9 /* AsyncSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncSubject.swift; path = RxSwift/Subjects/AsyncSubject.swift; sourceTree = ""; }; - 359E0E617AC6252C020ECD81C27A0569 /* _RXDelegateProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXDelegateProxy.m; path = RxCocoa/Runtime/_RXDelegateProxy.m; sourceTree = ""; }; - 35A5A6316F990C77C6D3727171BDF348 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; - 3612035A1538C3A1A8AF7D1DBB4D0184 /* RxNavigationControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxNavigationControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift; sourceTree = ""; }; - 3838BCB07EFD1D203AA7CCD91DE9C2E5 /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; - 38F45BA184E5E0716F4908F767BD7B3A /* TakeLast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeLast.swift; path = RxSwift/Observables/TakeLast.swift; sourceTree = ""; }; - 390343B0F0437A9ED750B8657080C49C /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = RxRelay/Utils.swift; sourceTree = ""; }; - 39921C9633DF11B9BEB63A732BCC0FDB /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; - 39B2E58EF22EE740478AB6EAD4AA54A3 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; - 3B96619905B442A12C1F2C65DCC72F9D /* Sequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sequence.swift; path = RxSwift/Observables/Sequence.swift; sourceTree = ""; }; - 3C14E0A58AD2EA6A4DE08C97BD42AC5D /* RxCocoa-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxCocoa-Info.plist"; sourceTree = ""; }; - 3C18A26F23ECE9BE8D5B1A6A198A0600 /* RxRelay.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.release.xcconfig; sourceTree = ""; }; - 3CE28AA56B38DACFBC04F7C8F4EA5984 /* Optional.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Optional.swift; path = RxSwift/Observables/Optional.swift; sourceTree = ""; }; - 3D36596C01773C3C3FC96979AD8726C1 /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Source/ConstraintMakerRelatable.swift; sourceTree = ""; }; - 3DFD8B7C287CE97937818BB36E6D0F7C /* Deferred.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deferred.swift; path = RxSwift/Observables/Deferred.swift; sourceTree = ""; }; - 3E18733EF8F0BF82670E3C3E41AD6A82 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedDisposeType.swift; path = RxSwift/Concurrency/SynchronizedDisposeType.swift; sourceTree = ""; }; - 3F04911873952BD6300007242C0F1EF4 /* SharedSequence+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Concurrency.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Concurrency.swift"; sourceTree = ""; }; - 3F080CD3AE644C4BB12664E9BE553B42 /* UIButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Rx.swift"; path = "RxCocoa/iOS/UIButton+Rx.swift"; sourceTree = ""; }; - 3F5D93D2A26CF9078B252BF264AABC60 /* UISearchController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchController+Rx.swift"; path = "RxCocoa/iOS/UISearchController+Rx.swift"; sourceTree = ""; }; - 406336451769C4ABD13D928D18C358F6 /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalSchedulerTimeConverter.swift; path = RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift; sourceTree = ""; }; - 410747E8F9D1164844C9D33F86671DD5 /* TakeWithPredicate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeWithPredicate.swift; path = RxSwift/Observables/TakeWithPredicate.swift; sourceTree = ""; }; - 412E7CB493D9A51E0BEB16EEB73977AE /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; - 4169B421DBD9C0157729FCA9836C9DAE /* Empty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Empty.swift; path = RxSwift/Observables/Empty.swift; sourceTree = ""; }; + 0027F0EFDE7EF07B89CC7DD7A26BBC04 /* PublishRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishRelay.swift; path = RxRelay/PublishRelay.swift; sourceTree = ""; }; + 005BC5B30DAB73C72CFA4D0B90F85194 /* Enumerated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Enumerated.swift; path = RxSwift/Observables/Enumerated.swift; sourceTree = ""; }; + 02DD5108531A657F7454879387DFB795 /* TakeWithPredicate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeWithPredicate.swift; path = RxSwift/Observables/TakeWithPredicate.swift; sourceTree = ""; }; + 03631B268C3CCC37CED157024CF4D3DD /* ControlProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlProperty.swift; path = RxCocoa/Traits/ControlProperty.swift; sourceTree = ""; }; + 052B51BC168C7D6CF8335F93AF4A67A5 /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDispatchQueueScheduler.swift; path = RxSwift/Schedulers/SerialDispatchQueueScheduler.swift; sourceTree = ""; }; + 054144A7760E716E29603EEDFFBA5AFF /* Protected.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Source/Protected.swift; sourceTree = ""; }; + 05A3AEC537D3BE26C51D6045A4BE0659 /* OperationQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OperationQueueScheduler.swift; path = RxSwift/Schedulers/OperationQueueScheduler.swift; sourceTree = ""; }; + 06041DE6F931C543695D7F87CD91C6C9 /* RxPickerViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift; sourceTree = ""; }; + 06D41EF68321F25F5DF29DCA66512232 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; + 0765B4EEB54FAC58B8234A058FA33E51 /* KVORepresentable+CoreGraphics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+CoreGraphics.swift"; path = "RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift"; sourceTree = ""; }; + 078321DA8756A79AA1EBDF1D3DFBA9BB /* ObserverBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverBase.swift; path = RxSwift/Observers/ObserverBase.swift; sourceTree = ""; }; + 07A793D684FC253E04E29A6CA931906E /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift; sourceTree = ""; }; + 0846BC731037DE3BA116292847C91021 /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeScheduler.swift; path = RxSwift/Schedulers/VirtualTimeScheduler.swift; sourceTree = ""; }; + 08A61FACE4DC58B6D63CDA2105EE1C2F /* NSSlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSSlider+Rx.swift"; path = "RxCocoa/macOS/NSSlider+Rx.swift"; sourceTree = ""; }; + 09EAE66CA22F356DDEAEC53B2972D9DB /* TVMonogramView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TVMonogramView+Kingfisher.swift"; path = "Sources/Extensions/TVMonogramView+Kingfisher.swift"; sourceTree = ""; }; + 0ABFB7BA27AE26BFEFF3BA732CACE191 /* Pods-GenderList */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-GenderList"; path = Pods_GenderList.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 0B50EE591E7052D97A3A53393B0232A6 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; }; + 0B5A237F228CBE682B896D5145A8F585 /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; + 0C06A78851D368C99335C77AE88F54C2 /* Decode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Decode.swift; path = RxSwift/Observables/Decode.swift; sourceTree = ""; }; + 0C2E3D4A19A01D0F46AB591C32690E98 /* KFOptionsSetter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFOptionsSetter.swift; path = Sources/General/KFOptionsSetter.swift; sourceTree = ""; }; + 0C4870B4A362118D2BB176E9219C5BB1 /* Optional.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Optional.swift; path = RxSwift/Observables/Optional.swift; sourceTree = ""; }; + 0C646DE8A55223D410F9282227BBE415 /* Materialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Materialize.swift; path = RxSwift/Observables/Materialize.swift; sourceTree = ""; }; + 0CB614DA2D2E0151F1A14D72578F6B1B /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDatePicker+Rx.swift"; path = "RxCocoa/iOS/UIDatePicker+Rx.swift"; sourceTree = ""; }; + 0D7B5A7AD167A4C224BA967C65613F9E /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; + 0E4604F79F3B7F16F870C0140292283C /* UIScrollView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIScrollView+Rx.swift"; path = "RxCocoa/iOS/UIScrollView+Rx.swift"; sourceTree = ""; }; + 0E5E13511F0AF2F8A7C637D0B1E5CE61 /* Reactive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reactive.swift; path = RxSwift/Reactive.swift; sourceTree = ""; }; + 0E7AF374BE13CA7EF6CEF091D12B06E2 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; }; + 0E98055623D69273DF17B778130628B8 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscriptionDisposable.swift; path = RxSwift/Disposables/SubscriptionDisposable.swift; sourceTree = ""; }; + 0F0123AEE5FF35F7AC3D76D8ABBF3F69 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; + 1022AEF0BFB392161D650BF9E00A3D8F /* StringEncoding+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StringEncoding+Alamofire.swift"; path = "Source/StringEncoding+Alamofire.swift"; sourceTree = ""; }; + 1040B8497C8CA28E0B37F77BDC2744F2 /* BinaryDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDisposable.swift; path = RxSwift/Disposables/BinaryDisposable.swift; sourceTree = ""; }; + 10D5ADFC37FC97F51CA8E4B68AC314C9 /* NSObject+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx.swift"; path = "RxCocoa/Foundation/NSObject+Rx.swift"; sourceTree = ""; }; + 10DBF9FA38BA3CFBEB34E19F6953E864 /* DisposeBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBase.swift; path = RxSwift/Disposables/DisposeBase.swift; sourceTree = ""; }; + 1156F9304249B4AC44D03B40EB30F69A /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; + 11B01A2390CA2DDDD676D1A67BD0C02D /* UITextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextView+Rx.swift"; path = "RxCocoa/iOS/UITextView+Rx.swift"; sourceTree = ""; }; + 148FCE152B9AD264C77EA952ACA5B376 /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; + 15311C960C78890DFEF8D4F4193F6359 /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; + 153B6B55AB85C7976FD527FD7D896CFE /* RxTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTarget.swift; path = RxCocoa/Common/RxTarget.swift; sourceTree = ""; }; + 15C5A7079392E548086A0C4C9D64BB20 /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; + 16207E1B4EEA0AF791AE4F11AF03C42A /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+Collection.swift"; path = "RxSwift/Observables/CombineLatest+Collection.swift"; sourceTree = ""; }; + 165933865EF401961B5BB6932BC66E8C /* SingleAsync.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAsync.swift; path = RxSwift/Observables/SingleAsync.swift; sourceTree = ""; }; + 177EDA0B76DEF69DB8E291B1F864EE04 /* SchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SchedulerType.swift; path = RxSwift/SchedulerType.swift; sourceTree = ""; }; + 17C579C36CDD6CF5A9A0BB547AA750D5 /* Zip+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+Collection.swift"; path = "RxSwift/Observables/Zip+Collection.swift"; sourceTree = ""; }; + 18D8E8D89BA483ED17D2EFDD71921594 /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; + 18DCE52506087CF4CC559E58DD403801 /* AsyncSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncSubject.swift; path = RxSwift/Subjects/AsyncSubject.swift; sourceTree = ""; }; + 191771D857A79C686B98B8202157674F /* UISegmentedControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISegmentedControl+Rx.swift"; path = "RxCocoa/iOS/UISegmentedControl+Rx.swift"; sourceTree = ""; }; + 19DF06221A11CCCC94FF2CFB37647CDD /* Observable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Observable.swift; path = RxSwift/Observable.swift; sourceTree = ""; }; + 1AA261BD733B0E7D34A8B8C53BAF08E5 /* AuthenticationInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationInterceptor.swift; path = Source/AuthenticationInterceptor.swift; sourceTree = ""; }; + 1ABEBCBC6DFDA3EC47F7B3B22548DAC5 /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Source/ConstraintView.swift; sourceTree = ""; }; + 1B43583C37157540C0BAC4B4E7AEA76A /* ConstraintDirectionalInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsetTarget.swift; path = Source/ConstraintDirectionalInsetTarget.swift; sourceTree = ""; }; + 1BF143D5E04FC312AF48745F2677C319 /* Infallible+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Create.swift"; path = "RxSwift/Traits/Infallible/Infallible+Create.swift"; sourceTree = ""; }; + 1CEC7002B9A3286DF431B186F07F0E50 /* Scan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Scan.swift; path = RxSwift/Observables/Scan.swift; sourceTree = ""; }; + 1E8EEC36578F8DBF0309DD73B87D4329 /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+KVORepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; }; + 1EA0DB41F8746732351623A4D6285F83 /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIBarButtonItem+Rx.swift"; path = "RxCocoa/iOS/UIBarButtonItem+Rx.swift"; sourceTree = ""; }; + 1FFFAEA9D04F0A584135382514690C3C /* Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Infallible.swift; path = RxSwift/Traits/Infallible/Infallible.swift; sourceTree = ""; }; + 20804B3A6BAEA5B63222084242339F53 /* RxCocoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoa.h; path = RxCocoa/RxCocoa.h; sourceTree = ""; }; + 22728DB59B0890DE4D0BFC938A5E5319 /* AsMaybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsMaybe.swift; path = RxSwift/Observables/AsMaybe.swift; sourceTree = ""; }; + 22955779FC97B3947D45B4CA2A3C5926 /* ObservableType+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+Extensions.swift"; path = "RxSwift/ObservableType+Extensions.swift"; sourceTree = ""; }; + 22F549E90893E8656AD2EEF4F9779A50 /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DistinctUntilChanged.swift; path = RxSwift/Observables/DistinctUntilChanged.swift; sourceTree = ""; }; + 230C05CE94222C563407E135A09FE52B /* UISwitch+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISwitch+Rx.swift"; path = "RxCocoa/iOS/UISwitch+Rx.swift"; sourceTree = ""; }; + 2424AF78DDEE23C54679665B2E11CECA /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; + 25AA7B62A9465F5790FFF2F2F453B872 /* AsSingle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsSingle.swift; path = RxSwift/Observables/AsSingle.swift; sourceTree = ""; }; + 26ADDE7E696F04B30C9DC8A393455CC5 /* Reduce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reduce.swift; path = RxSwift/Observables/Reduce.swift; sourceTree = ""; }; + 276D3909A04A45FFEFE39B92A608A913 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; + 2898579A8710C12A1F5B70B4A455D8F6 /* Disposables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposables.swift; path = RxSwift/Disposables/Disposables.swift; sourceTree = ""; }; + 291F7C069F9E079F932FDD60D8FEFA7D /* KVORepresentable+Swift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+Swift.swift"; path = "RxCocoa/Foundation/KVORepresentable+Swift.swift"; sourceTree = ""; }; + 29A8D5E730EDA418197D591546FAB0A8 /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CurrentThreadScheduler.swift; path = RxSwift/Schedulers/CurrentThreadScheduler.swift; sourceTree = ""; }; + 2A132226945BC922F96DF66A1385592F /* Repeat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Repeat.swift; path = RxSwift/Observables/Repeat.swift; sourceTree = ""; }; + 2AA689679D51D3F44B5448DA52B49346 /* NSButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Rx.swift"; path = "RxCocoa/macOS/NSButton+Rx.swift"; sourceTree = ""; }; + 2B267869B6FE5FC5CB863F860C1C1FAD /* RxRelay.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.debug.xcconfig; sourceTree = ""; }; + 2B6F7B84E077EC3DDF3056FF8349A606 /* Pods-GenderList-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GenderList-frameworks.sh"; sourceTree = ""; }; + 2B8F16D2904D429E2EF80FBC37D8B531 /* Throttle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Throttle.swift; path = RxSwift/Observables/Throttle.swift; sourceTree = ""; }; + 2BE01FA5A76FD95281BCF21AB650B8E0 /* ShareReplayScope.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ShareReplayScope.swift; path = RxSwift/Observables/ShareReplayScope.swift; sourceTree = ""; }; + 2BE22EC0538EA1CEC12B1DB18C24A184 /* Generate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generate.swift; path = RxSwift/Observables/Generate.swift; sourceTree = ""; }; + 2C76BFDCF0D1D12711765650CA1E6C6F /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; + 2D2324A70BFC56DC0C74F69EC2072986 /* UIApplication+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIApplication+Rx.swift"; path = "RxCocoa/iOS/UIApplication+Rx.swift"; sourceTree = ""; }; + 2D956866F9C4CFFCB478A2F597636FEC /* RxRelay-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-umbrella.h"; sourceTree = ""; }; + 2E0A84821DDFA668496084FB50DA7526 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; + 2E65E3AAF488477C388FE9A469DDD299 /* ObservableConvertibleType+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Signal.swift"; path = "RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift"; sourceTree = ""; }; + 2EB34FAA6EAA0B3F9D1FDB51584A5A76 /* _RXKVOObserver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXKVOObserver.m; path = RxCocoa/Runtime/_RXKVOObserver.m; sourceTree = ""; }; + 3161196A1725FB042806502C2CEC58A9 /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Source/ConstraintRelation.swift; sourceTree = ""; }; + 31BB1AECA99796B254CE53707A66D22E /* SectionedViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SectionedViewDataSourceType.swift; path = RxCocoa/Common/SectionedViewDataSourceType.swift; sourceTree = ""; }; + 328871EC5F47DC34D9B0224D74DA7E30 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; + 32AA4A86EE5313C95E3669CE9DA5FDC8 /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; + 33267D6278C73D35763DC6851211D419 /* KFImageOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageOptions.swift; path = Sources/SwiftUI/KFImageOptions.swift; sourceTree = ""; }; + 33BA2B6551160A572CB11661696B838A /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; + 34A4D9CCB4A1A5C3EBC1BF99BDB5F37B /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; + 3578A3CC608B05A5F1CD876FDAE5D161 /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Source/ConstraintMultiplierTarget.swift; sourceTree = ""; }; + 35E4ECAE1002E961A1C69F1D04E24EFD /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; + 385B3A35B5E22B7F48613B00712041DF /* PrimitiveSequence+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PrimitiveSequence+Zip+arity.swift"; path = "RxSwift/Traits/PrimitiveSequence/PrimitiveSequence+Zip+arity.swift"; sourceTree = ""; }; + 38AC16752A18BFD36B7F4F543811879B /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableConvertibleType.swift; path = RxSwift/ObservableConvertibleType.swift; sourceTree = ""; }; + 38E3773C87AB71FEFF099FBBC70AB837 /* NotificationCenter+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NotificationCenter+Rx.swift"; path = "RxCocoa/Foundation/NotificationCenter+Rx.swift"; sourceTree = ""; }; + 399CC3775BA27EDBA362F6F43A379F61 /* RxRelay.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxRelay.modulemap; sourceTree = ""; }; + 39AD7A483064C6E2459F057D93C37603 /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; + 39F4864853C931D994403E262406562F /* SchedulerServices+Emulation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerServices+Emulation.swift"; path = "RxSwift/Schedulers/SchedulerServices+Emulation.swift"; sourceTree = ""; }; + 3A464E4AFB2F136E06330E8CDEE738CC /* Sample.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sample.swift; path = RxSwift/Observables/Sample.swift; sourceTree = ""; }; + 3AFFFA4F985B09306F6EB74771AA77D9 /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; + 3C52DCC8578844B8C5AFEC3E61FC07D3 /* Pods-GenderList-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GenderList-acknowledgements.markdown"; sourceTree = ""; }; + 3CBE52AF7E852F29CE60E348DA19F51F /* Single.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Single.swift; path = RxSwift/Traits/PrimitiveSequence/Single.swift; sourceTree = ""; }; + 3CE870C8AB56EBCF98D6D45D93FC0603 /* RxCollectionViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; + 3D1E04658D6282D9191364B13B66A898 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; + 3E502569324A3191D2009A6E9CD8CAF3 /* Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signal.swift; path = RxCocoa/Traits/Signal/Signal.swift; sourceTree = ""; }; + 3F31398DA34BA86AB6669FCF1628199E /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentMainScheduler.swift; path = RxSwift/Schedulers/ConcurrentMainScheduler.swift; sourceTree = ""; }; + 3F77858A4515CB188A0008E88C302846 /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; + 3FE0EBD2D580EC665875B83BE0B38369 /* Buffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Buffer.swift; path = RxSwift/Observables/Buffer.swift; sourceTree = ""; }; + 408F9B427B8BCFDAF73895D578D2FF5C /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; + 41D6582E0936ACC2199801C4FE13E4DD /* DefaultIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DefaultIfEmpty.swift; path = RxSwift/Observables/DefaultIfEmpty.swift; sourceTree = ""; }; 4207BEE6DFA63E5CF69828DD467E9674 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 420B4C2C25E8A2AF22506AAC158F2AD3 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; - 42216AFFF59E357B6AF1F1378A785AFF /* KFOptionsSetter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFOptionsSetter.swift; path = Sources/General/KFOptionsSetter.swift; sourceTree = ""; }; - 44272824E10DE63C3D91E362DAC954CE /* Scan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Scan.swift; path = RxSwift/Observables/Scan.swift; sourceTree = ""; }; - 44404E8C9D38627A655B2CEC007AAA80 /* UIRefreshControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIRefreshControl+Rx.swift"; path = "RxCocoa/iOS/UIRefreshControl+Rx.swift"; sourceTree = ""; }; - 446ACEEA7E8F01C4AE5F13F8715B075D /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; - 448120BB0477A55852FA955184FE5616 /* Timer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timer.swift; path = RxSwift/Observables/Timer.swift; sourceTree = ""; }; - 44BED1C4650C3E0D28DE12A7A809D753 /* Pods-Bunjang.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Bunjang.release.xcconfig"; sourceTree = ""; }; - 45740A99F06B13415E6AB7855CA64512 /* Pods-Bunjang-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Bunjang-umbrella.h"; sourceTree = ""; }; - 462935E91ED59AF6B20ADE9631564D6B /* RxCocoa-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxCocoa-dummy.m"; sourceTree = ""; }; - 46DDD7887D41973B96666E7A02C9ABF7 /* URLConvertible+URLRequestConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLConvertible+URLRequestConvertible.swift"; path = "Source/URLConvertible+URLRequestConvertible.swift"; sourceTree = ""; }; - 479AC0D0C5CE3FD96E9568934D3C050F /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; - 4825BC57D4C56DC940BC05B110A6178F /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; - 48C6D9986152A06D2ADC0063B133E754 /* RxPickerViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift; sourceTree = ""; }; - 491640A78DA05BC89FD9699B3EEA4931 /* RxSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-prefix.pch"; sourceTree = ""; }; - 491B41F720BE34BE7F38E64B20E5F772 /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; - 492C5CAD0304480DBF304ACC718D8A62 /* NSView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSView+Rx.swift"; path = "RxCocoa/macOS/NSView+Rx.swift"; sourceTree = ""; }; - 49309CED1FF1518FC6DA6FB30AED2314 /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Source/ConstraintInsets.swift; sourceTree = ""; }; - 4932F8F6F0A427742452AC9CF0D58C77 /* BinaryDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDisposable.swift; path = RxSwift/Disposables/BinaryDisposable.swift; sourceTree = ""; }; - 49867C97EAB05F3879541A4853891A4B /* Never.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Never.swift; path = RxSwift/Observables/Never.swift; sourceTree = ""; }; - 49961095D3E6AA7114010352F9D8D866 /* ToArray.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToArray.swift; path = RxSwift/Observables/ToArray.swift; sourceTree = ""; }; - 49D2664CB995F0C4C70CC1ABB49CC79A /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; - 4A70846FD158CE4ABA153F2AB82F1051 /* RetryWhen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryWhen.swift; path = RxSwift/Observables/RetryWhen.swift; sourceTree = ""; }; - 4B1D5E99178DC6039AA64BA30DEC3D54 /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; }; - 4C0AC7C0A13AE44CF85E744BFD4FB822 /* Pods-Bunjang-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Bunjang-acknowledgements.markdown"; sourceTree = ""; }; - 4C3315AD200F0B9AD525D212C0C41504 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxRelay/Observable+Bind.swift"; sourceTree = ""; }; - 4EE696321DE0FE56CB61C37952EE0F2A /* ScheduledItemType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItemType.swift; path = RxSwift/Schedulers/Internal/ScheduledItemType.swift; sourceTree = ""; }; - 4FDE8944CE97206B2673253F9C20298B /* ObserveOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOn.swift; path = RxSwift/Observables/ObserveOn.swift; sourceTree = ""; }; - 501297031677D31F36A769809D7584A1 /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; - 509C092A271A374B7335A91F29349033 /* ShareReplayScope.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ShareReplayScope.swift; path = RxSwift/Observables/ShareReplayScope.swift; sourceTree = ""; }; - 517A605109B9601443F76406285A2E74 /* RxRelay-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxRelay-dummy.m"; sourceTree = ""; }; - 5240A0E2DBF5D9ECEF0F5D53B084DDF2 /* Do.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Do.swift; path = RxSwift/Observables/Do.swift; sourceTree = ""; }; - 5250B99AAE6D169C5028D00075D20CBA /* Sample.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sample.swift; path = RxSwift/Observables/Sample.swift; sourceTree = ""; }; + 425F7E64E335FA34B416F1317A984EEB /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Source/RedirectHandler.swift; sourceTree = ""; }; + 42663476A9313F46565756E7E95ED5AB /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; + 42B9A7E0A2CEEFFF576B51280B8D3A4B /* NSTextStorage+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextStorage+Rx.swift"; path = "RxCocoa/iOS/NSTextStorage+Rx.swift"; sourceTree = ""; }; + 42BFDE3D268FD1437C5660BC87A65B82 /* Lock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Lock.swift; path = RxSwift/Concurrency/Lock.swift; sourceTree = ""; }; + 433B692C89197DA2819292E7CB2E4ACD /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; + 438DCEC5FA002C1C232C8B944C833102 /* First.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = First.swift; path = RxSwift/Observables/First.swift; sourceTree = ""; }; + 43A399BE3081439D0BFC62B91BF9FC4F /* RetryWhen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryWhen.swift; path = RxSwift/Observables/RetryWhen.swift; sourceTree = ""; }; + 43EF4A1F3526BE0CAA711E9BD807894D /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; + 43FD0858967BD8005F603DA65EEBD563 /* OperationQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "OperationQueue+Alamofire.swift"; path = "Source/OperationQueue+Alamofire.swift"; sourceTree = ""; }; + 441B4B5DF69FFFA7DADD198084C7105C /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Source/ConstraintDescription.swift; sourceTree = ""; }; + 444654C800FF5388EA6EAFCE09425593 /* KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVORepresentable.swift; path = RxCocoa/Foundation/KVORepresentable.swift; sourceTree = ""; }; + 447E398F3949913B7D8AC3A555E97D6E /* ReplayRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplayRelay.swift; path = RxRelay/ReplayRelay.swift; sourceTree = ""; }; + 450683C53D82531C94866107D76A268D /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; + 45ED0DD251CA18C7D67361199D5DE10F /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; + 460CC31FF924BBE87297386FE46558DC /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; }; + 470BE4027F92B24DB7E235EC209D70DC /* RxRelay-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxRelay-Info.plist"; sourceTree = ""; }; + 4724C270B204A600A8253615CC123F48 /* TextInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextInput.swift; path = RxCocoa/Common/TextInput.swift; sourceTree = ""; }; + 475798275244D376C942E726734ADF1F /* URLConvertible+URLRequestConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLConvertible+URLRequestConvertible.swift"; path = "Source/URLConvertible+URLRequestConvertible.swift"; sourceTree = ""; }; + 477B069BB8F7AFF056C4DFCDCB34D983 /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = RxRelay/Utils.swift; sourceTree = ""; }; + 48D2E9A71B82298E7CEB37848357F768 /* SwitchIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwitchIfEmpty.swift; path = RxSwift/Observables/SwitchIfEmpty.swift; sourceTree = ""; }; + 490A189B6330719AAC1C4AFFF3A4A3F7 /* HistoricalScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalScheduler.swift; path = RxSwift/Schedulers/HistoricalScheduler.swift; sourceTree = ""; }; + 49839FCD719095B1D043C2DB596E3B40 /* RxTabBarControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift; sourceTree = ""; }; + 4B9DA6D679DB4EFF3EB7A39361C177AB /* Pods-GenderList-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GenderList-Info.plist"; sourceTree = ""; }; + 4BFB8D4A76E253CF05CFDE137052A178 /* Pods-GenderList.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GenderList.debug.xcconfig"; sourceTree = ""; }; + 4C103FEEAA25720139580FD379B94F4C /* Zip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zip.swift; path = RxSwift/Observables/Zip.swift; sourceTree = ""; }; + 4C9E473E4E1B5852EBD81E325E2B5C4D /* NSTextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextView+Rx.swift"; path = "RxCocoa/macOS/NSTextView+Rx.swift"; sourceTree = ""; }; + 4CE5751604115D39C388D1C4A1612A40 /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; }; + 4CFA9A617FFE3AADE8D62793D1CFD5C6 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedDisposeType.swift; path = RxSwift/Concurrency/SynchronizedDisposeType.swift; sourceTree = ""; }; + 4D87C46D3D423E94BC72155D7A5B5A2D /* Infallible+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Operators.swift"; path = "RxSwift/Traits/Infallible/Infallible+Operators.swift"; sourceTree = ""; }; + 4E991AAB3675553011A566D7D5890A76 /* Never.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Never.swift; path = RxSwift/Observables/Never.swift; sourceTree = ""; }; + 5097A478504A238C6105200FB47B7522 /* AsyncLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncLock.swift; path = RxSwift/Concurrency/AsyncLock.swift; sourceTree = ""; }; + 517BDC1669294A148E4DBFD5B37E4CA0 /* DisposeBag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBag.swift; path = RxSwift/Disposables/DisposeBag.swift; sourceTree = ""; }; + 51C95DFD2CA4362C4313EBE5596AD65F /* ObserverType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverType.swift; path = RxSwift/ObserverType.swift; sourceTree = ""; }; + 5223A3219D4D96425B9386779E9C3941 /* SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SnapKit-Info.plist"; sourceTree = ""; }; 52554E1C9731D5352FDE9E63F8C5466B /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; }; - 53223FF13560EBEA779AD3723F9BBA00 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; - 536AE0412E79AAD5D7758292B3B75D0B /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; - 5378FB89697FC8EA7FBC2EFCA76477CB /* ObserverBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverBase.swift; path = RxSwift/Observers/ObserverBase.swift; sourceTree = ""; }; - 53AD78AE798D875C99318D5D0912F543 /* Buffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Buffer.swift; path = RxSwift/Observables/Buffer.swift; sourceTree = ""; }; - 53D07AA6A24B29A203133E60FC50D7BB /* Completable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Completable.swift; path = RxSwift/Traits/PrimitiveSequence/Completable.swift; sourceTree = ""; }; - 5401FDAB1CBADE2FD2AC91D65EBBD4DC /* _RXKVOObserver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXKVOObserver.m; path = RxCocoa/Runtime/_RXKVOObserver.m; sourceTree = ""; }; - 545F2DDE7D8FF39935F86D5FE27C8CC4 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = RxSwift/Observables/Filter.swift; sourceTree = ""; }; - 55CB4877246F52FF87A8C244384E4E42 /* RxSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxSwift-dummy.m"; sourceTree = ""; }; - 562B01E7D1CBAA099413E50DB98212AC /* Infallible+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Zip+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+Zip+arity.swift"; sourceTree = ""; }; - 565F1573A89C0E571C1C7A874625F7E9 /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; - 5663CC614EDF46B43CD113FE47D9B9AD /* HTTPMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPMethod.swift; path = Source/HTTPMethod.swift; sourceTree = ""; }; - 5668586C4F1FBED7320E57E20FEF2209 /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; - 56B0287E747640F717C72FCFD5602A81 /* SchedulerServices+Emulation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerServices+Emulation.swift"; path = "RxSwift/Schedulers/SchedulerServices+Emulation.swift"; sourceTree = ""; }; - 56D6EC6EA4C2491D9C1946FFC2D0F77D /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Source/LayoutConstraint.swift; sourceTree = ""; }; - 5799D32A0710CD856AB9552515F6904B /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; - 57E162D330CF2CEF9DF0AF20E78638F8 /* ObservableConvertibleType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift"; sourceTree = ""; }; - 581ECB7EB510001F013CEE44FAD7CB93 /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UICollectionView+Rx.swift"; path = "RxCocoa/iOS/UICollectionView+Rx.swift"; sourceTree = ""; }; - 590ED942605473B4D25BE44D9207DDDE /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Source/ConstraintConstantTarget.swift; sourceTree = ""; }; - 594AF42B97DD02A1DFD0047E23495757 /* Pods-Bunjang */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-Bunjang"; path = Pods_Bunjang.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5A21AC031138F500D867B1A15877ED9C /* RxCollectionViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift; sourceTree = ""; }; - 5B0FC9E7F5D5E10E8BA353C0F145507D /* SkipUntil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipUntil.swift; path = RxSwift/Observables/SkipUntil.swift; sourceTree = ""; }; - 5B439B367CC6C89C100ED8B736E470FA /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmediateSchedulerType.swift; path = RxSwift/ImmediateSchedulerType.swift; sourceTree = ""; }; - 5C000E2E307CBE72910B6A0E5625A6AC /* RetryPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryPolicy.swift; path = Source/RetryPolicy.swift; sourceTree = ""; }; - 5C475814CC7778BF88A47494A1117A28 /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchQueueConfiguration.swift; path = RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift; sourceTree = ""; }; + 5264EDC8D0DB10A5282A04C71579F2AC /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Source/ConstraintLayoutGuide.swift; sourceTree = ""; }; + 535245D6165D831E74CCF68877E016BC /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; + 5376CA15D3279EF75237B1C406400270 /* CombineLatest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CombineLatest.swift; path = RxSwift/Observables/CombineLatest.swift; sourceTree = ""; }; + 5422501686FAC3E64A8018D8F903CD57 /* ConstraintDirectionalInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsets.swift; path = Source/ConstraintDirectionalInsets.swift; sourceTree = ""; }; + 549CAA2B2EDE8AD94C5988D95A8829E5 /* RxSearchBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift; sourceTree = ""; }; + 55C7070925A0D5B91896AFBB46ADB57F /* RxCocoa-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxCocoa-dummy.m"; sourceTree = ""; }; + 579FA3521C9FD6CB4DCCB1B2CEF7982D /* RxScrollViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxScrollViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift; sourceTree = ""; }; + 587647AE89A8323AA8669B5ACA6201BE /* RxRelay-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxRelay-dummy.m"; sourceTree = ""; }; + 5A1E2AE32DE9B16524DBF78CFF07F72E /* RxCocoa.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.debug.xcconfig; sourceTree = ""; }; + 5AAF61DCEE7EF17C7D4E598C5194836D /* Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Driver.swift; path = RxCocoa/Traits/Driver/Driver.swift; sourceTree = ""; }; + 5AEF374C7E373EFFF865471106A1FCEC /* UIStepper+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIStepper+Rx.swift"; path = "RxCocoa/iOS/UIStepper+Rx.swift"; sourceTree = ""; }; + 5B0C7B81DA43217A2842F181A0413B81 /* RxTableViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; + 5BF636A803D82E59DA4ADF71F7AA4027 /* SubjectType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubjectType.swift; path = RxSwift/Subjects/SubjectType.swift; sourceTree = ""; }; + 5C0DA1708C5DB689CED1BB733A6202C2 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; + 5CD2C62A0338F3123A15A325CF410C46 /* RxPickerViewAdapter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewAdapter.swift; path = RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift; sourceTree = ""; }; + 5CDE30B01C6DAD0D5FD8C972F98DE288 /* Timeout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeout.swift; path = RxSwift/Observables/Timeout.swift; sourceTree = ""; }; + 5D25D7E510A6EBB96395707104EF360C /* ControlProperty+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlProperty+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlProperty+Driver.swift"; sourceTree = ""; }; + 5D6F90B890CCCC1B401070F43B61779C /* RxPickerViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift; sourceTree = ""; }; + 5D761FAD304D3B41BD183F4BF6B6CF99 /* ControlEvent+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Signal.swift"; path = "RxCocoa/Traits/Signal/ControlEvent+Signal.swift"; sourceTree = ""; }; 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Alamofire; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D8A73A39785C42B97E613D0CFA6BDD0 /* ObservableConvertibleType+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Driver.swift"; path = "RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift"; sourceTree = ""; }; - 5DCC04F3693DED5FA68286618AD2C348 /* Pods-Bunjang-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Bunjang-acknowledgements.plist"; sourceTree = ""; }; - 5E153A1EECE82F48D2805239759A549A /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDatePicker+Rx.swift"; path = "RxCocoa/iOS/UIDatePicker+Rx.swift"; sourceTree = ""; }; - 5EBB6166F378B6BA3BA6045513AD0B68 /* Signal+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Signal+Subscription.swift"; path = "RxCocoa/Traits/Signal/Signal+Subscription.swift"; sourceTree = ""; }; - 5FB6515374F67729417916635301BE41 /* SharedSequence+Operators+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators+arity.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift"; sourceTree = ""; }; - 601BAA3A79806B156A41056A73088AE8 /* UISegmentedControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISegmentedControl+Rx.swift"; path = "RxCocoa/iOS/UISegmentedControl+Rx.swift"; sourceTree = ""; }; - 6024A9A382EF8A747BF3EF7F6CB93279 /* Pods-Bunjang-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Bunjang-Info.plist"; sourceTree = ""; }; - 60ED99EA71CABA14574423D41AB0E5A3 /* Materialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Materialize.swift; path = RxSwift/Observables/Materialize.swift; sourceTree = ""; }; - 60F565743D0E0A3EFD781A8F8A9B51CD /* Debounce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debounce.swift; path = RxSwift/Observables/Debounce.swift; sourceTree = ""; }; - 610390D4044731D1CFB686687A81F305 /* RxWKNavigationDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxWKNavigationDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift; sourceTree = ""; }; - 61070FC24D3DD3C05630D2FD00ECF898 /* RequestTaskMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestTaskMap.swift; path = Source/RequestTaskMap.swift; sourceTree = ""; }; - 6283F9E56EB235587468C6A23E30BFE0 /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; - 63004A6A6B9BEFDAA58B7FA062278C43 /* ConstraintMakerPriortizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPriortizable.swift; path = Source/ConstraintMakerPriortizable.swift; sourceTree = ""; }; - 665B7D600A93931F9FC0056B47D815E1 /* UITabBarController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBarController+Rx.swift"; path = "RxCocoa/iOS/UITabBarController+Rx.swift"; sourceTree = ""; }; - 66C4A8CDB4B63101810861A42200B095 /* RxRelay-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxRelay-Info.plist"; sourceTree = ""; }; - 66CA00697CC0D00401E693CB52991330 /* Typealiases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Typealiases.swift; path = Source/Typealiases.swift; sourceTree = ""; }; - 6715A6CAA80600D08EC4B8F2671014AD /* ReplaySubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplaySubject.swift; path = RxSwift/Subjects/ReplaySubject.swift; sourceTree = ""; }; - 673EDC2A7995B2775EF3A3D7B1F1D50C /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; - 67DD57B81172C762BFE739FC04F4D21E /* BehaviorSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorSubject.swift; path = RxSwift/Subjects/BehaviorSubject.swift; sourceTree = ""; }; - 682485D6700D5F4F209B3D7E8409414A /* AtomicInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AtomicInt.swift; path = Platform/AtomicInt.swift; sourceTree = ""; }; - 687E155797AF351961D6BEEF1A2766F2 /* Cancelable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cancelable.swift; path = RxSwift/Cancelable.swift; sourceTree = ""; }; - 68F413AB8BC1E3A11E7767EE9B3B3B0E /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CurrentThreadScheduler.swift; path = RxSwift/Schedulers/CurrentThreadScheduler.swift; sourceTree = ""; }; - 690CBA6B46BCDC28457F1D7848E98E4F /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; - 6A2C3C1D0E6D7A4FE37D9A983BD28417 /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; - 6AD1E7581C086DB0A3C8E579FB4664B3 /* SerialDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDisposable.swift; path = RxSwift/Disposables/SerialDisposable.swift; sourceTree = ""; }; - 6AE4579792A54E5559A9DAEDD992456D /* KVORepresentable+CoreGraphics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+CoreGraphics.swift"; path = "RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift"; sourceTree = ""; }; - 6AEF96291CDC473DD230EFDC04E3745A /* GraphicsContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphicsContext.swift; path = Sources/Image/GraphicsContext.swift; sourceTree = ""; }; - 6B35807BDF3E02C1B736BA4C9C9358C7 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; }; - 6B3A7C706BF0A33310C00DB4E7422EF6 /* PublishSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishSubject.swift; path = RxSwift/Subjects/PublishSubject.swift; sourceTree = ""; }; - 6BF605F4199BEDA7DC3DCD3BE09331AE /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; - 6C4C951A1EF580FD0454E47472A52DEA /* OperationQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OperationQueueScheduler.swift; path = RxSwift/Schedulers/OperationQueueScheduler.swift; sourceTree = ""; }; - 6CA9A671658EDC6000F285EBAF057106 /* _RXDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXDelegateProxy.h; path = RxCocoa/Runtime/include/_RXDelegateProxy.h; sourceTree = ""; }; - 6E29D4C339F968E99A592A06B33343DD /* RxCocoa.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.release.xcconfig; sourceTree = ""; }; - 6FF013F915831C54C604373BFD7FF75D /* CombineLatest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CombineLatest.swift; path = RxSwift/Observables/CombineLatest.swift; sourceTree = ""; }; - 7015A2723C7EB58E15977193C5ADE30A /* AnonymousDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousDisposable.swift; path = RxSwift/Disposables/AnonymousDisposable.swift; sourceTree = ""; }; - 7016AF1EC96543C2911C96C8D525402B /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; - 7085CE1B5550909B6FB91DBF692233F3 /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAssignmentDisposable.swift; path = RxSwift/Disposables/SingleAssignmentDisposable.swift; sourceTree = ""; }; - 709DF0E3B25C0AEE4AAFB24B57499054 /* ControlProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlProperty.swift; path = RxCocoa/Traits/ControlProperty.swift; sourceTree = ""; }; - 70EB53F90BC2C2B55771AB42C6359FA6 /* NSTextStorage+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextStorage+Rx.swift"; path = "RxCocoa/iOS/NSTextStorage+Rx.swift"; sourceTree = ""; }; - 7210D187331A95A56DFC067B911061D8 /* UIActivityIndicatorView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIActivityIndicatorView+Rx.swift"; path = "RxCocoa/iOS/UIActivityIndicatorView+Rx.swift"; sourceTree = ""; }; - 72B29299DFED276BACC7D6FF6F41973B /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; - 737D6142E61022ADE009B35BCA7D67A0 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; - 739DC6301DF1F2FA1A37C23C38EAACB3 /* UISlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISlider+Rx.swift"; path = "RxCocoa/iOS/UISlider+Rx.swift"; sourceTree = ""; }; - 741F949E7A59F3DDA438594A62CF0B5B /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift; sourceTree = ""; }; - 7477F9282D2B4E4714DD0ADEEAC8A14C /* ControlEvent+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlEvent+Driver.swift"; sourceTree = ""; }; - 74C004D11372137CC8A4B3C27854344E /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Source/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; - 77A079F61C4AB9506A8A7123727E58A3 /* _RXKVOObserver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXKVOObserver.h; path = RxCocoa/Runtime/include/_RXKVOObserver.h; sourceTree = ""; }; - 77D4E5B389FE76E8E5A9C151697E1E3A /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Source/ConstraintRelatableTarget.swift; sourceTree = ""; }; - 782CA0710D423EBD97794817C8359075 /* RxCollectionViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; - 7A4A33D4EBD87311076E540A7ABFA143 /* RxRelay-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-umbrella.h"; sourceTree = ""; }; - 7A5D8C38F674F50CB23E901928ABBFA5 /* RxTableViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift; sourceTree = ""; }; - 7AD5FC6299043CD5F0F76E73F4F7411F /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentMainScheduler.swift; path = RxSwift/Schedulers/ConcurrentMainScheduler.swift; sourceTree = ""; }; - 7B5FE232EFFF73B7C3D25288BA3912B7 /* Infallible+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Create.swift"; path = "RxSwift/Traits/Infallible/Infallible+Create.swift"; sourceTree = ""; }; - 7C96CEE8260D1D4000BBBEDFB62CD8D3 /* ElementAt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementAt.swift; path = RxSwift/Observables/ElementAt.swift; sourceTree = ""; }; - 7D1B38AC6033251DAD312CD6B3A92EC2 /* Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Driver.swift; path = RxCocoa/Traits/Driver/Driver.swift; sourceTree = ""; }; - 7E52CD081388CCB8E6485B2504337448 /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Source/ConstraintOffsetTarget.swift; sourceTree = ""; }; - 7E7B9C74BBBFA3CF7A52FD8918555C8E /* ObserverType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverType.swift; path = RxSwift/ObserverType.swift; sourceTree = ""; }; - 7E896F1E52CD239FF87B9110061B1B63 /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Source/ConstraintView+Extensions.swift"; sourceTree = ""; }; - 7EE84A906E3B42A400F7A6A21B74204B /* TextInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextInput.swift; path = RxCocoa/Common/TextInput.swift; sourceTree = ""; }; - 803AA769B8BDFAFF27D2D09489678DE4 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + 5D865B2EF3338D285050AFD9717880B6 /* RxPickerViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift; sourceTree = ""; }; + 5DC1C2FF2C913DE532CD697CE2E82EE8 /* RxCocoa.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxCocoa.modulemap; sourceTree = ""; }; + 5DCFBB65EFC4BB3B34271DEEEF799093 /* Date+Dispatch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Dispatch.swift"; path = "RxSwift/Date+Dispatch.swift"; sourceTree = ""; }; + 5DEA69A88EF4071C8F5957A614F62B71 /* _RXDelegateProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXDelegateProxy.m; path = RxCocoa/Runtime/_RXDelegateProxy.m; sourceTree = ""; }; + 5DFFF2012F5791E774C912AC86DDCE0D /* NSTextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextField+Rx.swift"; path = "RxCocoa/macOS/NSTextField+Rx.swift"; sourceTree = ""; }; + 5E26F802520E48824E02912593B726AE /* PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PrimitiveSequence.swift; path = RxSwift/Traits/PrimitiveSequence/PrimitiveSequence.swift; sourceTree = ""; }; + 5E4760342B9E9A2D2585A3A124C49345 /* RequestInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestInterceptor.swift; path = Source/RequestInterceptor.swift; sourceTree = ""; }; + 5E8A7F6C8121A6FA3F53FCA8F53EA8FA /* DelaySubscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelaySubscription.swift; path = RxSwift/Observables/DelaySubscription.swift; sourceTree = ""; }; + 5F5D8D6E3DFEDC6651C6B2F9C4FA1FBD /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; + 60A77062CC86E62ABF59F12FCA57E196 /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Source/ConstraintMakerFinalizable.swift; sourceTree = ""; }; + 6133281F47EC6817A2F139A120E864AE /* ToArray.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToArray.swift; path = RxSwift/Observables/ToArray.swift; sourceTree = ""; }; + 61AA2DA550B097827DA12AE1415B11B4 /* URLEncodedFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncodedFormEncoder.swift; path = Source/URLEncodedFormEncoder.swift; sourceTree = ""; }; + 61CE5FA8C390F7C5066EE1B035CF5037 /* RxCocoa.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.release.xcconfig; sourceTree = ""; }; + 6335C0CBDFEB0A267F383DF5A5D0E209 /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; + 63E79E25C1CD7ABF6BE187033583F968 /* TakeLast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeLast.swift; path = RxSwift/Observables/TakeLast.swift; sourceTree = ""; }; + 63F86EDE0DE4C642283ED4E5E4CDFBE0 /* InvocableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableType.swift; path = RxSwift/Schedulers/Internal/InvocableType.swift; sourceTree = ""; }; + 6484BB20C4A334B3CA255803D52D0AF7 /* Cancelable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cancelable.swift; path = RxSwift/Cancelable.swift; sourceTree = ""; }; + 649025AAC69E92BE8E9ABB1A2DDF2FB8 /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; + 65E38C9F179F1817B63D21E6B8042079 /* _RXObjCRuntime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXObjCRuntime.m; path = RxCocoa/Runtime/_RXObjCRuntime.m; sourceTree = ""; }; + 66053C44365424146EEB9240C16BAF31 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; }; + 661995B1014D4EFB67154575503A2A88 /* Event.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Event.swift; path = RxSwift/Event.swift; sourceTree = ""; }; + 68251CF4FE3622BA12120AFDF13FA1C4 /* Do.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Do.swift; path = RxSwift/Observables/Do.swift; sourceTree = ""; }; + 68B4D2046A60FAA56B043EF6DBFDE4FE /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Source/ConstraintAttributes.swift; sourceTree = ""; }; + 69679F318A371FDD8C42439C3FE25586 /* UITableView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITableView+Rx.swift"; path = "RxCocoa/iOS/UITableView+Rx.swift"; sourceTree = ""; }; + 6B0156512CBF5584A1DB161E180766E1 /* URLSession+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSession+Rx.swift"; path = "RxCocoa/Foundation/URLSession+Rx.swift"; sourceTree = ""; }; + 6BA3CEEAC4F4177C22F2015BD3FF1F24 /* Just.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Just.swift; path = RxSwift/Observables/Just.swift; sourceTree = ""; }; + 6CA535D550AC90898448FAC2B3E839E8 /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; + 6CDB776F8CD44684C79FAD47ACB1C3D7 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 6D0D84CA1B759F7250F1F55706122246 /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; + 6D74B49F8F212BDF24A91CA248B5EFD1 /* ConnectableObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectableObservableType.swift; path = RxSwift/ConnectableObservableType.swift; sourceTree = ""; }; + 6DD6F88E56C3C14732D14F6C6D64767C /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; + 6F76B9A485E25F7856CEB67B8CD8B569 /* Pods-GenderList-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GenderList-umbrella.h"; sourceTree = ""; }; + 6FB7DC60BEE1C9BDE9A6AFE88497F85E /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; + 70A10D5A2BD6546E0640BE73E3A4B3D2 /* NSObject+Rx+RawRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+RawRepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift"; sourceTree = ""; }; + 70EB884AE386D32AAF63E0A0FAA7AC5C /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; + 7146CCCBE0B9901F601E355C2966BD1E /* AtomicInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AtomicInt.swift; path = Platform/AtomicInt.swift; sourceTree = ""; }; + 71DE11D37B0EB2DC6721E198C5B7BB94 /* PublishRelay+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PublishRelay+Signal.swift"; path = "RxCocoa/Traits/Signal/PublishRelay+Signal.swift"; sourceTree = ""; }; + 72B9242504B8D42D2180847C1D02DD74 /* RxSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxSwift-dummy.m"; sourceTree = ""; }; + 741FCF6FD88310101424A7ED16D279BF /* DelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxy.swift; path = RxCocoa/Common/DelegateProxy.swift; sourceTree = ""; }; + 748BD5FEAE0F1BDC45114CB14C6322A4 /* UIPickerView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIPickerView+Rx.swift"; path = "RxCocoa/iOS/UIPickerView+Rx.swift"; sourceTree = ""; }; + 74D56845A1D247158DDA408F45DAA35E /* GroupBy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupBy.swift; path = RxSwift/Observables/GroupBy.swift; sourceTree = ""; }; + 74E4D3E1255D7FA3A2EC241B99432FEF /* Typealiases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Typealiases.swift; path = Source/Typealiases.swift; sourceTree = ""; }; + 770297B28D90456712801DCBAB3F3D4E /* TailRecursiveSink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TailRecursiveSink.swift; path = RxSwift/Observers/TailRecursiveSink.swift; sourceTree = ""; }; + 7738ACDE4C2E00BC16AF9185E123A3DF /* Pods-GenderList-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GenderList-dummy.m"; sourceTree = ""; }; + 776DFD1F3CBB65E70DE70D6103601433 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxCocoa/Common/Observable+Bind.swift"; sourceTree = ""; }; + 7773B6A17EBF60A6676CD1478F2FA2B0 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; + 7776F5D697B91DC2D5C6C66F4B6D0C6E /* Maybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Maybe.swift; path = RxSwift/Traits/PrimitiveSequence/Maybe.swift; sourceTree = ""; }; + 77FA35F270AE53C737F4FF7A4879A13B /* Observable+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Concurrency.swift"; path = "RxSwift/Observable+Concurrency.swift"; sourceTree = ""; }; + 783CF62358B7156761CAE141432059EC /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeConverterType.swift; path = RxSwift/Schedulers/VirtualTimeConverterType.swift; sourceTree = ""; }; + 7880A9F133272877D5749E9DA11537EB /* ScheduledDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledDisposable.swift; path = RxSwift/Disposables/ScheduledDisposable.swift; sourceTree = ""; }; + 796DC31A2574F842FC44B7D07E24A722 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; + 79F42263D865156D4945BFDBF0A4CFE4 /* SerialDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDisposable.swift; path = RxSwift/Disposables/SerialDisposable.swift; sourceTree = ""; }; + 7A338F46E55BB4522632D9A50330DE81 /* PublishSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishSubject.swift; path = RxSwift/Subjects/PublishSubject.swift; sourceTree = ""; }; + 7ACFE08527ACEE2E4AA211BEA97F4F2A /* Skip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Skip.swift; path = RxSwift/Observables/Skip.swift; sourceTree = ""; }; + 7BE60A9AB9690D6EC4D6CB050F76F0AD /* RxCollectionViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift; sourceTree = ""; }; + 7D17F5C46B8A9F8C14865CEF5914AB30 /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; + 7E40213495C29B7EC0897128E18347B9 /* CachedResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CachedResponseHandler.swift; path = Source/CachedResponseHandler.swift; sourceTree = ""; }; + 7F92B6AFEA2D6A41A69C4B3F1F81E66F /* RxCocoa-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxCocoa-Info.plist"; sourceTree = ""; }; + 803BC476D5564A4FA5CD5F0275CFB254 /* ScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItem.swift; path = RxSwift/Schedulers/Internal/ScheduledItem.swift; sourceTree = ""; }; + 806A2A4C9A4D1D5500BE72BFA6B13F91 /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; + 807ADE91E070BDDFA8FC7E6D0CAAD435 /* UIActivityIndicatorView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIActivityIndicatorView+Rx.swift"; path = "RxCocoa/iOS/UIActivityIndicatorView+Rx.swift"; sourceTree = ""; }; 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = RxSwift; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 80A64114D53C625813C2D26E4677BCF7 /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; - 81596965EC2DAB2BF48389645FC00166 /* Pods-Bunjang-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Bunjang-dummy.m"; sourceTree = ""; }; - 8162421B4BB84E20689FE291FFFAF647 /* RxPickerViewAdapter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewAdapter.swift; path = RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift; sourceTree = ""; }; - 81E49C8041DCCA4DC4E591197550BF98 /* RxSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxSwift-Info.plist"; sourceTree = ""; }; - 824686CA707E4A0205D584D7D80A548C /* _RXObjCRuntime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXObjCRuntime.m; path = RxCocoa/Runtime/_RXObjCRuntime.m; sourceTree = ""; }; - 837D68EC9B5FF19849A4309C9D50C12F /* DefaultIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DefaultIfEmpty.swift; path = RxSwift/Observables/DefaultIfEmpty.swift; sourceTree = ""; }; - 8460862A1D5FAE753536EE93A4D4A90E /* UITextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextField+Rx.swift"; path = "RxCocoa/iOS/UITextField+Rx.swift"; sourceTree = ""; }; - 84983A505E8934C5AD701FE2D31FB770 /* ControlTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlTarget.swift; path = RxCocoa/Common/ControlTarget.swift; sourceTree = ""; }; - 8500C3892A8916E27BA49771DDC39F84 /* ControlEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlEvent.swift; path = RxCocoa/Traits/ControlEvent.swift; sourceTree = ""; }; - 8502AB6F24119364EC6FFAC9C51D8B72 /* Decode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Decode.swift; path = RxSwift/Observables/Decode.swift; sourceTree = ""; }; - 85293B8B83659B656B1ABF20EF57E4F1 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; - 852B3F5F7CAC90F024AD13ABCCFB986C /* Infallible+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Concurrency.swift"; path = "RxSwift/Traits/Infallible/Infallible+Concurrency.swift"; sourceTree = ""; }; - 8634AC774363585D5917FFA4AEEF52DD /* RxSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.release.xcconfig; sourceTree = ""; }; - 86DC6ACB03731C01E7B7EBCE23FB1BE9 /* UINavigationController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UINavigationController+Rx.swift"; path = "RxCocoa/iOS/UINavigationController+Rx.swift"; sourceTree = ""; }; + 8292E3BE05ACD436F29CF9A67287A8DF /* UINavigationController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UINavigationController+Rx.swift"; path = "RxCocoa/iOS/UINavigationController+Rx.swift"; sourceTree = ""; }; + 82F76798AA7C42A64C4EB6B59DC95A77 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; + 8423330216C0F1793ABF4D8864F9C3E1 /* Infallible+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Zip+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+Zip+arity.swift"; sourceTree = ""; }; + 86EBEFE81557E00B7289D083294B013A /* SkipUntil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipUntil.swift; path = RxSwift/Observables/SkipUntil.swift; sourceTree = ""; }; 872D7EFA572ECEE8EF993C27196E16DD /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; - 877A2FD7746750C7EEA0776F7100ED51 /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; - 8795F9C24E8EEBF4399FB16C4A213174 /* RxRelay.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxRelay.modulemap; sourceTree = ""; }; - 888140F08408B7B3271F6544822DD56D /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; - 88C9CBE328FA6D027532F2845F170D6F /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Source/ConstraintMakerEditable.swift; sourceTree = ""; }; - 892593379667A23952F2CC74685738E3 /* NSTextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextView+Rx.swift"; path = "RxCocoa/macOS/NSTextView+Rx.swift"; sourceTree = ""; }; - 8A3BCDC3D9A45F0A36083EB4A32CBB59 /* UITabBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBar+Rx.swift"; path = "RxCocoa/iOS/UITabBar+Rx.swift"; sourceTree = ""; }; - 8DF09656ED4D86E85CD578AF13D73744 /* RxScrollViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxScrollViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift; sourceTree = ""; }; - 9060E46ABEBE8DF1C9F5CDBEA8F03188 /* RxTabBarControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift; sourceTree = ""; }; - 90A368B9BE806FE43AF910196519FC5D /* PublishRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishRelay.swift; path = RxRelay/PublishRelay.swift; sourceTree = ""; }; - 90FD593F6533CBAE30159E9909FB238D /* ConnectableObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectableObservableType.swift; path = RxSwift/ConnectableObservableType.swift; sourceTree = ""; }; - 91722A08B7BCDFD99580E9A0199DF3F4 /* UIScrollView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIScrollView+Rx.swift"; path = "RxCocoa/iOS/UIScrollView+Rx.swift"; sourceTree = ""; }; - 91C7499695875934CFF0EAC81F7E26C5 /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextStorageDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift; sourceTree = ""; }; - 92302766ED87489DC4556A56CD10A5B9 /* RxCocoaObjCRuntimeError+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "RxCocoaObjCRuntimeError+Extensions.swift"; path = "RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift"; sourceTree = ""; }; - 923A02BEB70212483E3F31C6FA05C4E3 /* DelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxy.swift; path = RxCocoa/Common/DelegateProxy.swift; sourceTree = ""; }; - 93B9D54BE7D34A5488B42DC19D10A403 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; - 94775AC80AD2CDC009C836D6249E04B5 /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+Collection.swift"; path = "RxSwift/Observables/CombineLatest+Collection.swift"; sourceTree = ""; }; - 95079D39BC909C1A6BAD48240CC1CEBA /* PublishRelay+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PublishRelay+Signal.swift"; path = "RxCocoa/Traits/Signal/PublishRelay+Signal.swift"; sourceTree = ""; }; - 95488DC7B444610250080F96F0BB9942 /* RxCocoa.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCocoa.swift; path = RxCocoa/RxCocoa.swift; sourceTree = ""; }; - 9583D07CFEC32E9B920EC112BDCF8F1E /* ObservableType+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+Extensions.swift"; path = "RxSwift/ObservableType+Extensions.swift"; sourceTree = ""; }; - 96399A3F19C97048BD73AC6C016447AA /* Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debug.swift; path = RxSwift/Observables/Debug.swift; sourceTree = ""; }; - 965B3A6BE185B4673A5F58FF419A00AE /* ConstraintDirectionalInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsetTarget.swift; path = Source/ConstraintDirectionalInsetTarget.swift; sourceTree = ""; }; - 96B1049D115F74C6C48B9BF7B975E5F3 /* DelegateProxyType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxyType.swift; path = RxCocoa/Common/DelegateProxyType.swift; sourceTree = ""; }; - 96B99BA47A5EBF3E66630684A8F212DD /* Enumerated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Enumerated.swift; path = RxSwift/Observables/Enumerated.swift; sourceTree = ""; }; - 96C930E38E9AB3484081BAF76C727EC9 /* SharedSequence+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift"; sourceTree = ""; }; - 977C506F43603C288E2B36DB0F5FE1A6 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 87C197CF31D13B491047064857E79C4E /* _RX.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RX.h; path = RxCocoa/Runtime/include/_RX.h; sourceTree = ""; }; + 88509CE697A792FDB49CFA1BB4ACA90D /* Disposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposable.swift; path = RxSwift/Disposable.swift; sourceTree = ""; }; + 885975EFA59BAE09779F812C3088B554 /* ConstraintPriority.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriority.swift; path = Source/ConstraintPriority.swift; sourceTree = ""; }; + 8882B3B9AE691A21883DDA845199981A /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Source/Constraint.swift; sourceTree = ""; }; + 8890470F000AFACA77AF03D583016B43 /* SubscribeOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscribeOn.swift; path = RxSwift/Observables/SubscribeOn.swift; sourceTree = ""; }; + 8975545EC3285FA17F23C282511FAF50 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; + 89BA94ED52F0795DC30B8EDF36697174 /* SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SharedSequence.swift; path = RxCocoa/Traits/SharedSequence/SharedSequence.swift; sourceTree = ""; }; + 8AD68A687DC10A841007668CF32CAD53 /* Pods-GenderList-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GenderList-acknowledgements.plist"; sourceTree = ""; }; + 8BB4260CF2A46B845613C59B79940D4E /* NSControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSControl+Rx.swift"; path = "RxCocoa/macOS/NSControl+Rx.swift"; sourceTree = ""; }; + 8C1BE9E50D4CDA794129A973C8D1103C /* RxMutableBox.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxMutableBox.swift; path = RxSwift/RxMutableBox.swift; sourceTree = ""; }; + 8CAD8A267F66DAD110741B2A5847070E /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; + 8CB14F660CC08F53BE651CF4ECBEF658 /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableScheduledItem.swift; path = RxSwift/Schedulers/Internal/InvocableScheduledItem.swift; sourceTree = ""; }; + 8D05715E1C746DA8A57A002AD77320E2 /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Source/ConstraintMakerRelatable.swift; sourceTree = ""; }; + 8DE826C87D74FA780918D4C7EA87B7AE /* ScheduledItemType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItemType.swift; path = RxSwift/Schedulers/Internal/ScheduledItemType.swift; sourceTree = ""; }; + 8E856C87271A41592E12866CE3C9A668 /* RetryPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryPolicy.swift; path = Source/RetryPolicy.swift; sourceTree = ""; }; + 8F20EB9BFC1006360D8A179A92D3A514 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; + 8F28559ECB31ED01EBF30485A89354E9 /* SharedSequence+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift"; sourceTree = ""; }; + 8F9DB5DEEFE0943EE6183585AD693D22 /* CompactMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompactMap.swift; path = RxSwift/Observables/CompactMap.swift; sourceTree = ""; }; + 8FBFC0CBBF3385F74EA898D58C65B4B3 /* Infallible+CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+CombineLatest+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+CombineLatest+arity.swift"; sourceTree = ""; }; + 8FD2D1EC03E239BF0A8EF6F05A8C0BC5 /* RxSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.release.xcconfig; sourceTree = ""; }; + 8FDF6CD75C1834270FDEB7F5D0F2BCB1 /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UICollectionView+Rx.swift"; path = "RxCocoa/iOS/UICollectionView+Rx.swift"; sourceTree = ""; }; + 9007FC5024FD1C48B575F77C8E3B1865 /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Source/LayoutConstraint.swift; sourceTree = ""; }; + 9044CC20197AD853A260B3EA7AA3E5B5 /* RxCocoaRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoaRuntime.h; path = RxCocoa/Runtime/include/RxCocoaRuntime.h; sourceTree = ""; }; + 9070D35DDE49A9987567E3F308BB5221 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; + 90C3484BA91ADC6B89669375A948E937 /* SkipWhile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipWhile.swift; path = RxSwift/Observables/SkipWhile.swift; sourceTree = ""; }; + 91D56807DC7DF84CD3BB6C0208B64E31 /* Combine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Combine.swift; path = Source/Combine.swift; sourceTree = ""; }; + 923B236039A70B1F88907A3F82BFE2AE /* NopDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NopDisposable.swift; path = RxSwift/Disposables/NopDisposable.swift; sourceTree = ""; }; + 92425124E34B67695B33DCE332AA82EC /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = RxSwift/Observables/Map.swift; sourceTree = ""; }; + 928A9C7117C36D7FD359DDFE7E4D8CD7 /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Source/ConstraintItem.swift; sourceTree = ""; }; + 92C4B6FEBA77235BB4623831F8AED445 /* Infallible+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Bind.swift"; path = "RxCocoa/Common/Infallible+Bind.swift"; sourceTree = ""; }; + 92C6D703ECB03FF623920A2ABBA1C984 /* BehaviorSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorSubject.swift; path = RxSwift/Subjects/BehaviorSubject.swift; sourceTree = ""; }; + 939BBB23FED848AEA8A9A3782F5BB566 /* BooleanDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BooleanDisposable.swift; path = RxSwift/Disposables/BooleanDisposable.swift; sourceTree = ""; }; + 944092E0A468F6032639BB3DEFC353BD /* UIControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIControl+Rx.swift"; path = "RxCocoa/iOS/UIControl+Rx.swift"; sourceTree = ""; }; + 94BE1EE9EBCA5538B271C44C0D2C3061 /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = RxSwift/Observables/Switch.swift; sourceTree = ""; }; + 94DC3DF73BAE5D55802A8D13A41C0AD3 /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; + 94F6A4941C676635405DF83466B0BC26 /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; + 952EC55F4C5F9DE9E5C6CEA37ACFE65D /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; + 964EB3E2D2B380D91FE17EA3BD81849A /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; + 96BAD09D260831792CA65A8C5971A26C /* Signal+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Signal+Subscription.swift"; path = "RxCocoa/Traits/Signal/Signal+Subscription.swift"; sourceTree = ""; }; + 9705F4FFEB198353334C91129FD3C7B6 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; + 9738AD838D2B289843146F132AB003E9 /* ControlEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlEvent.swift; path = RxCocoa/Traits/ControlEvent.swift; sourceTree = ""; }; 979486118B3E90C08386079D57962701 /* SnapKit */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SnapKit; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 97CE79655B8A34D6270A73B843CF2271 /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = RxSwift/Errors.swift; sourceTree = ""; }; - 987EC0DD92EE020800E3E03D74818D35 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; - 9884F54F21ABFA557C53E40DD34E35B3 /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDispatchQueueScheduler.swift; path = RxSwift/Schedulers/SerialDispatchQueueScheduler.swift; sourceTree = ""; }; - 98ED6A1FB741868720BC377FA293B9A0 /* Driver+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Subscription.swift"; path = "RxCocoa/Traits/Driver/Driver+Subscription.swift"; sourceTree = ""; }; - 999012423D4F0401601226FECBAD91DC /* RxCocoa.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxCocoa.modulemap; sourceTree = ""; }; - 9991701AA0379D8817CEDBF9CAEDE1A4 /* RxTableViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; - 9AB4873AE1C8F057BB406BD437FEBEC0 /* UIApplication+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIApplication+Rx.swift"; path = "RxCocoa/iOS/UIApplication+Rx.swift"; sourceTree = ""; }; - 9B49579A82C0539E33F8DB78641B1E64 /* URLEncodedFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncodedFormEncoder.swift; path = Source/URLEncodedFormEncoder.swift; sourceTree = ""; }; - 9C078D8BDF198136B167BED30F8A82E0 /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; - 9C3BB98B0EF87EC7B8B22703000ACA9E /* BehaviorRelay+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "BehaviorRelay+Driver.swift"; path = "RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift"; sourceTree = ""; }; - 9CE3B739A608F0DDAD0F2DE37083707A /* HistoricalScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalScheduler.swift; path = RxSwift/Schedulers/HistoricalScheduler.swift; sourceTree = ""; }; - 9D7887303BCD625A3E1124F82E25F6D2 /* WKWebView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKWebView+Rx.swift"; path = "RxCocoa/iOS/WKWebView+Rx.swift"; sourceTree = ""; }; + 99427CA80A669FE028CF88825B36EACF /* SharedSequence+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Concurrency.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Concurrency.swift"; sourceTree = ""; }; + 9A2F68AB3AB4B514979EC4B758CC781B /* Alamofire.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.release.xcconfig; sourceTree = ""; }; + 9B07F4E91969B4B4290F4E935C528AC4 /* RxTextViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift; sourceTree = ""; }; + 9B6D7EC7AFB179E41E13D4BD2C664704 /* Dematerialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Dematerialize.swift; path = RxSwift/Observables/Dematerialize.swift; sourceTree = ""; }; + 9B8074DCF34AA82F470D83BE9AFA22EA /* Delay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delay.swift; path = RxSwift/Observables/Delay.swift; sourceTree = ""; }; + 9B8AB683D3CE1BC246D1C753622BC4FC /* RxTableViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift; sourceTree = ""; }; + 9C300A4562E606959DBC2D95A38D347E /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift; sourceTree = ""; }; + 9C91A18F51E4CC6B9E6968EE21EDCF94 /* WithLatestFrom.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithLatestFrom.swift; path = RxSwift/Observables/WithLatestFrom.swift; sourceTree = ""; }; + 9D22CAA3D66865CE1343FDADF4776379 /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Source/ConstraintConfig.swift; sourceTree = ""; }; + 9D242FB48AEB035B24741F5EF5D470D9 /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Source/ConstraintMaker.swift; 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; }; - 9DA099226DE912F6804ED601DCE54DA7 /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Source/ConstraintDescription.swift; sourceTree = ""; }; - 9DE2CE1E44745DF7D91F7A5994CE22A6 /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Source/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; - 9E0A868C9971CDD7B0B6C688E3643774 /* ObservableConvertibleType+Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Infallible.swift"; path = "RxSwift/Traits/Infallible/ObservableConvertibleType+Infallible.swift"; sourceTree = ""; }; - 9EC8262350C75698D71BEC19D863D711 /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; - 9F00B9A5E2C77D491F42C7A323D89434 /* ConcurrentDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentDispatchQueueScheduler.swift; path = RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift; sourceTree = ""; }; - 9F4F78CF439D58FD5F821B8196123351 /* NSTextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextField+Rx.swift"; path = "RxCocoa/macOS/NSTextField+Rx.swift"; sourceTree = ""; }; - 9FB53906BE6B2C9E6204708B943C66E8 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; - 9FE24B1808CCB08EBA787BC2F6C8C9C2 /* SchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SchedulerType.swift; path = RxSwift/SchedulerType.swift; sourceTree = ""; }; - 9FF0A54173D4CF241D535F100AB21A1C /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DistinctUntilChanged.swift; path = RxSwift/Observables/DistinctUntilChanged.swift; sourceTree = ""; }; - 9FF466253C12307D3952E7BF6496394B /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; - A002EFCC8C0346E39E3DB06B1725881C /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; - A0B6997E7F68410D8A6C16644E3B92AD /* Alamofire.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.debug.xcconfig; sourceTree = ""; }; - A102DCE673A0A9A983D6DE36965791A1 /* Range.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Range.swift; path = RxSwift/Observables/Range.swift; sourceTree = ""; }; - A1B19C706685F1007CFA37D8B72F4A84 /* WithUnretained.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithUnretained.swift; path = RxSwift/Observables/WithUnretained.swift; sourceTree = ""; }; - A1C288444CD932974293E8EF6BDDACD6 /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Source/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; - A2BC13603EB21A257F88ADDCDBB022C8 /* Lock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Lock.swift; path = RxSwift/Concurrency/Lock.swift; sourceTree = ""; }; - A2D10146397CCBBA9C236D37BB87BAB9 /* RxTabBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift; sourceTree = ""; }; - A3166ABA859436ACB43784064BA94408 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Source/ConstraintInsetTarget.swift; sourceTree = ""; }; - A3CBFB2E2A7835AFFD9AF09F49AB44DB /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; - A3E2A7B51D1978B92017963C55349295 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxCocoa/Common/Observable+Bind.swift"; sourceTree = ""; }; - A44A26151470999E8036AC468A9C1372 /* Using.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Using.swift; path = RxSwift/Observables/Using.swift; sourceTree = ""; }; - A501DBEFDB319841EFCB339196BD2087 /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Source/LayoutConstraintItem.swift; sourceTree = ""; }; - A53773ECF7488C9D01CE5D439FCC2F8A /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = RxSwift/Observables/Switch.swift; sourceTree = ""; }; - A549A9EB6AF7788C2602ACBFEB019EAF /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; - A54C1F19A76D740FCD01B0FFE8B8B52D /* RxPickerViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift; sourceTree = ""; }; - A5E3B733BCCBB62B59FD06B8C437FF95 /* Delay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delay.swift; path = RxSwift/Observables/Delay.swift; sourceTree = ""; }; - A60CCCC9B71B8257E82BB6A53357E35F /* ConstraintPriority.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriority.swift; path = Source/ConstraintPriority.swift; sourceTree = ""; }; - A767B65FB96753CA10F8AAB2477D9DF9 /* Alamofire.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.release.xcconfig; sourceTree = ""; }; - A785ADAF5C7B8D666BB4ED42943A8662 /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; - A83C680BD4FC55B43A8CED179AD14F46 /* AlamofireExtended.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireExtended.swift; path = Source/AlamofireExtended.swift; sourceTree = ""; }; - A84C5BEA876D4A87BEB5E63B35C885AC /* CachedResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CachedResponseHandler.swift; path = Source/CachedResponseHandler.swift; sourceTree = ""; }; - A85637ACD268647B3D9AB2FCF1640346 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; - A86C98B190BBB18095371820610FFBA9 /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; - A8830E829C546878488B268DCE7DDB4D /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; - A926E0571C383DCF3CA9610A7DD2A439 /* MultipartUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartUpload.swift; path = Source/MultipartUpload.swift; sourceTree = ""; }; - A9F57960FCF66D2D01C89E218FB41DA8 /* RxTextViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift; sourceTree = ""; }; - AA58654B4430250D86C1BCBD63DE43A8 /* ReplayRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplayRelay.swift; path = RxRelay/ReplayRelay.swift; sourceTree = ""; }; - AB3D593961945959F1A44BE5C05C5A58 /* Disposables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposables.swift; path = RxSwift/Disposables/Disposables.swift; sourceTree = ""; }; - AB73CA1C3F8B703DE2C884659A31C2D7 /* Bag+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bag+Rx.swift"; path = "RxSwift/Extensions/Bag+Rx.swift"; sourceTree = ""; }; - ACEDFBBA5F76F3B47E6A904879318588 /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; - ACF8BDA55CB353142EEB66AD26161D10 /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeScheduler.swift; path = RxSwift/Schedulers/VirtualTimeScheduler.swift; sourceTree = ""; }; - AD31C27FDA4BDB820AE3811BBF0F3289 /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift; sourceTree = ""; }; - AD3677E72917440D5EA45F5BCB6B5829 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; - ADB2003C180AFB52A18317561E6EC5CE /* WithLatestFrom.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithLatestFrom.swift; path = RxSwift/Observables/WithLatestFrom.swift; sourceTree = ""; }; - AEF7A990982D57F3CF18103B53C623BA /* BehaviorRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorRelay.swift; path = RxRelay/BehaviorRelay.swift; sourceTree = ""; }; - AF91FDC5BD806070B5160246987FD3D5 /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+KVORepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; }; - AFBE121C04BB773EBAADCF4FEF232E49 /* Reduce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reduce.swift; path = RxSwift/Observables/Reduce.swift; sourceTree = ""; }; - B025DF756635BB8334DED4384ABB6D8B /* SchedulerType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift"; sourceTree = ""; }; - B041565AEEC2F2E374E5AEA0A1805FBA /* TailRecursiveSink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TailRecursiveSink.swift; path = RxSwift/Observers/TailRecursiveSink.swift; sourceTree = ""; }; - B12F9ECAACAE51F90B804AABFCBF3650 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedUnsubscribeType.swift; path = RxSwift/Concurrency/SynchronizedUnsubscribeType.swift; sourceTree = ""; }; - B17FE795BFDF8716FCE863719F88C915 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; }; - B40C6BA6CDC6B229E81A833B34FC0605 /* Infallible+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Bind.swift"; path = "RxCocoa/Common/Infallible+Bind.swift"; sourceTree = ""; }; - B42016A0131B39159AFDAD957DB09CD6 /* ItemEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ItemEvents.swift; path = RxCocoa/iOS/Events/ItemEvents.swift; sourceTree = ""; }; - B47FE5B477CC9C18416010929166F7DC /* Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Infallible.swift; path = RxSwift/Traits/Infallible/Infallible.swift; sourceTree = ""; }; - B4BC0F2018503D8002E78FCE926EE3DB /* URLSession+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSession+Rx.swift"; path = "RxCocoa/Foundation/URLSession+Rx.swift"; sourceTree = ""; }; - B6EDE4C2E94C7299D615D4615B12B896 /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableScheduledItem.swift; path = RxSwift/Schedulers/Internal/InvocableScheduledItem.swift; sourceTree = ""; }; - B7737EEE6716D463DA348B99E54B89E6 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; - B79B95D1B2DDEC221F61E2BACEDAF527 /* ObservableType+PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+PrimitiveSequence.swift"; path = "RxSwift/Traits/PrimitiveSequence/ObservableType+PrimitiveSequence.swift"; sourceTree = ""; }; - B7C1CDFAC10807BB2B956A999969A0FF /* TVMonogramView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TVMonogramView+Kingfisher.swift"; path = "Sources/Extensions/TVMonogramView+Kingfisher.swift"; sourceTree = ""; }; - B7EA47329CE7C48C537F13F781A9FAAB /* RxCocoaRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoaRuntime.h; path = RxCocoa/Runtime/include/RxCocoaRuntime.h; sourceTree = ""; }; - B84BB4804259F96248E7DB341FCDFDC8 /* ParameterEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoder.swift; path = Source/ParameterEncoder.swift; sourceTree = ""; }; - B89A1E4268C8D59F48FC54DA5809ACC7 /* RxTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTarget.swift; path = RxCocoa/Common/RxTarget.swift; sourceTree = ""; }; - B91BFE5181BE61CE32BA2259CFA60B89 /* URLRequest+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Alamofire.swift"; path = "Source/URLRequest+Alamofire.swift"; sourceTree = ""; }; - B9F67A58719C517741D63F9EAC3F24D6 /* Observable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Observable.swift; path = RxSwift/Observable.swift; sourceTree = ""; }; - BA03DC4A3F895B6A381043F1C17753B7 /* PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PrimitiveSequence.swift; path = RxSwift/Traits/PrimitiveSequence/PrimitiveSequence.swift; sourceTree = ""; }; - BA51397293F7F7DE9320460FD4C14042 /* Zip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zip.swift; path = RxSwift/Observables/Zip.swift; sourceTree = ""; }; - BB3816ADA06410A6B7793234D38F84D5 /* Amb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Amb.swift; path = RxSwift/Observables/Amb.swift; sourceTree = ""; }; - BBABFFF76C76A9D5D8DADB1EDE58F23E /* CompositeDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompositeDisposable.swift; path = RxSwift/Disposables/CompositeDisposable.swift; sourceTree = ""; }; - BBCE1CAEA27D5FDE3D9D901415378A20 /* First.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = First.swift; path = RxSwift/Observables/First.swift; sourceTree = ""; }; - BC182783F31B0D1DD816939B95155F5D /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIBarButtonItem+Rx.swift"; path = "RxCocoa/iOS/UIBarButtonItem+Rx.swift"; sourceTree = ""; }; + 9DA8D267F3F3C52824DB85F2A4558754 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + 9DF9A1F6E5E6B9C758E8ECEB280377DF /* BehaviorRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorRelay.swift; path = RxRelay/BehaviorRelay.swift; sourceTree = ""; }; + 9E252F71811BA2A0DF5FAEDA77B3D86D /* AddRef.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AddRef.swift; path = RxSwift/Observables/AddRef.swift; sourceTree = ""; }; + 9F82EB30ACBF25A82505A35ACDCE2A96 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; + 9F97DD8D894161C3532CA0B9B171A9FB /* Debounce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debounce.swift; path = RxSwift/Observables/Debounce.swift; sourceTree = ""; }; + A15A5CB1859AE914F9A4883C909C1D04 /* DelegateProxyType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxyType.swift; path = RxCocoa/Common/DelegateProxyType.swift; sourceTree = ""; }; + A2E6CC487F38F5A6D12B359D6AFB09A6 /* Multicast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Multicast.swift; path = RxSwift/Observables/Multicast.swift; sourceTree = ""; }; + A3270291C59FE54F4233693ADDE644C7 /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; + A4ED1922D596A1522D90C5B55D697E8E /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; + A5532071B77604F3BDCDCAD049CC3294 /* RxCocoaObjCRuntimeError+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "RxCocoaObjCRuntimeError+Extensions.swift"; path = "RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift"; sourceTree = ""; }; + A6EB7CA5E10FC28F6095BE8C836B9DA2 /* Timer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timer.swift; path = RxSwift/Observables/Timer.swift; sourceTree = ""; }; + A71FF01397BCF8E5126F7DB2781F9A19 /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; + A72B315AB5C66F8B157BAB601E734E3E /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; + A74E5079BE8E238BED74E89B731D5157 /* MultipartUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartUpload.swift; path = Source/MultipartUpload.swift; sourceTree = ""; }; + A7F1E6B2FA0343E7E89E81C88CC672A3 /* Completable+AndThen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Completable+AndThen.swift"; path = "RxSwift/Traits/PrimitiveSequence/Completable+AndThen.swift"; sourceTree = ""; }; + A85D6B6C09F3FA02098B1204C99334CA /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmediateSchedulerType.swift; path = RxSwift/ImmediateSchedulerType.swift; sourceTree = ""; }; + A8A5CEB9207F34477DCBCE05CA0329FE /* SynchronizedOnType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedOnType.swift; path = RxSwift/Concurrency/SynchronizedOnType.swift; sourceTree = ""; }; + A8ABD7704AF8D558B05DBFE563C8BFB8 /* SharedSequence+Operators+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators+arity.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift"; sourceTree = ""; }; + A910CC14D263A3C2DBCBBF8AE936A9B2 /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = RxSwift/SwiftSupport/SwiftSupport.swift; sourceTree = ""; }; + A98553727E761D8D5A0BC081285ADE9E /* UITextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextField+Rx.swift"; path = "RxCocoa/iOS/UITextField+Rx.swift"; sourceTree = ""; }; + AA78242DC744444804153FB317B7E2E8 /* RecursiveScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveScheduler.swift; path = RxSwift/Schedulers/RecursiveScheduler.swift; sourceTree = ""; }; + AABBF71F11B9315AE1BF54B313097F7E /* RxSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-umbrella.h"; sourceTree = ""; }; + AB2F7D87FA65948E65985C245E90F30D /* SchedulerType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift"; sourceTree = ""; }; + ABA6E66779D1E9F9B8001B7D359D02EA /* Completable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Completable.swift; path = RxSwift/Traits/PrimitiveSequence/Completable.swift; sourceTree = ""; }; + AC9DAA4C9C6A0CA4FA72B74F3756FD48 /* RxCocoa-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-prefix.pch"; sourceTree = ""; }; + ACCBD4C0C85A487DCD856558486F38E2 /* UISlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISlider+Rx.swift"; path = "RxCocoa/iOS/UISlider+Rx.swift"; sourceTree = ""; }; + AD233B7BE3779DE6C50056326BC19F22 /* ServerTrustEvaluation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustEvaluation.swift; path = Source/ServerTrustEvaluation.swift; sourceTree = ""; }; + AD98DA4FED7C52AA2D77259CBF98E81D /* ObservableConvertibleType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift"; sourceTree = ""; }; + AED03E92814E6B1D4872D7FE4343DBFF /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Source/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; + AF741934484C2FF24397B93BA6FE6709 /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; + B0257C7F85074973CEFF9BB412C5B41D /* ConcurrentDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentDispatchQueueScheduler.swift; path = RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift; sourceTree = ""; }; + B0A095E2B75D2E3DB3B274F8F8A4CF92 /* BehaviorRelay+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "BehaviorRelay+Driver.swift"; path = "RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift"; sourceTree = ""; }; + B0C42A7163BD5ADE05A3340C6B8B5D22 /* Using.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Using.swift; path = RxSwift/Observables/Using.swift; sourceTree = ""; }; + B229B8631DFEA25BD56F9A5330D76F9E /* Producer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Producer.swift; path = RxSwift/Observables/Producer.swift; sourceTree = ""; }; + B2DF563BC203205607B72B98451BF9AA /* StartWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StartWith.swift; path = RxSwift/Observables/StartWith.swift; sourceTree = ""; }; + B2FBB746560DC1E971E2EA40E423CDFB /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Source/Debugging.swift; sourceTree = ""; }; + B3291F34A83BABC8CAB3AF78E427484F /* URLSessionConfiguration+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSessionConfiguration+Alamofire.swift"; path = "Source/URLSessionConfiguration+Alamofire.swift"; sourceTree = ""; }; + B340DB018799D7AFF781F5CEADCC06F6 /* Take.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Take.swift; path = RxSwift/Observables/Take.swift; sourceTree = ""; }; + B425BCF674CEF3AA80353C753E6527DB /* AnyObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyObserver.swift; path = RxSwift/AnyObserver.swift; sourceTree = ""; }; + B431141CBD5FDEE892FB07B93CFD1D51 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; + B4715F04958933344007626908174565 /* RxWKNavigationDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxWKNavigationDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift; sourceTree = ""; }; + B5C7D6CA2E239A1CAAB0805B3EDBDD3F /* RxNavigationControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxNavigationControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift; sourceTree = ""; }; + B6411610C892550E50F787ECE3AC4475 /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = RxSwift/Errors.swift; sourceTree = ""; }; + B6AC886A405B78BA6458877730E1591B /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; + B75D4359FA407C5BFDCA84D5DC68698E /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Source/ConstraintDSL.swift; sourceTree = ""; }; + B7CFF041D4E96A90F3CCF914CB009E40 /* UITabBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBar+Rx.swift"; path = "RxCocoa/iOS/UITabBar+Rx.swift"; sourceTree = ""; }; + B81CC2EC16DFF3718AF037BFE08AF4F7 /* AnonymousObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousObserver.swift; path = RxSwift/Observers/AnonymousObserver.swift; sourceTree = ""; }; + B9DEC06B67A85AA48A2118481BCF5D38 /* Merge.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Merge.swift; path = RxSwift/Observables/Merge.swift; sourceTree = ""; }; + BB5A231091AC6A99D67423C54E54C73F /* Result+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Result+Alamofire.swift"; path = "Source/Result+Alamofire.swift"; sourceTree = ""; }; + BB8779B59592C7549ADBF5AB5110B0BB /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Source/ConstraintInsets.swift; sourceTree = ""; }; + BBE61D79694AAA7EB29E379C8487EE71 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; + BC0A930E95F275B6B5E02AE3F3FF030D /* ControlEvent+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlEvent+Driver.swift"; sourceTree = ""; }; BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = RxCocoa; path = RxCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BC6D96E71D0D40BFA9ED18FE23078F8F /* Infallible+CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+CombineLatest+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+CombineLatest+arity.swift"; sourceTree = ""; }; - BDD4A751EE1628FD6964148586377853 /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Source/ConstraintLayoutGuide.swift; sourceTree = ""; }; - BDD7993237F89658783EA88C8FA4924F /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Source/ConstraintMakerFinalizable.swift; sourceTree = ""; }; - BE032E5A6B45556B1CE4035AB8300BC7 /* PrimitiveSequence+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PrimitiveSequence+Concurrency.swift"; path = "RxSwift/Traits/PrimitiveSequence/PrimitiveSequence+Concurrency.swift"; sourceTree = ""; }; - BE6D3755550E71F3C4ED3DBF77FDAF45 /* UIControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIControl+Rx.swift"; path = "RxCocoa/iOS/UIControl+Rx.swift"; sourceTree = ""; }; - BF9F98E08158E504E673C919AF746700 /* Date+Dispatch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Dispatch.swift"; path = "RxSwift/Date+Dispatch.swift"; sourceTree = ""; }; - C12BD7A4C979860972136F7BA019630B /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; - C16AEBDE0AC9FA3063D48EE7921A25B1 /* Generate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generate.swift; path = RxSwift/Observables/Generate.swift; sourceTree = ""; }; - C24F87871E996DBDC20A4F578217123E /* RxCollectionViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift; sourceTree = ""; }; - C26EC0D0D63F0FB850F30A10CBE850E2 /* Sink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sink.swift; path = RxSwift/Observables/Sink.swift; sourceTree = ""; }; - C294FFEA094D34D45BC84CEF61CF1C49 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; }; - C2A6AE6EEE6FB189C7673B9F58C77757 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; - C2AD9E34263C1FD6F837368810D9B6B6 /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Source/ConstraintMakerExtendable.swift; sourceTree = ""; }; - C3E5CBA1DB958A279FE0C629D26B7185 /* KFImageOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageOptions.swift; path = Sources/SwiftUI/KFImageOptions.swift; sourceTree = ""; }; + BD67BADF711C03B22878143404E08FCB /* ObservableType+PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+PrimitiveSequence.swift"; path = "RxSwift/Traits/PrimitiveSequence/ObservableType+PrimitiveSequence.swift"; sourceTree = ""; }; + BDC090E508088FF0C0A3490F4B4AC21F /* Empty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Empty.swift; path = RxSwift/Observables/Empty.swift; sourceTree = ""; }; + BE04B2773B47F444AD15B2D3ED195A0C /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; + BF856F895F5BD4D5F260053D673E8B93 /* Alamofire.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.debug.xcconfig; sourceTree = ""; }; + BFA5D5163A1B894A0D3138DB29FAB037 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; + BFAA391D692A854BE386E250FA9D185E /* ObservableConvertibleType+Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Infallible.swift"; path = "RxSwift/Traits/Infallible/ObservableConvertibleType+Infallible.swift"; sourceTree = ""; }; + BFCD8F726BA2E1ED840CB2402B98E783 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; + BFF69ED1FA9497A9E9861EBDB2ABF203 /* ObservableConvertibleType+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Driver.swift"; path = "RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift"; sourceTree = ""; }; + C047D0F4457085742D9DF66A00FACEE0 /* CompositeDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompositeDisposable.swift; path = RxSwift/Disposables/CompositeDisposable.swift; sourceTree = ""; }; + C0E32787F7DBEBBED4C99A7FFD8F195D /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchQueueConfiguration.swift; path = RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift; sourceTree = ""; }; + C0E4B80AD9F51FD88A2D7B3262518209 /* Bag+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bag+Rx.swift"; path = "RxSwift/Extensions/Bag+Rx.swift"; sourceTree = ""; }; + C0F7056A97FEB5FCB2C86F9686D2C0F8 /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Source/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; + C119DBAA7D6E7B3882D1CC7B760256E2 /* ElementAt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementAt.swift; path = RxSwift/Observables/ElementAt.swift; sourceTree = ""; }; + C234656CE4C4E9C9ADB150EC38A6316F /* Catch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Catch.swift; path = RxSwift/Observables/Catch.swift; sourceTree = ""; }; + C29A289EF7C91591D808694C7F3473ED /* Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concurrency.swift; path = Source/Concurrency.swift; sourceTree = ""; }; + C2C8987AD5E008F7FF45922286EB79F0 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; + C2CDA3A4DDF9E4D7E37FC3A32090E715 /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; + C2E0BD09EF34AC741CDB014F457C2EB6 /* WithUnretained.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithUnretained.swift; path = RxSwift/Observables/WithUnretained.swift; sourceTree = ""; }; + C2E1371BA56D60F8CA446C7DA1840DDF /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Source/ConstraintView+Extensions.swift"; sourceTree = ""; }; + C2FF21266D29953418187232F568362E /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; + C326389654418C163F0542532BC17110 /* UIRefreshControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIRefreshControl+Rx.swift"; path = "RxCocoa/iOS/UIRefreshControl+Rx.swift"; sourceTree = ""; }; C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Kingfisher; path = Kingfisher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C45144499497DB482329E52115E128E3 /* InvocableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableType.swift; path = RxSwift/Schedulers/Internal/InvocableType.swift; sourceTree = ""; }; - C47AF1800496AAD9455F26513BBA496B /* UITableView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITableView+Rx.swift"; path = "RxCocoa/iOS/UITableView+Rx.swift"; sourceTree = ""; }; - C78AA19DC4AE9B2EE6F6022F07E84E07 /* Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rx.swift; path = RxSwift/Rx.swift; sourceTree = ""; }; - C87C76EEE158FB9F89ADF843A9FDC6ED /* Timeout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeout.swift; path = RxSwift/Observables/Timeout.swift; sourceTree = ""; }; - C954F6DF8FF162D446F5C12EB53E01AA /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Source/RedirectHandler.swift; sourceTree = ""; }; - CA67DA9621D034A48C86105DBADC18FE /* Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+arity.swift"; path = "RxSwift/Observables/Zip+arity.swift"; sourceTree = ""; }; - CB1A5BE2F78CB18678F6C66C43494879 /* UIStepper+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIStepper+Rx.swift"; path = "RxCocoa/iOS/UIStepper+Rx.swift"; sourceTree = ""; }; - CB28A30D5E28A968807FF91682435113 /* RxTableViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift; sourceTree = ""; }; - CBDF289925E0A8E8FE110FC2EE0FC5BC /* Reactive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reactive.swift; path = RxSwift/Reactive.swift; sourceTree = ""; }; - CC36F9E06FE49F1F4F80BB1AFA71E98E /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchBar+Rx.swift"; path = "RxCocoa/iOS/UISearchBar+Rx.swift"; sourceTree = ""; }; - CCCF2EE2D7FDC0AD69FBC3A1B95A1486 /* RxMutableBox.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxMutableBox.swift; path = RxSwift/RxMutableBox.swift; sourceTree = ""; }; - CDB1D196B882ED38EFB67CDB8058A6DA /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; - CE614EF7725D1080DC262AA7AF3B9C30 /* Repeat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Repeat.swift; path = RxSwift/Observables/Repeat.swift; sourceTree = ""; }; - CE864F413CB764E2D3840B6A04F5C8BB /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; - CEBA261C0E4D59E792E2A1E87DA48CD3 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Source/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; - CF507A128B1048F9A9506E5EF8DD94E5 /* Zip+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+Collection.swift"; path = "RxSwift/Observables/Zip+Collection.swift"; sourceTree = ""; }; - CF937DC1BF9020E271091491FB8CF954 /* DelaySubscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelaySubscription.swift; path = RxSwift/Observables/DelaySubscription.swift; sourceTree = ""; }; - CF9D4F784D11A2A619A5B91A0B218600 /* RxRelay-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-prefix.pch"; sourceTree = ""; }; - CFB1D3357C9D51B861167D08229FD122 /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; - CFCFD51497C9110708C858EA2C19368C /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; - CFD28848184CFC8F2669F9C7B6F3ECA9 /* Skip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Skip.swift; path = RxSwift/Observables/Skip.swift; sourceTree = ""; }; - D0739409A23BACA2BE8DD8A961490989 /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Source/ConstraintView.swift; sourceTree = ""; }; - D0B578AF8941617056FE4E294D356E78 /* SingleAsync.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAsync.swift; path = RxSwift/Observables/SingleAsync.swift; sourceTree = ""; }; - D13859A2CFBD9C9E8B504BEAA461B51A /* KVORepresentable+Swift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+Swift.swift"; path = "RxCocoa/Foundation/KVORepresentable+Swift.swift"; sourceTree = ""; }; - D2089866320AF70B3661336D75B57BC0 /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; - D3311B6D4D057AD143CB7E74A0B1E1E5 /* RefCountDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RefCountDisposable.swift; path = RxSwift/Disposables/RefCountDisposable.swift; sourceTree = ""; }; - D4B8B6B28C084865856AD6D49550E430 /* Concat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concat.swift; path = RxSwift/Observables/Concat.swift; sourceTree = ""; }; - D529B43DBB7B1DA17E601A091D5305BB /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Source/ConstraintLayoutSupport.swift; sourceTree = ""; }; - D67131024C7367F11A6414DE7CA82CF0 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; - D93865933C5B3EEC7A6744968D58B8B1 /* Window.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Window.swift; path = RxSwift/Observables/Window.swift; sourceTree = ""; }; - D9781B0EC24FD1296469FF205F8FB810 /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; - D9F047AFE79DA1C753989691948402E8 /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; - DC95CABB41414838A5CA49BCCBA6D914 /* KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVORepresentable.swift; path = RxCocoa/Foundation/KVORepresentable.swift; sourceTree = ""; }; - DCA169B7E5D3DEAD4224D444953FAFD3 /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; - DD09C5F6714AD9AE9D5F476B1B38822D /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Source/ConstraintPriorityTarget.swift; sourceTree = ""; }; - DD8374B2F9307524AA49B8C180B751A0 /* URLSessionConfiguration+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSessionConfiguration+Alamofire.swift"; path = "Source/URLSessionConfiguration+Alamofire.swift"; sourceTree = ""; }; - DE62662A2D55BF8E43A8AE661CC6EDE4 /* Just.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Just.swift; path = RxSwift/Observables/Just.swift; sourceTree = ""; }; - DF9F7C0C096008AB17EA43C33758716D /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; - DFB2F5D8F493BEAFE9EFA5E3E5EA0027 /* RxPickerViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift; sourceTree = ""; }; - E02491ED736B233DE2EA307C1EB3E2B9 /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = RxSwift/SwiftSupport/SwiftSupport.swift; sourceTree = ""; }; - E049D95E456C13016DBD029DF097E38B /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; - E1057D4EB481C24ACA874B22DB4B986C /* Multicast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Multicast.swift; path = RxSwift/Observables/Multicast.swift; sourceTree = ""; }; - E134AA052C1FF8D939096469FC59AE78 /* UIPickerView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIPickerView+Rx.swift"; path = "RxCocoa/iOS/UIPickerView+Rx.swift"; sourceTree = ""; }; - E16592D918033D6F1FCACB9C70EBDEC7 /* NSControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSControl+Rx.swift"; path = "RxCocoa/macOS/NSControl+Rx.swift"; sourceTree = ""; }; - E16C9210350E4CF9F59ED55DE6C2EAE7 /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift; sourceTree = ""; }; - E21D0733C912FD68451BD423ADC83E4D /* CompactMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompactMap.swift; path = RxSwift/Observables/CompactMap.swift; sourceTree = ""; }; - E23433B6C5425020E1F9ABB659C33A82 /* AsyncLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncLock.swift; path = RxSwift/Concurrency/AsyncLock.swift; sourceTree = ""; }; - E2863AA3C3F0EBF54E3EA897B0EB74C7 /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Source/Debugging.swift; sourceTree = ""; }; - E4C954C71FA7E915CF61F045E29B4866 /* SkipWhile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipWhile.swift; path = RxSwift/Observables/SkipWhile.swift; sourceTree = ""; }; - E618A494A482B3DEC86B81C1AD1D365F /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = RxSwift/Observables/Map.swift; sourceTree = ""; }; - E64546B97551BE82226EF18A88571095 /* RxCocoa-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-prefix.pch"; sourceTree = ""; }; - E7555D68AECBE9EC9B6D36A0AD9B6038 /* AsSingle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsSingle.swift; path = RxSwift/Observables/AsSingle.swift; sourceTree = ""; }; - E784C3A6B34056D0BBA3B30E79142A7E /* UITextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextView+Rx.swift"; path = "RxCocoa/iOS/UITextView+Rx.swift"; sourceTree = ""; }; - E86414347BF96F3CB7BBEE331C50AE90 /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; - E90B9C4250086CFB7483AAD87B1C4989 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; - E913CE22A6FD9AC2977EE4115A73181D /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; - EA2E3307EAC0D40402CF75CA99E59080 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; - EA6203B0A1D8270B6CE3B525E6F7ECE3 /* ScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItem.swift; path = RxSwift/Schedulers/Internal/ScheduledItem.swift; sourceTree = ""; }; - EA90122D850DDF57AA5D6CB8903DD8FB /* Pods-Bunjang-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Bunjang-frameworks.sh"; sourceTree = ""; }; - EABE22BF2DF69287E362BE1D2C88D65C /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; - EAE4529CDBEBC039DFAA7036AB45EE30 /* AddRef.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AddRef.swift; path = RxSwift/Observables/AddRef.swift; sourceTree = ""; }; - EBFBAFDA9E115C3FA592178ABCB160FA /* Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Create.swift; path = RxSwift/Observables/Create.swift; sourceTree = ""; }; - EC0527510AA2DB17EAC9D3E218CAA163 /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableConvertibleType.swift; path = RxSwift/ObservableConvertibleType.swift; sourceTree = ""; }; - EC109E1398391D4E301F805F761BC5B2 /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; - EC362006304825F3407E5280F369197F /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; }; - ED3E0D1A2B19426FEBE08684BE7EB997 /* UIGestureRecognizer+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIGestureRecognizer+Rx.swift"; path = "RxCocoa/iOS/UIGestureRecognizer+Rx.swift"; sourceTree = ""; }; - ED95C7C562A3738CF2D4BF66BADF61F5 /* LockOwnerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LockOwnerType.swift; path = RxSwift/Concurrency/LockOwnerType.swift; sourceTree = ""; }; - EDF6BA90952A9B09B459D0A010FFF4CB /* SynchronizedOnType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedOnType.swift; path = RxSwift/Concurrency/SynchronizedOnType.swift; sourceTree = ""; }; - EDF7AA432C0E4C80D47EEF000590D957 /* Protector.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protector.swift; path = Source/Protector.swift; sourceTree = ""; }; - EF2AE61FD67D2D52D425F6BED79AE568 /* AnonymousObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousObserver.swift; path = RxSwift/Observers/AnonymousObserver.swift; sourceTree = ""; }; - EFAF4546BEC4051969C1020917C3FB33 /* SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SharedSequence.swift; path = RxCocoa/Traits/SharedSequence/SharedSequence.swift; sourceTree = ""; }; - EFEDC3D329D65E48B3BC7FCA14CDED97 /* EventMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventMonitor.swift; path = Source/EventMonitor.swift; sourceTree = ""; }; - F266CB0FCD269EE6A8449BC282D0187D /* NSObject+Rx+RawRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+RawRepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift"; sourceTree = ""; }; - F2A6298A6E44AC15ECABBDBC9D11D79F /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; - F3EB20F3A45D6B29A3E978F87182B9C0 /* SubjectType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubjectType.swift; path = RxSwift/Subjects/SubjectType.swift; sourceTree = ""; }; - F3EE251BF5CC611B7D07507D0B79D416 /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Source/ConstraintDSL.swift; sourceTree = ""; }; - F56F39816D76F06712167096FF3E3A5F /* Single.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Single.swift; path = RxSwift/Traits/PrimitiveSequence/Single.swift; sourceTree = ""; }; - F6DDE21B51F954F2DCA17A42FA6C7DF9 /* GroupBy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupBy.swift; path = RxSwift/Observables/GroupBy.swift; sourceTree = ""; }; - F87FF9A89CEA3BE638D492B4D2861FC5 /* ControlEvent+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Signal.swift"; path = "RxCocoa/Traits/Signal/ControlEvent+Signal.swift"; sourceTree = ""; }; - F8A8A341317A3DFABDA1E41E20BEF985 /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Source/ConstraintConfig.swift; sourceTree = ""; }; - F938BFD201DD51B234CDAF2A7BE97279 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; - F9E69EBCE3389722923E118788F3FF7A /* OperationQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "OperationQueue+Alamofire.swift"; path = "Source/OperationQueue+Alamofire.swift"; sourceTree = ""; }; - FA0410C906661C5ECBB5A94E5BEDBA52 /* Completable+AndThen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Completable+AndThen.swift"; path = "RxSwift/Traits/PrimitiveSequence/Completable+AndThen.swift"; sourceTree = ""; }; - FA742B9CCC6986A75BCC203D8A301748 /* ScheduledDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledDisposable.swift; path = RxSwift/Disposables/ScheduledDisposable.swift; sourceTree = ""; }; - FB8FFF121EEF33CEBB22766BD88B0155 /* DisposeBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBase.swift; path = RxSwift/Disposables/DisposeBase.swift; sourceTree = ""; }; - FBA68C43E44294E2A8A0ED20C0BDF200 /* ConstraintDirectionalInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsets.swift; path = Source/ConstraintDirectionalInsets.swift; sourceTree = ""; }; - FBF80ED92B3DEF5D9EE1A157A9E17442 /* Merge.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Merge.swift; path = RxSwift/Observables/Merge.swift; sourceTree = ""; }; - FC5FAACB2F1EFDF21330936154BF6DFA /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; - FDCFCE5266BE0AD0A4A0EDB04177DC43 /* RxCocoa.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.debug.xcconfig; sourceTree = ""; }; - FE70B944EB620CD61740D3BA724EACEC /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; - FEC59675D09A0CF86AEF5C3158226E1B /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; - FF0683C05982A495A423CBDA039C3AC6 /* RxSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxSwift.modulemap; sourceTree = ""; }; - FF1A11CA657EBFC3AE9A5FAA8F50C737 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; + C6A393DD2437866A291C7EC4EF3C1E0B /* RxSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxSwift.modulemap; sourceTree = ""; }; + C711A78D09F3C9ED05DD103F20ED97F8 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Source/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; + C7449A6095EB1BA269B3C2B73CBDB28D /* RxCocoa.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCocoa.swift; path = RxCocoa/RxCocoa.swift; sourceTree = ""; }; + C763C3301F4A9D71EA67289A30CCA5C2 /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Source/ConstraintOffsetTarget.swift; sourceTree = ""; }; + C925288023BDC18E74D66D6E1BBFDAF3 /* Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+arity.swift"; path = "RxSwift/Observables/Zip+arity.swift"; sourceTree = ""; }; + C92D5CEA71FB521BF9D2801EBFD0EDE3 /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; + CA0F4A1959721B796E0302A27F5EEDAA /* NSView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSView+Rx.swift"; path = "RxCocoa/macOS/NSView+Rx.swift"; sourceTree = ""; }; + CB204A7905DC8CDA462909EB4D19A184 /* RxSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.debug.xcconfig; sourceTree = ""; }; + CB22C6A389B7E966F793D95F308B669C /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; + CBC08F9FA24E20B061964BC084936292 /* UISearchController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchController+Rx.swift"; path = "RxCocoa/iOS/UISearchController+Rx.swift"; sourceTree = ""; }; + CC0BB8711A19D4B872ADBAE7977F2D55 /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Source/ConstraintMakerExtendable.swift; sourceTree = ""; }; + CC1E8344C026E264D4315EB2020BCB3A /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; + CC8A68F8FC8A03F8C5839FD7419DFC46 /* Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rx.swift; path = RxSwift/Rx.swift; sourceTree = ""; }; + CCE3665D6C88438C0AC4433967269C3F /* UITabBarController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBarController+Rx.swift"; path = "RxCocoa/iOS/UITabBarController+Rx.swift"; sourceTree = ""; }; + CD17068C473F46FDDA345E0B8F45A14E /* HTTPHeaders.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPHeaders.swift; path = Source/HTTPHeaders.swift; sourceTree = ""; }; + CD31B7D0E44D1C6D267C74B719E9C93E /* RxTableViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift; sourceTree = ""; }; + CEA53E0135F75F3243B0F36720469A22 /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextStorageDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift; sourceTree = ""; }; + CF05C45A2F67138ECA96FE19A456DA92 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; + CF58036EDA6186C6EC1D8BC6D74DB5AC /* ItemEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ItemEvents.swift; path = RxCocoa/iOS/Events/ItemEvents.swift; sourceTree = ""; }; + D002139C96A6306EE9B058F61088B34D /* Session.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Session.swift; path = Source/Session.swift; sourceTree = ""; }; + D1AE195A397C30921EED304B8BADF132 /* Concat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concat.swift; path = RxSwift/Observables/Concat.swift; sourceTree = ""; }; + D1FEE76912A6E8FC2242C3F48DC49D8B /* Driver+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Subscription.swift"; path = "RxCocoa/Traits/Driver/Driver+Subscription.swift"; sourceTree = ""; }; + D23B36396D7AB021DB60C837EB036FE1 /* _RXDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXDelegateProxy.h; path = RxCocoa/Runtime/include/_RXDelegateProxy.h; sourceTree = ""; }; + D250D8F7946F2AB945B56880B4CDD35F /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; + D2EA73D174336145C16B4581B24C09AE /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Source/ConstraintRelatableTarget.swift; sourceTree = ""; }; + D3A590980F39515643092D1F757109A1 /* Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Create.swift; path = RxSwift/Observables/Create.swift; sourceTree = ""; }; + D4656B8E22754A0978FDFCBB4C67A0B4 /* _RX.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RX.m; path = RxCocoa/Runtime/_RX.m; sourceTree = ""; }; + D559333329A32BD7831F2E45D4FF16A7 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Source/ConstraintPriorityTarget.swift; sourceTree = ""; }; + D586379F42484F03DE243BA460D48E9F /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; + D6107C17D2C9AC490E84B09E3E310181 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Source/ConstraintInsetTarget.swift; sourceTree = ""; }; + D6D5C72E2C612EAA4B4CEF7A4D0D3479 /* KF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KF.swift; path = Sources/General/KF.swift; sourceTree = ""; }; + D6F5ED8C35455EBE258F138A1802D306 /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; + D798CB81E1C040FD4AF4AEBB9C9FD0A3 /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Source/ConstraintConstantTarget.swift; sourceTree = ""; }; + D8EA5BC052FE1348FF54A000FECB7186 /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift; sourceTree = ""; }; + D8FAB2E960EAC19A564D96AC83373912 /* Sequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sequence.swift; path = RxSwift/Observables/Sequence.swift; sourceTree = ""; }; + D907EC9C19B69B73A37BF27C30B38F05 /* MainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MainScheduler.swift; path = RxSwift/Schedulers/MainScheduler.swift; sourceTree = ""; }; + D96C8448CD7962AF26C90A25D4D1294E /* ParameterEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoder.swift; path = Source/ParameterEncoder.swift; sourceTree = ""; }; + D9D6C9CF4A996C73FDDD4AC8781A22F7 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxRelay/Observable+Bind.swift"; sourceTree = ""; }; + DA8005737AEE2B81D048D33A714C51C5 /* ObserveOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOn.swift; path = RxSwift/Observables/ObserveOn.swift; sourceTree = ""; }; + DC3E9FBB96DD375A4691E77F12BAD394 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; }; + DC48DB40E7345B46179098B3B1AA269C /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Source/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; + DD7C07E445E94C46C60EA60D57ACFC23 /* RxSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-prefix.pch"; sourceTree = ""; }; + DD7C1E2C14FC38CA7DC000E07D73EC59 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; + DF86AE6F99EFEC9B7B0DCA289F5D3DF7 /* Sink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sink.swift; path = RxSwift/Observables/Sink.swift; sourceTree = ""; }; + DF943837465A8C84EE5469F9C9938D3F /* Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debug.swift; path = RxSwift/Observables/Debug.swift; sourceTree = ""; }; + E0874EF395F89BC8B395CAD49E98ECE8 /* AlamofireExtended.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireExtended.swift; path = Source/AlamofireExtended.swift; sourceTree = ""; }; + E11B4424ED13C46FF58813926D87E872 /* Binder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Binder.swift; path = RxSwift/Binder.swift; sourceTree = ""; }; + E1A1D01CFC7263F1507C121415A60F10 /* WKWebView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKWebView+Rx.swift"; path = "RxCocoa/iOS/WKWebView+Rx.swift"; sourceTree = ""; }; + E1FE6F6768DE4B073C442DFEB4EA7C4D /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Source/ConstraintLayoutSupport.swift; sourceTree = ""; }; + E35174A2243D3E1CDC3F2518EBBCEB7A /* AnonymousDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousDisposable.swift; path = RxSwift/Disposables/AnonymousDisposable.swift; sourceTree = ""; }; + E3AD1926FB78B2FA344D6CFDA19C5F93 /* PrimitiveSequence+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PrimitiveSequence+Concurrency.swift"; path = "RxSwift/Traits/PrimitiveSequence/PrimitiveSequence+Concurrency.swift"; sourceTree = ""; }; + E3E9BDD5EBA375AF48858939A1673F76 /* RxCocoa-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-umbrella.h"; sourceTree = ""; }; + E3FCD724B7B1AF75B0FDC252E28E6D0E /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; + E447DD75B5DFC0A94F8F3AA082F16DC8 /* GroupedObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupedObservable.swift; path = RxSwift/GroupedObservable.swift; sourceTree = ""; }; + E6381EDBFEDA485DF5135E051EF6974B /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchBar+Rx.swift"; path = "RxCocoa/iOS/UISearchBar+Rx.swift"; sourceTree = ""; }; + E6663C48732F86BE136321DAE5C8CB4D /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; + E6886B33994444A6EB9CAC1264FF0D5C /* Infallible+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Concurrency.swift"; path = "RxSwift/Traits/Infallible/Infallible+Concurrency.swift"; sourceTree = ""; }; + E70B523D086F737CC0FC6FF2968EF50C /* Deferred.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deferred.swift; path = RxSwift/Observables/Deferred.swift; sourceTree = ""; }; + E724CE2180A86CA9D4D2A7FEF873464B /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; + E85E1CDB9FB613F8CE69DCB854E6B399 /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAssignmentDisposable.swift; path = RxSwift/Disposables/SingleAssignmentDisposable.swift; sourceTree = ""; }; + E8DCCFFDB2CB96005F27FBF226FC2802 /* UIButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Rx.swift"; path = "RxCocoa/iOS/UIButton+Rx.swift"; sourceTree = ""; }; + E9076DC103CA5FE5AAA229FA6D4F12EF /* RxCollectionViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift; sourceTree = ""; }; + E949866D1199DFDAB2026305C0CD9F09 /* RxRelay-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-prefix.pch"; sourceTree = ""; }; + E94D54A724CBA85DBF90033986466C60 /* UIGestureRecognizer+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIGestureRecognizer+Rx.swift"; path = "RxCocoa/iOS/UIGestureRecognizer+Rx.swift"; sourceTree = ""; }; + EAA5A2FDD88E02447CE131F7C5675472 /* _RXObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXObjCRuntime.h; path = RxCocoa/Runtime/include/_RXObjCRuntime.h; sourceTree = ""; }; + EB9D81BE5A997A78B7964B8E92CE0B93 /* _RXKVOObserver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXKVOObserver.h; path = RxCocoa/Runtime/include/_RXKVOObserver.h; sourceTree = ""; }; + EC1E7777904C53C224AD9EC13928AA60 /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalSchedulerTimeConverter.swift; path = RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift; sourceTree = ""; }; + EC93761C8ADB8B00344821B1B009F02E /* Pods-GenderList.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GenderList.release.xcconfig"; sourceTree = ""; }; + ECBE9BBA6EBB5DF07D0B176CF85B2686 /* ControlTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlTarget.swift; path = RxCocoa/Common/ControlTarget.swift; sourceTree = ""; }; + ED61B9E9979F042340DD70C4160F7A62 /* ObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableType.swift; path = RxSwift/ObservableType.swift; sourceTree = ""; }; + EDF28982DEBE7F0803BB0597AA1C3FB2 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; + EE3076DD5597EABB5CD920CFF6E4ACC7 /* Amb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Amb.swift; path = RxSwift/Observables/Amb.swift; sourceTree = ""; }; + EE5CD5014A09A8B5FEF6D3E30B7B776D /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Source/ConstraintViewDSL.swift; sourceTree = ""; }; + EF147A0D663689C5F262DA7E61709115 /* RequestTaskMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestTaskMap.swift; path = Source/RequestTaskMap.swift; sourceTree = ""; }; + F01D8505DC894677CE2FB4DC24B4018C /* RxTabBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift; sourceTree = ""; }; + F060E67EDD1C139F8C56E3FD714779CB /* RxRelay.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.release.xcconfig; sourceTree = ""; }; + F0D2F124FD52C827D1220776CC40AD2C /* RxSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxSwift-Info.plist"; sourceTree = ""; }; + F1F00C8521C329190BE365BA5A431237 /* CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+arity.swift"; path = "RxSwift/Observables/CombineLatest+arity.swift"; sourceTree = ""; }; + F2341A179F0C231C4BC79A8F07E8B04E /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; + F257D204D4CB255CCFEDD0564D96D030 /* ConstraintMakerPriortizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPriortizable.swift; path = Source/ConstraintMakerPriortizable.swift; sourceTree = ""; }; + F40312C667A21EB4D9E6C8005CD1B164 /* RefCountDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RefCountDisposable.swift; path = RxSwift/Disposables/RefCountDisposable.swift; sourceTree = ""; }; + F469F47D809A2E852FFAB72BFFE46D9E /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; + F473180FF0C50A1E0367E1B7E8F08373 /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift; sourceTree = ""; }; + F4AF170ACB6E5383A95764D1A3DA168A /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = RxSwift/Observables/Error.swift; sourceTree = ""; }; + F5DC8DF1D5F1FD3FFAD27AF5B10C367A /* URLRequest+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Alamofire.swift"; path = "Source/URLRequest+Alamofire.swift"; sourceTree = ""; }; + F5E0AE7C857ED5E9B5ECF6AD1EED8E82 /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; + F662A60ECDBE45A7F551522E8372BFA0 /* Pods-GenderList.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GenderList.modulemap"; sourceTree = ""; }; + F71E05F1DEEA7FF4B426AFE545A829DF /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; + F816B43767B379812F884C578D631E88 /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Source/LayoutConstraintItem.swift; sourceTree = ""; }; + F81CBB69E8A5AE33C9EBECB5F6529AC5 /* LockOwnerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LockOwnerType.swift; path = RxSwift/Concurrency/LockOwnerType.swift; sourceTree = ""; }; + F821FA477D5CBC2A029AB6C504983C90 /* RxTableViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift; sourceTree = ""; }; + F8A05DCE6FA0242DB558250D79B85A28 /* ReplaySubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplaySubject.swift; path = RxSwift/Subjects/ReplaySubject.swift; sourceTree = ""; }; + F9281DB73C863EE56557931C895FA070 /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; + F934FE3C0472E89EDA71BECB5FC29245 /* HTTPMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPMethod.swift; path = Source/HTTPMethod.swift; sourceTree = ""; }; + FAAF3645DF88E1E0DA21560E63737408 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; + FADFCB60B88A2B9122979E57337B8D47 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedUnsubscribeType.swift; path = RxSwift/Concurrency/SynchronizedUnsubscribeType.swift; sourceTree = ""; }; + FAE5C37C514852C880072749300AF8A5 /* GraphicsContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphicsContext.swift; path = Sources/Image/GraphicsContext.swift; sourceTree = ""; }; + FB4AC18518632E482B180EC7A9807907 /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Source/ConstraintMakerEditable.swift; sourceTree = ""; }; + FB92E87126CB99BA3210A3EC1AE61DF3 /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; + FC6172868C69E6D61153FD817422A036 /* EventMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventMonitor.swift; path = Source/EventMonitor.swift; sourceTree = ""; }; + FC7BEB23F49CED3D68E031F723F0BDD0 /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; + FE0809DCB644EA1525EA9CFEE9018507 /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; }; + FE75E6B4CC424ABF9C8A7EC4DD4517C7 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; + FF13E01C557A0B7AA31D6B77F42EB22B /* Window.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Window.swift; path = RxSwift/Observables/Window.swift; sourceTree = ""; }; + FF638C997821B67CFD87ED2784B2BCF1 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = RxSwift/Observables/Filter.swift; sourceTree = ""; }; FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = RxRelay; path = RxRelay.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FFA5D1BD0FAEAB4E04B446CB9E483DDE /* Range.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Range.swift; path = RxSwift/Observables/Range.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 6CDBE85C1FF2D1940AA1F0F792DCC589 /* Frameworks */ = { + 15DC142A7EE833251AA37FC8E2B8E01F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - B6AF48158CE1D31ACA8A57437E3EFD1F /* CFNetwork.framework in Frameworks */, - 501191C24EA7EF2F675F90E12EC61B0E /* Foundation.framework in Frameworks */, + 7B068137A8925891446203B5D3D6A4ED /* CFNetwork.framework in Frameworks */, + 0F4037DBF307AC8058BD0A3D35C7E7E9 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 79906E3FD9696ED1D66D5AD4FFFE0FDF /* Frameworks */ = { + 45D55D72D6D5C20BC82FF77452BE7744 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D8BA9FB2C1FDE670C3B999DB1F42A67 /* Foundation.framework in Frameworks */, + AD0DA93E31995012541F4FB0C826E7D1 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -988,410 +996,425 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B3FD44A81D6BB69C90D069361E98B2A6 /* Frameworks */ = { + D474762EDAD769DDF562D7338F7F3590 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8BF59E920DC561A9F071F6D2860A9B99 /* Foundation.framework in Frameworks */, + 4BEFD05346081CE7797BBA2F6C9DC363 /* Accelerate.framework in Frameworks */, + 3315E95E92C3EC0D0D28A68819FFCC38 /* CFNetwork.framework in Frameworks */, + 566E1BD667CCAEF237B605D80A10C5E3 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D20FE8C9788757E0BF68768B4C17D59A /* Frameworks */ = { + E4AB0452F719F6CBD11E27B1B3ECC4E7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2DA79588D9A8DEC192452C4A212F821F /* Foundation.framework in Frameworks */, + F4455C957BC8D1C80898FDC9E0D93465 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D474762EDAD769DDF562D7338F7F3590 /* Frameworks */ = { + E877FC0D3719519B688F3E17FF0228B2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BEFD05346081CE7797BBA2F6C9DC363 /* Accelerate.framework in Frameworks */, - 3315E95E92C3EC0D0D28A68819FFCC38 /* CFNetwork.framework in Frameworks */, - 566E1BD667CCAEF237B605D80A10C5E3 /* Foundation.framework in Frameworks */, + 2987A730911012C32AF6695D7B54E35C /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - E877FC0D3719519B688F3E17FF0228B2 /* Frameworks */ = { + ECFF7A1DCB8C536B1B8981BC7123E8CF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2987A730911012C32AF6695D7B54E35C /* Foundation.framework in Frameworks */, + 86DD807C261B13BFB5EDA57B449D255E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */ = { + 03709846C0CA49F4A06BAA7ECD71EAA5 /* RxRelay */ = { isa = PBXGroup; children = ( - 5EE21CBB8EFB615AB450D209E054FAE6 /* iOS */, + 9DF9A1F6E5E6B9C758E8ECEB280377DF /* BehaviorRelay.swift */, + D9D6C9CF4A996C73FDDD4AC8781A22F7 /* Observable+Bind.swift */, + 0027F0EFDE7EF07B89CC7DD7A26BBC04 /* PublishRelay.swift */, + 447E398F3949913B7D8AC3A555E97D6E /* ReplayRelay.swift */, + 477B069BB8F7AFF056C4DFCDCB34D983 /* Utils.swift */, + 4FAEDA7754D51F64CF458BFD576CD4B5 /* Support Files */, ); - name = Frameworks; + name = RxRelay; + path = RxRelay; sourceTree = ""; }; - 0CE845F38E5EDD1B75746735A2D910A2 /* Pods */ = { + 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */ = { isa = PBXGroup; children = ( - E5D391B1BA7DB41E05B868639D18F32B /* Alamofire */, - F28F6B6A96993CF1D0660DC067A15765 /* Kingfisher */, - 51667FC6D45FACDFCD4AA8294DED8880 /* RxCocoa */, - F80A4E53B661E1E1D22C0E498171F559 /* RxRelay */, - 2F64A655370BC215ED76A5444B5BFD97 /* RxSwift */, - 8F1F777D8F77F373A9D61D1CD6EE1B61 /* SnapKit */, + 5EE21CBB8EFB615AB450D209E054FAE6 /* iOS */, ); - name = Pods; + name = Frameworks; sourceTree = ""; }; - 22C54E34AE5A13837A9CB189FF4844DF /* Support Files */ = { + 1E273235868D3EB9828064D8F80F060C /* RxCocoa */ = { isa = PBXGroup; children = ( - 8795F9C24E8EEBF4399FB16C4A213174 /* RxRelay.modulemap */, - 517A605109B9601443F76406285A2E74 /* RxRelay-dummy.m */, - 66C4A8CDB4B63101810861A42200B095 /* RxRelay-Info.plist */, - CF9D4F784D11A2A619A5B91A0B218600 /* RxRelay-prefix.pch */, - 7A4A33D4EBD87311076E540A7ABFA143 /* RxRelay-umbrella.h */, - 2B7CB3FCA9A4B086818B0611E2E9A449 /* RxRelay.debug.xcconfig */, - 3C18A26F23ECE9BE8D5B1A6A198A0600 /* RxRelay.release.xcconfig */, + 87C197CF31D13B491047064857E79C4E /* _RX.h */, + D4656B8E22754A0978FDFCBB4C67A0B4 /* _RX.m */, + D23B36396D7AB021DB60C837EB036FE1 /* _RXDelegateProxy.h */, + 5DEA69A88EF4071C8F5957A614F62B71 /* _RXDelegateProxy.m */, + EB9D81BE5A997A78B7964B8E92CE0B93 /* _RXKVOObserver.h */, + 2EB34FAA6EAA0B3F9D1FDB51584A5A76 /* _RXKVOObserver.m */, + EAA5A2FDD88E02447CE131F7C5675472 /* _RXObjCRuntime.h */, + 65E38C9F179F1817B63D21E6B8042079 /* _RXObjCRuntime.m */, + A71FF01397BCF8E5126F7DB2781F9A19 /* Bag.swift */, + B0A095E2B75D2E3DB3B274F8F8A4CF92 /* BehaviorRelay+Driver.swift */, + 9738AD838D2B289843146F132AB003E9 /* ControlEvent.swift */, + BC0A930E95F275B6B5E02AE3F3FF030D /* ControlEvent+Driver.swift */, + 5D761FAD304D3B41BD183F4BF6B6CF99 /* ControlEvent+Signal.swift */, + 03631B268C3CCC37CED157024CF4D3DD /* ControlProperty.swift */, + 5D25D7E510A6EBB96395707104EF360C /* ControlProperty+Driver.swift */, + ECBE9BBA6EBB5DF07D0B176CF85B2686 /* ControlTarget.swift */, + 741FCF6FD88310101424A7ED16D279BF /* DelegateProxy.swift */, + A15A5CB1859AE914F9A4883C909C1D04 /* DelegateProxyType.swift */, + EDF28982DEBE7F0803BB0597AA1C3FB2 /* DispatchQueue+Extensions.swift */, + 5AAF61DCEE7EF17C7D4E598C5194836D /* Driver.swift */, + D1FEE76912A6E8FC2242C3F48DC49D8B /* Driver+Subscription.swift */, + 92C4B6FEBA77235BB4623831F8AED445 /* Infallible+Bind.swift */, + 806A2A4C9A4D1D5500BE72BFA6B13F91 /* InfiniteSequence.swift */, + CF58036EDA6186C6EC1D8BC6D74DB5AC /* ItemEvents.swift */, + 444654C800FF5388EA6EAFCE09425593 /* KVORepresentable.swift */, + 0765B4EEB54FAC58B8234A058FA33E51 /* KVORepresentable+CoreGraphics.swift */, + 291F7C069F9E079F932FDD60D8FEFA7D /* KVORepresentable+Swift.swift */, + 38E3773C87AB71FEFF099FBBC70AB837 /* NotificationCenter+Rx.swift */, + 2AA689679D51D3F44B5448DA52B49346 /* NSButton+Rx.swift */, + 8BB4260CF2A46B845613C59B79940D4E /* NSControl+Rx.swift */, + 10D5ADFC37FC97F51CA8E4B68AC314C9 /* NSObject+Rx.swift */, + 1E8EEC36578F8DBF0309DD73B87D4329 /* NSObject+Rx+KVORepresentable.swift */, + 70A10D5A2BD6546E0640BE73E3A4B3D2 /* NSObject+Rx+RawRepresentable.swift */, + 08A61FACE4DC58B6D63CDA2105EE1C2F /* NSSlider+Rx.swift */, + 5DFFF2012F5791E774C912AC86DDCE0D /* NSTextField+Rx.swift */, + 42B9A7E0A2CEEFFF576B51280B8D3A4B /* NSTextStorage+Rx.swift */, + 4C9E473E4E1B5852EBD81E325E2B5C4D /* NSTextView+Rx.swift */, + CA0F4A1959721B796E0302A27F5EEDAA /* NSView+Rx.swift */, + 776DFD1F3CBB65E70DE70D6103601433 /* Observable+Bind.swift */, + BFF69ED1FA9497A9E9861EBDB2ABF203 /* ObservableConvertibleType+Driver.swift */, + AD98DA4FED7C52AA2D77259CBF98E81D /* ObservableConvertibleType+SharedSequence.swift */, + 2E65E3AAF488477C388FE9A469DDD299 /* ObservableConvertibleType+Signal.swift */, + CB22C6A389B7E966F793D95F308B669C /* Platform.Darwin.swift */, + 2424AF78DDEE23C54679665B2E11CECA /* Platform.Linux.swift */, + 0B5A237F228CBE682B896D5145A8F585 /* PriorityQueue.swift */, + 71DE11D37B0EB2DC6721E198C5B7BB94 /* PublishRelay+Signal.swift */, + E6663C48732F86BE136321DAE5C8CB4D /* Queue.swift */, + 6335C0CBDFEB0A267F383DF5A5D0E209 /* RecursiveLock.swift */, + 20804B3A6BAEA5B63222084242339F53 /* RxCocoa.h */, + C7449A6095EB1BA269B3C2B73CBDB28D /* RxCocoa.swift */, + A5532071B77604F3BDCDCAD049CC3294 /* RxCocoaObjCRuntimeError+Extensions.swift */, + 9044CC20197AD853A260B3EA7AA3E5B5 /* RxCocoaRuntime.h */, + 3CE870C8AB56EBCF98D6D45D93FC0603 /* RxCollectionViewDataSourcePrefetchingProxy.swift */, + 7BE60A9AB9690D6EC4D6CB050F76F0AD /* RxCollectionViewDataSourceProxy.swift */, + 07A793D684FC253E04E29A6CA931906E /* RxCollectionViewDataSourceType.swift */, + E9076DC103CA5FE5AAA229FA6D4F12EF /* RxCollectionViewDelegateProxy.swift */, + D8EA5BC052FE1348FF54A000FECB7186 /* RxCollectionViewReactiveArrayDataSource.swift */, + B5C7D6CA2E239A1CAAB0805B3EDBDD3F /* RxNavigationControllerDelegateProxy.swift */, + 5CD2C62A0338F3123A15A325CF410C46 /* RxPickerViewAdapter.swift */, + 06041DE6F931C543695D7F87CD91C6C9 /* RxPickerViewDataSourceProxy.swift */, + 5D6F90B890CCCC1B401070F43B61779C /* RxPickerViewDataSourceType.swift */, + 5D865B2EF3338D285050AFD9717880B6 /* RxPickerViewDelegateProxy.swift */, + 579FA3521C9FD6CB4DCCB1B2CEF7982D /* RxScrollViewDelegateProxy.swift */, + 549CAA2B2EDE8AD94C5988D95A8829E5 /* RxSearchBarDelegateProxy.swift */, + 9C300A4562E606959DBC2D95A38D347E /* RxSearchControllerDelegateProxy.swift */, + 49839FCD719095B1D043C2DB596E3B40 /* RxTabBarControllerDelegateProxy.swift */, + F01D8505DC894677CE2FB4DC24B4018C /* RxTabBarDelegateProxy.swift */, + 5B0C7B81DA43217A2842F181A0413B81 /* RxTableViewDataSourcePrefetchingProxy.swift */, + CD31B7D0E44D1C6D267C74B719E9C93E /* RxTableViewDataSourceProxy.swift */, + F473180FF0C50A1E0367E1B7E8F08373 /* RxTableViewDataSourceType.swift */, + F821FA477D5CBC2A029AB6C504983C90 /* RxTableViewDelegateProxy.swift */, + 9B8AB683D3CE1BC246D1C753622BC4FC /* RxTableViewReactiveArrayDataSource.swift */, + 153B6B55AB85C7976FD527FD7D896CFE /* RxTarget.swift */, + CEA53E0135F75F3243B0F36720469A22 /* RxTextStorageDelegateProxy.swift */, + 9B07F4E91969B4B4290F4E935C528AC4 /* RxTextViewDelegateProxy.swift */, + B4715F04958933344007626908174565 /* RxWKNavigationDelegateProxy.swift */, + AB2F7D87FA65948E65985C245E90F30D /* SchedulerType+SharedSequence.swift */, + 31BB1AECA99796B254CE53707A66D22E /* SectionedViewDataSourceType.swift */, + 89BA94ED52F0795DC30B8EDF36697174 /* SharedSequence.swift */, + 99427CA80A669FE028CF88825B36EACF /* SharedSequence+Concurrency.swift */, + 8F28559ECB31ED01EBF30485A89354E9 /* SharedSequence+Operators.swift */, + A8ABD7704AF8D558B05DBFE563C8BFB8 /* SharedSequence+Operators+arity.swift */, + 3E502569324A3191D2009A6E9CD8CAF3 /* Signal.swift */, + 96BAD09D260831792CA65A8C5971A26C /* Signal+Subscription.swift */, + 4724C270B204A600A8253615CC123F48 /* TextInput.swift */, + 807ADE91E070BDDFA8FC7E6D0CAAD435 /* UIActivityIndicatorView+Rx.swift */, + 2D2324A70BFC56DC0C74F69EC2072986 /* UIApplication+Rx.swift */, + 1EA0DB41F8746732351623A4D6285F83 /* UIBarButtonItem+Rx.swift */, + E8DCCFFDB2CB96005F27FBF226FC2802 /* UIButton+Rx.swift */, + 8FDF6CD75C1834270FDEB7F5D0F2BCB1 /* UICollectionView+Rx.swift */, + 944092E0A468F6032639BB3DEFC353BD /* UIControl+Rx.swift */, + 0CB614DA2D2E0151F1A14D72578F6B1B /* UIDatePicker+Rx.swift */, + E94D54A724CBA85DBF90033986466C60 /* UIGestureRecognizer+Rx.swift */, + 8292E3BE05ACD436F29CF9A67287A8DF /* UINavigationController+Rx.swift */, + 748BD5FEAE0F1BDC45114CB14C6322A4 /* UIPickerView+Rx.swift */, + C326389654418C163F0542532BC17110 /* UIRefreshControl+Rx.swift */, + 0E4604F79F3B7F16F870C0140292283C /* UIScrollView+Rx.swift */, + E6381EDBFEDA485DF5135E051EF6974B /* UISearchBar+Rx.swift */, + CBC08F9FA24E20B061964BC084936292 /* UISearchController+Rx.swift */, + 191771D857A79C686B98B8202157674F /* UISegmentedControl+Rx.swift */, + ACCBD4C0C85A487DCD856558486F38E2 /* UISlider+Rx.swift */, + 5AEF374C7E373EFFF865471106A1FCEC /* UIStepper+Rx.swift */, + 230C05CE94222C563407E135A09FE52B /* UISwitch+Rx.swift */, + B7CFF041D4E96A90F3CCF914CB009E40 /* UITabBar+Rx.swift */, + CCE3665D6C88438C0AC4433967269C3F /* UITabBarController+Rx.swift */, + 69679F318A371FDD8C42439C3FE25586 /* UITableView+Rx.swift */, + A98553727E761D8D5A0BC081285ADE9E /* UITextField+Rx.swift */, + 11B01A2390CA2DDDD676D1A67BD0C02D /* UITextView+Rx.swift */, + 6B0156512CBF5584A1DB161E180766E1 /* URLSession+Rx.swift */, + E1A1D01CFC7263F1507C121415A60F10 /* WKWebView+Rx.swift */, + 89B87C98E9F9390A945FD3489BC6752C /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/RxRelay"; + name = RxCocoa; + path = RxCocoa; sourceTree = ""; }; - 2F64A655370BC215ED76A5444B5BFD97 /* RxSwift */ = { + 1EE46838A2C7708E276009190038625A /* RxSwift */ = { isa = PBXGroup; children = ( - EAE4529CDBEBC039DFAA7036AB45EE30 /* AddRef.swift */, - BB3816ADA06410A6B7793234D38F84D5 /* Amb.swift */, - 7015A2723C7EB58E15977193C5ADE30A /* AnonymousDisposable.swift */, - EF2AE61FD67D2D52D425F6BED79AE568 /* AnonymousObserver.swift */, - 1FB0AB5EBB9EAF18968D0715DC6473EF /* AnyObserver.swift */, - 1D335E71CC0ADA589EE65F467A506799 /* AsMaybe.swift */, - E7555D68AECBE9EC9B6D36A0AD9B6038 /* AsSingle.swift */, - E23433B6C5425020E1F9ABB659C33A82 /* AsyncLock.swift */, - 34F34C3DFEA45CA618A7BD11A7ED48D9 /* AsyncSubject.swift */, - 682485D6700D5F4F209B3D7E8409414A /* AtomicInt.swift */, - 2E679291E767C8D0045D70F6E1FE6558 /* Bag.swift */, - AB73CA1C3F8B703DE2C884659A31C2D7 /* Bag+Rx.swift */, - 67DD57B81172C762BFE739FC04F4D21E /* BehaviorSubject.swift */, - 4932F8F6F0A427742452AC9CF0D58C77 /* BinaryDisposable.swift */, - 1ED812CC3A0ED3E6BCCFCA3EA27368A3 /* Binder.swift */, - 2D8EBCDD6EB54DCDDCA65563CF324CDA /* BooleanDisposable.swift */, - 53AD78AE798D875C99318D5D0912F543 /* Buffer.swift */, - 687E155797AF351961D6BEEF1A2766F2 /* Cancelable.swift */, - 267A04DBC3322B5D3D8402EC66199CD1 /* Catch.swift */, - 6FF013F915831C54C604373BFD7FF75D /* CombineLatest.swift */, - 0E7DB5BA65C1FFABAEC78D90F6FDC6C8 /* CombineLatest+arity.swift */, - 94775AC80AD2CDC009C836D6249E04B5 /* CombineLatest+Collection.swift */, - E21D0733C912FD68451BD423ADC83E4D /* CompactMap.swift */, - 53D07AA6A24B29A203133E60FC50D7BB /* Completable.swift */, - FA0410C906661C5ECBB5A94E5BEDBA52 /* Completable+AndThen.swift */, - BBABFFF76C76A9D5D8DADB1EDE58F23E /* CompositeDisposable.swift */, - D4B8B6B28C084865856AD6D49550E430 /* Concat.swift */, - 9F00B9A5E2C77D491F42C7A323D89434 /* ConcurrentDispatchQueueScheduler.swift */, - 7AD5FC6299043CD5F0F76E73F4F7411F /* ConcurrentMainScheduler.swift */, - 90FD593F6533CBAE30159E9909FB238D /* ConnectableObservableType.swift */, - EBFBAFDA9E115C3FA592178ABCB160FA /* Create.swift */, - 68F413AB8BC1E3A11E7767EE9B3B3B0E /* CurrentThreadScheduler.swift */, - BF9F98E08158E504E673C919AF746700 /* Date+Dispatch.swift */, - 60F565743D0E0A3EFD781A8F8A9B51CD /* Debounce.swift */, - 96399A3F19C97048BD73AC6C016447AA /* Debug.swift */, - 8502AB6F24119364EC6FFAC9C51D8B72 /* Decode.swift */, - 837D68EC9B5FF19849A4309C9D50C12F /* DefaultIfEmpty.swift */, - 3DFD8B7C287CE97937818BB36E6D0F7C /* Deferred.swift */, - A5E3B733BCCBB62B59FD06B8C437FF95 /* Delay.swift */, - CF937DC1BF9020E271091491FB8CF954 /* DelaySubscription.swift */, - 31A72DC794794857921D83CFBABFD01B /* Dematerialize.swift */, - E049D95E456C13016DBD029DF097E38B /* DispatchQueue+Extensions.swift */, - 5C475814CC7778BF88A47494A1117A28 /* DispatchQueueConfiguration.swift */, - 002820526DCF691DEE139BFF1455D570 /* Disposable.swift */, - AB3D593961945959F1A44BE5C05C5A58 /* Disposables.swift */, - 152DA282A487530C176A0B25C8DF6883 /* DisposeBag.swift */, - FB8FFF121EEF33CEBB22766BD88B0155 /* DisposeBase.swift */, - 9FF0A54173D4CF241D535F100AB21A1C /* DistinctUntilChanged.swift */, - 5240A0E2DBF5D9ECEF0F5D53B084DDF2 /* Do.swift */, - 7C96CEE8260D1D4000BBBEDFB62CD8D3 /* ElementAt.swift */, - 4169B421DBD9C0157729FCA9836C9DAE /* Empty.swift */, - 96B99BA47A5EBF3E66630684A8F212DD /* Enumerated.swift */, - 2395D2D816592B47A30CF5C10787ECC7 /* Error.swift */, - 97CE79655B8A34D6270A73B843CF2271 /* Errors.swift */, - 1695D8C618F845EEE48F2BB9379A7BF4 /* Event.swift */, - 545F2DDE7D8FF39935F86D5FE27C8CC4 /* Filter.swift */, - BBCE1CAEA27D5FDE3D9D901415378A20 /* First.swift */, - C16AEBDE0AC9FA3063D48EE7921A25B1 /* Generate.swift */, - F6DDE21B51F954F2DCA17A42FA6C7DF9 /* GroupBy.swift */, - 2453D0762FE79905E9AA9C5F5C3A5E75 /* GroupedObservable.swift */, - 9CE3B739A608F0DDAD0F2DE37083707A /* HistoricalScheduler.swift */, - 406336451769C4ABD13D928D18C358F6 /* HistoricalSchedulerTimeConverter.swift */, - 5B439B367CC6C89C100ED8B736E470FA /* ImmediateSchedulerType.swift */, - B47FE5B477CC9C18416010929166F7DC /* Infallible.swift */, - BC6D96E71D0D40BFA9ED18FE23078F8F /* Infallible+CombineLatest+arity.swift */, - 852B3F5F7CAC90F024AD13ABCCFB986C /* Infallible+Concurrency.swift */, - 7B5FE232EFFF73B7C3D25288BA3912B7 /* Infallible+Create.swift */, - 32193DD28EB90453567A59F1A182F96D /* Infallible+Operators.swift */, - 562B01E7D1CBAA099413E50DB98212AC /* Infallible+Zip+arity.swift */, - D9F047AFE79DA1C753989691948402E8 /* InfiniteSequence.swift */, - B6EDE4C2E94C7299D615D4615B12B896 /* InvocableScheduledItem.swift */, - C45144499497DB482329E52115E128E3 /* InvocableType.swift */, - DE62662A2D55BF8E43A8AE661CC6EDE4 /* Just.swift */, - A2BC13603EB21A257F88ADDCDBB022C8 /* Lock.swift */, - ED95C7C562A3738CF2D4BF66BADF61F5 /* LockOwnerType.swift */, - 0CFD4EB1A0879E8DE5C3EE9C693DAA55 /* MainScheduler.swift */, - E618A494A482B3DEC86B81C1AD1D365F /* Map.swift */, - 60ED99EA71CABA14574423D41AB0E5A3 /* Materialize.swift */, - 1A52FCBFBDBFDA727757BADAC2FE4D7D /* Maybe.swift */, - FBF80ED92B3DEF5D9EE1A157A9E17442 /* Merge.swift */, - E1057D4EB481C24ACA874B22DB4B986C /* Multicast.swift */, - 49867C97EAB05F3879541A4853891A4B /* Never.swift */, - 2A91950D5DC29F11BD39F3AD4EE89E6B /* NopDisposable.swift */, - B9F67A58719C517741D63F9EAC3F24D6 /* Observable.swift */, - 2BF9BDC107FFB51F0879071F69E589A6 /* Observable+Concurrency.swift */, - EC0527510AA2DB17EAC9D3E218CAA163 /* ObservableConvertibleType.swift */, - 9E0A868C9971CDD7B0B6C688E3643774 /* ObservableConvertibleType+Infallible.swift */, - 0C240573DDD75AB5F81D423C5E2EFA0A /* ObservableType.swift */, - 9583D07CFEC32E9B920EC112BDCF8F1E /* ObservableType+Extensions.swift */, - B79B95D1B2DDEC221F61E2BACEDAF527 /* ObservableType+PrimitiveSequence.swift */, - 4FDE8944CE97206B2673253F9C20298B /* ObserveOn.swift */, - 5378FB89697FC8EA7FBC2EFCA76477CB /* ObserverBase.swift */, - 7E7B9C74BBBFA3CF7A52FD8918555C8E /* ObserverType.swift */, - 6C4C951A1EF580FD0454E47472A52DEA /* OperationQueueScheduler.swift */, - 3CE28AA56B38DACFBC04F7C8F4EA5984 /* Optional.swift */, - ACEDFBBA5F76F3B47E6A904879318588 /* Platform.Darwin.swift */, - CFCFD51497C9110708C858EA2C19368C /* Platform.Linux.swift */, - BA03DC4A3F895B6A381043F1C17753B7 /* PrimitiveSequence.swift */, - BE032E5A6B45556B1CE4035AB8300BC7 /* PrimitiveSequence+Concurrency.swift */, - 004354BDA07A0416EB9F2950BD343B6A /* PrimitiveSequence+Zip+arity.swift */, - 491B41F720BE34BE7F38E64B20E5F772 /* PriorityQueue.swift */, - 0096AB1EA15E66D9C5112DE4712A1426 /* Producer.swift */, - 6B3A7C706BF0A33310C00DB4E7422EF6 /* PublishSubject.swift */, - D9781B0EC24FD1296469FF205F8FB810 /* Queue.swift */, - A102DCE673A0A9A983D6DE36965791A1 /* Range.swift */, - CBDF289925E0A8E8FE110FC2EE0FC5BC /* Reactive.swift */, - CDB1D196B882ED38EFB67CDB8058A6DA /* RecursiveLock.swift */, - 037BD3F6EA04A1FC02F2B43610E6A808 /* RecursiveScheduler.swift */, - AFBE121C04BB773EBAADCF4FEF232E49 /* Reduce.swift */, - D3311B6D4D057AD143CB7E74A0B1E1E5 /* RefCountDisposable.swift */, - CE614EF7725D1080DC262AA7AF3B9C30 /* Repeat.swift */, - 6715A6CAA80600D08EC4B8F2671014AD /* ReplaySubject.swift */, - 4A70846FD158CE4ABA153F2AB82F1051 /* RetryWhen.swift */, - C78AA19DC4AE9B2EE6F6022F07E84E07 /* Rx.swift */, - CCCF2EE2D7FDC0AD69FBC3A1B95A1486 /* RxMutableBox.swift */, - 5250B99AAE6D169C5028D00075D20CBA /* Sample.swift */, - 44272824E10DE63C3D91E362DAC954CE /* Scan.swift */, - FA742B9CCC6986A75BCC203D8A301748 /* ScheduledDisposable.swift */, - EA6203B0A1D8270B6CE3B525E6F7ECE3 /* ScheduledItem.swift */, - 4EE696321DE0FE56CB61C37952EE0F2A /* ScheduledItemType.swift */, - 56B0287E747640F717C72FCFD5602A81 /* SchedulerServices+Emulation.swift */, - 9FE24B1808CCB08EBA787BC2F6C8C9C2 /* SchedulerType.swift */, - 3B96619905B442A12C1F2C65DCC72F9D /* Sequence.swift */, - 9884F54F21ABFA557C53E40DD34E35B3 /* SerialDispatchQueueScheduler.swift */, - 6AD1E7581C086DB0A3C8E579FB4664B3 /* SerialDisposable.swift */, - 509C092A271A374B7335A91F29349033 /* ShareReplayScope.swift */, - F56F39816D76F06712167096FF3E3A5F /* Single.swift */, - 7085CE1B5550909B6FB91DBF692233F3 /* SingleAssignmentDisposable.swift */, - D0B578AF8941617056FE4E294D356E78 /* SingleAsync.swift */, - C26EC0D0D63F0FB850F30A10CBE850E2 /* Sink.swift */, - CFD28848184CFC8F2669F9C7B6F3ECA9 /* Skip.swift */, - 5B0FC9E7F5D5E10E8BA353C0F145507D /* SkipUntil.swift */, - E4C954C71FA7E915CF61F045E29B4866 /* SkipWhile.swift */, - 2C3BE0AFF952A3AAA8373E044BBADAE7 /* StartWith.swift */, - F3EB20F3A45D6B29A3E978F87182B9C0 /* SubjectType.swift */, - 07F26138B76C48A68119CBAD2AC7F749 /* SubscribeOn.swift */, - 2A38E734191D770256D5CA30A7EB1BFE /* SubscriptionDisposable.swift */, - E02491ED736B233DE2EA307C1EB3E2B9 /* SwiftSupport.swift */, - A53773ECF7488C9D01CE5D439FCC2F8A /* Switch.swift */, - 09F6B34177CDA13EEC9692109D9630D5 /* SwitchIfEmpty.swift */, - 3E18733EF8F0BF82670E3C3E41AD6A82 /* SynchronizedDisposeType.swift */, - EDF6BA90952A9B09B459D0A010FFF4CB /* SynchronizedOnType.swift */, - B12F9ECAACAE51F90B804AABFCBF3650 /* SynchronizedUnsubscribeType.swift */, - B041565AEEC2F2E374E5AEA0A1805FBA /* TailRecursiveSink.swift */, - 042A5EC597C796CAE77BFA7517A5593C /* Take.swift */, - 38F45BA184E5E0716F4908F767BD7B3A /* TakeLast.swift */, - 410747E8F9D1164844C9D33F86671DD5 /* TakeWithPredicate.swift */, - 0CA874964DCD7DA61F687EC29CF0182D /* Throttle.swift */, - C87C76EEE158FB9F89ADF843A9FDC6ED /* Timeout.swift */, - 448120BB0477A55852FA955184FE5616 /* Timer.swift */, - 49961095D3E6AA7114010352F9D8D866 /* ToArray.swift */, - A44A26151470999E8036AC468A9C1372 /* Using.swift */, - 0752E2033E127DDECCBE3EBF5AED6438 /* VirtualTimeConverterType.swift */, - ACF8BDA55CB353142EEB66AD26161D10 /* VirtualTimeScheduler.swift */, - D93865933C5B3EEC7A6744968D58B8B1 /* Window.swift */, - ADB2003C180AFB52A18317561E6EC5CE /* WithLatestFrom.swift */, - A1B19C706685F1007CFA37D8B72F4A84 /* WithUnretained.swift */, - BA51397293F7F7DE9320460FD4C14042 /* Zip.swift */, - CA67DA9621D034A48C86105DBADC18FE /* Zip+arity.swift */, - CF507A128B1048F9A9506E5EF8DD94E5 /* Zip+Collection.swift */, - 5931C0771A99DF66D5B772E382C666C5 /* Support Files */, + 9E252F71811BA2A0DF5FAEDA77B3D86D /* AddRef.swift */, + EE3076DD5597EABB5CD920CFF6E4ACC7 /* Amb.swift */, + E35174A2243D3E1CDC3F2518EBBCEB7A /* AnonymousDisposable.swift */, + B81CC2EC16DFF3718AF037BFE08AF4F7 /* AnonymousObserver.swift */, + B425BCF674CEF3AA80353C753E6527DB /* AnyObserver.swift */, + 22728DB59B0890DE4D0BFC938A5E5319 /* AsMaybe.swift */, + 25AA7B62A9465F5790FFF2F2F453B872 /* AsSingle.swift */, + 5097A478504A238C6105200FB47B7522 /* AsyncLock.swift */, + 18DCE52506087CF4CC559E58DD403801 /* AsyncSubject.swift */, + 7146CCCBE0B9901F601E355C2966BD1E /* AtomicInt.swift */, + 15C5A7079392E548086A0C4C9D64BB20 /* Bag.swift */, + C0E4B80AD9F51FD88A2D7B3262518209 /* Bag+Rx.swift */, + 92C6D703ECB03FF623920A2ABBA1C984 /* BehaviorSubject.swift */, + 1040B8497C8CA28E0B37F77BDC2744F2 /* BinaryDisposable.swift */, + E11B4424ED13C46FF58813926D87E872 /* Binder.swift */, + 939BBB23FED848AEA8A9A3782F5BB566 /* BooleanDisposable.swift */, + 3FE0EBD2D580EC665875B83BE0B38369 /* Buffer.swift */, + 6484BB20C4A334B3CA255803D52D0AF7 /* Cancelable.swift */, + C234656CE4C4E9C9ADB150EC38A6316F /* Catch.swift */, + 5376CA15D3279EF75237B1C406400270 /* CombineLatest.swift */, + F1F00C8521C329190BE365BA5A431237 /* CombineLatest+arity.swift */, + 16207E1B4EEA0AF791AE4F11AF03C42A /* CombineLatest+Collection.swift */, + 8F9DB5DEEFE0943EE6183585AD693D22 /* CompactMap.swift */, + ABA6E66779D1E9F9B8001B7D359D02EA /* Completable.swift */, + A7F1E6B2FA0343E7E89E81C88CC672A3 /* Completable+AndThen.swift */, + C047D0F4457085742D9DF66A00FACEE0 /* CompositeDisposable.swift */, + D1AE195A397C30921EED304B8BADF132 /* Concat.swift */, + B0257C7F85074973CEFF9BB412C5B41D /* ConcurrentDispatchQueueScheduler.swift */, + 3F31398DA34BA86AB6669FCF1628199E /* ConcurrentMainScheduler.swift */, + 6D74B49F8F212BDF24A91CA248B5EFD1 /* ConnectableObservableType.swift */, + D3A590980F39515643092D1F757109A1 /* Create.swift */, + 29A8D5E730EDA418197D591546FAB0A8 /* CurrentThreadScheduler.swift */, + 5DCFBB65EFC4BB3B34271DEEEF799093 /* Date+Dispatch.swift */, + 9F97DD8D894161C3532CA0B9B171A9FB /* Debounce.swift */, + DF943837465A8C84EE5469F9C9938D3F /* Debug.swift */, + 0C06A78851D368C99335C77AE88F54C2 /* Decode.swift */, + 41D6582E0936ACC2199801C4FE13E4DD /* DefaultIfEmpty.swift */, + E70B523D086F737CC0FC6FF2968EF50C /* Deferred.swift */, + 9B8074DCF34AA82F470D83BE9AFA22EA /* Delay.swift */, + 5E8A7F6C8121A6FA3F53FCA8F53EA8FA /* DelaySubscription.swift */, + 9B6D7EC7AFB179E41E13D4BD2C664704 /* Dematerialize.swift */, + 42663476A9313F46565756E7E95ED5AB /* DispatchQueue+Extensions.swift */, + C0E32787F7DBEBBED4C99A7FFD8F195D /* DispatchQueueConfiguration.swift */, + 88509CE697A792FDB49CFA1BB4ACA90D /* Disposable.swift */, + 2898579A8710C12A1F5B70B4A455D8F6 /* Disposables.swift */, + 517BDC1669294A148E4DBFD5B37E4CA0 /* DisposeBag.swift */, + 10DBF9FA38BA3CFBEB34E19F6953E864 /* DisposeBase.swift */, + 22F549E90893E8656AD2EEF4F9779A50 /* DistinctUntilChanged.swift */, + 68251CF4FE3622BA12120AFDF13FA1C4 /* Do.swift */, + C119DBAA7D6E7B3882D1CC7B760256E2 /* ElementAt.swift */, + BDC090E508088FF0C0A3490F4B4AC21F /* Empty.swift */, + 005BC5B30DAB73C72CFA4D0B90F85194 /* Enumerated.swift */, + F4AF170ACB6E5383A95764D1A3DA168A /* Error.swift */, + B6411610C892550E50F787ECE3AC4475 /* Errors.swift */, + 661995B1014D4EFB67154575503A2A88 /* Event.swift */, + FF638C997821B67CFD87ED2784B2BCF1 /* Filter.swift */, + 438DCEC5FA002C1C232C8B944C833102 /* First.swift */, + 2BE22EC0538EA1CEC12B1DB18C24A184 /* Generate.swift */, + 74D56845A1D247158DDA408F45DAA35E /* GroupBy.swift */, + E447DD75B5DFC0A94F8F3AA082F16DC8 /* GroupedObservable.swift */, + 490A189B6330719AAC1C4AFFF3A4A3F7 /* HistoricalScheduler.swift */, + EC1E7777904C53C224AD9EC13928AA60 /* HistoricalSchedulerTimeConverter.swift */, + A85D6B6C09F3FA02098B1204C99334CA /* ImmediateSchedulerType.swift */, + 1FFFAEA9D04F0A584135382514690C3C /* Infallible.swift */, + 8FBFC0CBBF3385F74EA898D58C65B4B3 /* Infallible+CombineLatest+arity.swift */, + E6886B33994444A6EB9CAC1264FF0D5C /* Infallible+Concurrency.swift */, + 1BF143D5E04FC312AF48745F2677C319 /* Infallible+Create.swift */, + 4D87C46D3D423E94BC72155D7A5B5A2D /* Infallible+Operators.swift */, + 8423330216C0F1793ABF4D8864F9C3E1 /* Infallible+Zip+arity.swift */, + 43EF4A1F3526BE0CAA711E9BD807894D /* InfiniteSequence.swift */, + 8CB14F660CC08F53BE651CF4ECBEF658 /* InvocableScheduledItem.swift */, + 63F86EDE0DE4C642283ED4E5E4CDFBE0 /* InvocableType.swift */, + 6BA3CEEAC4F4177C22F2015BD3FF1F24 /* Just.swift */, + 42BFDE3D268FD1437C5660BC87A65B82 /* Lock.swift */, + F81CBB69E8A5AE33C9EBECB5F6529AC5 /* LockOwnerType.swift */, + D907EC9C19B69B73A37BF27C30B38F05 /* MainScheduler.swift */, + 92425124E34B67695B33DCE332AA82EC /* Map.swift */, + 0C646DE8A55223D410F9282227BBE415 /* Materialize.swift */, + 7776F5D697B91DC2D5C6C66F4B6D0C6E /* Maybe.swift */, + B9DEC06B67A85AA48A2118481BCF5D38 /* Merge.swift */, + A2E6CC487F38F5A6D12B359D6AFB09A6 /* Multicast.swift */, + 4E991AAB3675553011A566D7D5890A76 /* Never.swift */, + 923B236039A70B1F88907A3F82BFE2AE /* NopDisposable.swift */, + 19DF06221A11CCCC94FF2CFB37647CDD /* Observable.swift */, + 77FA35F270AE53C737F4FF7A4879A13B /* Observable+Concurrency.swift */, + 38AC16752A18BFD36B7F4F543811879B /* ObservableConvertibleType.swift */, + BFAA391D692A854BE386E250FA9D185E /* ObservableConvertibleType+Infallible.swift */, + ED61B9E9979F042340DD70C4160F7A62 /* ObservableType.swift */, + 22955779FC97B3947D45B4CA2A3C5926 /* ObservableType+Extensions.swift */, + BD67BADF711C03B22878143404E08FCB /* ObservableType+PrimitiveSequence.swift */, + DA8005737AEE2B81D048D33A714C51C5 /* ObserveOn.swift */, + 078321DA8756A79AA1EBDF1D3DFBA9BB /* ObserverBase.swift */, + 51C95DFD2CA4362C4313EBE5596AD65F /* ObserverType.swift */, + 05A3AEC537D3BE26C51D6045A4BE0659 /* OperationQueueScheduler.swift */, + 0C4870B4A362118D2BB176E9219C5BB1 /* Optional.swift */, + 15311C960C78890DFEF8D4F4193F6359 /* Platform.Darwin.swift */, + 32AA4A86EE5313C95E3669CE9DA5FDC8 /* Platform.Linux.swift */, + 5E26F802520E48824E02912593B726AE /* PrimitiveSequence.swift */, + E3AD1926FB78B2FA344D6CFDA19C5F93 /* PrimitiveSequence+Concurrency.swift */, + 385B3A35B5E22B7F48613B00712041DF /* PrimitiveSequence+Zip+arity.swift */, + 94DC3DF73BAE5D55802A8D13A41C0AD3 /* PriorityQueue.swift */, + B229B8631DFEA25BD56F9A5330D76F9E /* Producer.swift */, + 7A338F46E55BB4522632D9A50330DE81 /* PublishSubject.swift */, + 34A4D9CCB4A1A5C3EBC1BF99BDB5F37B /* Queue.swift */, + FFA5D1BD0FAEAB4E04B446CB9E483DDE /* Range.swift */, + 0E5E13511F0AF2F8A7C637D0B1E5CE61 /* Reactive.swift */, + 94F6A4941C676635405DF83466B0BC26 /* RecursiveLock.swift */, + AA78242DC744444804153FB317B7E2E8 /* RecursiveScheduler.swift */, + 26ADDE7E696F04B30C9DC8A393455CC5 /* Reduce.swift */, + F40312C667A21EB4D9E6C8005CD1B164 /* RefCountDisposable.swift */, + 2A132226945BC922F96DF66A1385592F /* Repeat.swift */, + F8A05DCE6FA0242DB558250D79B85A28 /* ReplaySubject.swift */, + 43A399BE3081439D0BFC62B91BF9FC4F /* RetryWhen.swift */, + CC8A68F8FC8A03F8C5839FD7419DFC46 /* Rx.swift */, + 8C1BE9E50D4CDA794129A973C8D1103C /* RxMutableBox.swift */, + 3A464E4AFB2F136E06330E8CDEE738CC /* Sample.swift */, + 1CEC7002B9A3286DF431B186F07F0E50 /* Scan.swift */, + 7880A9F133272877D5749E9DA11537EB /* ScheduledDisposable.swift */, + 803BC476D5564A4FA5CD5F0275CFB254 /* ScheduledItem.swift */, + 8DE826C87D74FA780918D4C7EA87B7AE /* ScheduledItemType.swift */, + 39F4864853C931D994403E262406562F /* SchedulerServices+Emulation.swift */, + 177EDA0B76DEF69DB8E291B1F864EE04 /* SchedulerType.swift */, + D8FAB2E960EAC19A564D96AC83373912 /* Sequence.swift */, + 052B51BC168C7D6CF8335F93AF4A67A5 /* SerialDispatchQueueScheduler.swift */, + 79F42263D865156D4945BFDBF0A4CFE4 /* SerialDisposable.swift */, + 2BE01FA5A76FD95281BCF21AB650B8E0 /* ShareReplayScope.swift */, + 3CBE52AF7E852F29CE60E348DA19F51F /* Single.swift */, + E85E1CDB9FB613F8CE69DCB854E6B399 /* SingleAssignmentDisposable.swift */, + 165933865EF401961B5BB6932BC66E8C /* SingleAsync.swift */, + DF86AE6F99EFEC9B7B0DCA289F5D3DF7 /* Sink.swift */, + 7ACFE08527ACEE2E4AA211BEA97F4F2A /* Skip.swift */, + 86EBEFE81557E00B7289D083294B013A /* SkipUntil.swift */, + 90C3484BA91ADC6B89669375A948E937 /* SkipWhile.swift */, + B2DF563BC203205607B72B98451BF9AA /* StartWith.swift */, + 5BF636A803D82E59DA4ADF71F7AA4027 /* SubjectType.swift */, + 8890470F000AFACA77AF03D583016B43 /* SubscribeOn.swift */, + 0E98055623D69273DF17B778130628B8 /* SubscriptionDisposable.swift */, + A910CC14D263A3C2DBCBBF8AE936A9B2 /* SwiftSupport.swift */, + 94BE1EE9EBCA5538B271C44C0D2C3061 /* Switch.swift */, + 48D2E9A71B82298E7CEB37848357F768 /* SwitchIfEmpty.swift */, + 4CFA9A617FFE3AADE8D62793D1CFD5C6 /* SynchronizedDisposeType.swift */, + A8A5CEB9207F34477DCBCE05CA0329FE /* SynchronizedOnType.swift */, + FADFCB60B88A2B9122979E57337B8D47 /* SynchronizedUnsubscribeType.swift */, + 770297B28D90456712801DCBAB3F3D4E /* TailRecursiveSink.swift */, + B340DB018799D7AFF781F5CEADCC06F6 /* Take.swift */, + 63E79E25C1CD7ABF6BE187033583F968 /* TakeLast.swift */, + 02DD5108531A657F7454879387DFB795 /* TakeWithPredicate.swift */, + 2B8F16D2904D429E2EF80FBC37D8B531 /* Throttle.swift */, + 5CDE30B01C6DAD0D5FD8C972F98DE288 /* Timeout.swift */, + A6EB7CA5E10FC28F6095BE8C836B9DA2 /* Timer.swift */, + 6133281F47EC6817A2F139A120E864AE /* ToArray.swift */, + B0C42A7163BD5ADE05A3340C6B8B5D22 /* Using.swift */, + 783CF62358B7156761CAE141432059EC /* VirtualTimeConverterType.swift */, + 0846BC731037DE3BA116292847C91021 /* VirtualTimeScheduler.swift */, + FF13E01C557A0B7AA31D6B77F42EB22B /* Window.swift */, + 9C91A18F51E4CC6B9E6968EE21EDCF94 /* WithLatestFrom.swift */, + C2E0BD09EF34AC741CDB014F457C2EB6 /* WithUnretained.swift */, + 4C103FEEAA25720139580FD379B94F4C /* Zip.swift */, + C925288023BDC18E74D66D6E1BBFDAF3 /* Zip+arity.swift */, + 17C579C36CDD6CF5A9A0BB547AA750D5 /* Zip+Collection.swift */, + A0526F03C39EF886022F395423FF1754 /* Support Files */, ); name = RxSwift; path = RxSwift; sourceTree = ""; }; - 51667FC6D45FACDFCD4AA8294DED8880 /* RxCocoa */ = { + 23FC7D932CE6AF0E97539CDCC6ADE151 /* Pods-GenderList */ = { isa = PBXGroup; children = ( - 284D083D86D8F6BDAA4B8916E8986BAB /* _RX.h */, - 34CB6D05E236E726EBA220EB8AD8AB58 /* _RX.m */, - 6CA9A671658EDC6000F285EBAF057106 /* _RXDelegateProxy.h */, - 359E0E617AC6252C020ECD81C27A0569 /* _RXDelegateProxy.m */, - 77A079F61C4AB9506A8A7123727E58A3 /* _RXKVOObserver.h */, - 5401FDAB1CBADE2FD2AC91D65EBBD4DC /* _RXKVOObserver.m */, - 0C44F364482EB4F6905DAF107341E243 /* _RXObjCRuntime.h */, - 824686CA707E4A0205D584D7D80A548C /* _RXObjCRuntime.m */, - 216434676B68D96B04E6DDDA0D1D5A83 /* Bag.swift */, - 9C3BB98B0EF87EC7B8B22703000ACA9E /* BehaviorRelay+Driver.swift */, - 8500C3892A8916E27BA49771DDC39F84 /* ControlEvent.swift */, - 7477F9282D2B4E4714DD0ADEEAC8A14C /* ControlEvent+Driver.swift */, - F87FF9A89CEA3BE638D492B4D2861FC5 /* ControlEvent+Signal.swift */, - 709DF0E3B25C0AEE4AAFB24B57499054 /* ControlProperty.swift */, - 2D76A603A5E56D14C1699BCAF85E537B /* ControlProperty+Driver.swift */, - 84983A505E8934C5AD701FE2D31FB770 /* ControlTarget.swift */, - 923A02BEB70212483E3F31C6FA05C4E3 /* DelegateProxy.swift */, - 96B1049D115F74C6C48B9BF7B975E5F3 /* DelegateProxyType.swift */, - 446ACEEA7E8F01C4AE5F13F8715B075D /* DispatchQueue+Extensions.swift */, - 7D1B38AC6033251DAD312CD6B3A92EC2 /* Driver.swift */, - 98ED6A1FB741868720BC377FA293B9A0 /* Driver+Subscription.swift */, - B40C6BA6CDC6B229E81A833B34FC0605 /* Infallible+Bind.swift */, - DCA169B7E5D3DEAD4224D444953FAFD3 /* InfiniteSequence.swift */, - B42016A0131B39159AFDAD957DB09CD6 /* ItemEvents.swift */, - DC95CABB41414838A5CA49BCCBA6D914 /* KVORepresentable.swift */, - 6AE4579792A54E5559A9DAEDD992456D /* KVORepresentable+CoreGraphics.swift */, - D13859A2CFBD9C9E8B504BEAA461B51A /* KVORepresentable+Swift.swift */, - 3212B74DA6E8E30143526455790A11A7 /* NotificationCenter+Rx.swift */, - 03956BA3890ABF298FBA26FBF08B4E67 /* NSButton+Rx.swift */, - E16592D918033D6F1FCACB9C70EBDEC7 /* NSControl+Rx.swift */, - 1F6D4CBB22DC0338D091547BC40AA631 /* NSObject+Rx.swift */, - AF91FDC5BD806070B5160246987FD3D5 /* NSObject+Rx+KVORepresentable.swift */, - F266CB0FCD269EE6A8449BC282D0187D /* NSObject+Rx+RawRepresentable.swift */, - 2D5BA2237796BAC05B2E72B417F5A80A /* NSSlider+Rx.swift */, - 9F4F78CF439D58FD5F821B8196123351 /* NSTextField+Rx.swift */, - 70EB53F90BC2C2B55771AB42C6359FA6 /* NSTextStorage+Rx.swift */, - 892593379667A23952F2CC74685738E3 /* NSTextView+Rx.swift */, - 492C5CAD0304480DBF304ACC718D8A62 /* NSView+Rx.swift */, - A3E2A7B51D1978B92017963C55349295 /* Observable+Bind.swift */, - 5D8A73A39785C42B97E613D0CFA6BDD0 /* ObservableConvertibleType+Driver.swift */, - 57E162D330CF2CEF9DF0AF20E78638F8 /* ObservableConvertibleType+SharedSequence.swift */, - 2C0272514C0FECA114FCAA610EC7667C /* ObservableConvertibleType+Signal.swift */, - 028879668058DF7CB3068D2F773FC498 /* Platform.Darwin.swift */, - 888140F08408B7B3271F6544822DD56D /* Platform.Linux.swift */, - 80A64114D53C625813C2D26E4677BCF7 /* PriorityQueue.swift */, - 95079D39BC909C1A6BAD48240CC1CEBA /* PublishRelay+Signal.swift */, - CFB1D3357C9D51B861167D08229FD122 /* Queue.swift */, - 39921C9633DF11B9BEB63A732BCC0FDB /* RecursiveLock.swift */, - 0A895508CA44EE9BFFB139EBD5DCA92E /* RxCocoa.h */, - 95488DC7B444610250080F96F0BB9942 /* RxCocoa.swift */, - 92302766ED87489DC4556A56CD10A5B9 /* RxCocoaObjCRuntimeError+Extensions.swift */, - B7EA47329CE7C48C537F13F781A9FAAB /* RxCocoaRuntime.h */, - 782CA0710D423EBD97794817C8359075 /* RxCollectionViewDataSourcePrefetchingProxy.swift */, - 5A21AC031138F500D867B1A15877ED9C /* RxCollectionViewDataSourceProxy.swift */, - 741F949E7A59F3DDA438594A62CF0B5B /* RxCollectionViewDataSourceType.swift */, - C24F87871E996DBDC20A4F578217123E /* RxCollectionViewDelegateProxy.swift */, - 090F56B03C1EA838E662190E3D064532 /* RxCollectionViewReactiveArrayDataSource.swift */, - 3612035A1538C3A1A8AF7D1DBB4D0184 /* RxNavigationControllerDelegateProxy.swift */, - 8162421B4BB84E20689FE291FFFAF647 /* RxPickerViewAdapter.swift */, - A54C1F19A76D740FCD01B0FFE8B8B52D /* RxPickerViewDataSourceProxy.swift */, - DFB2F5D8F493BEAFE9EFA5E3E5EA0027 /* RxPickerViewDataSourceType.swift */, - 48C6D9986152A06D2ADC0063B133E754 /* RxPickerViewDelegateProxy.swift */, - 8DF09656ED4D86E85CD578AF13D73744 /* RxScrollViewDelegateProxy.swift */, - 1E90FF704D8B7C423ED6AF884FEC88E6 /* RxSearchBarDelegateProxy.swift */, - AD31C27FDA4BDB820AE3811BBF0F3289 /* RxSearchControllerDelegateProxy.swift */, - 9060E46ABEBE8DF1C9F5CDBEA8F03188 /* RxTabBarControllerDelegateProxy.swift */, - A2D10146397CCBBA9C236D37BB87BAB9 /* RxTabBarDelegateProxy.swift */, - 9991701AA0379D8817CEDBF9CAEDE1A4 /* RxTableViewDataSourcePrefetchingProxy.swift */, - 141B4D876D24D86E863F48BAC657EBC7 /* RxTableViewDataSourceProxy.swift */, - E16C9210350E4CF9F59ED55DE6C2EAE7 /* RxTableViewDataSourceType.swift */, - 7A5D8C38F674F50CB23E901928ABBFA5 /* RxTableViewDelegateProxy.swift */, - CB28A30D5E28A968807FF91682435113 /* RxTableViewReactiveArrayDataSource.swift */, - B89A1E4268C8D59F48FC54DA5809ACC7 /* RxTarget.swift */, - 91C7499695875934CFF0EAC81F7E26C5 /* RxTextStorageDelegateProxy.swift */, - A9F57960FCF66D2D01C89E218FB41DA8 /* RxTextViewDelegateProxy.swift */, - 610390D4044731D1CFB686687A81F305 /* RxWKNavigationDelegateProxy.swift */, - B025DF756635BB8334DED4384ABB6D8B /* SchedulerType+SharedSequence.swift */, - 1D83223BDC370C77F9850BB2A6C8742F /* SectionedViewDataSourceType.swift */, - EFAF4546BEC4051969C1020917C3FB33 /* SharedSequence.swift */, - 3F04911873952BD6300007242C0F1EF4 /* SharedSequence+Concurrency.swift */, - 96C930E38E9AB3484081BAF76C727EC9 /* SharedSequence+Operators.swift */, - 5FB6515374F67729417916635301BE41 /* SharedSequence+Operators+arity.swift */, - 2C0944E5F4EFFF24A475580B10825367 /* Signal.swift */, - 5EBB6166F378B6BA3BA6045513AD0B68 /* Signal+Subscription.swift */, - 7EE84A906E3B42A400F7A6A21B74204B /* TextInput.swift */, - 7210D187331A95A56DFC067B911061D8 /* UIActivityIndicatorView+Rx.swift */, - 9AB4873AE1C8F057BB406BD437FEBEC0 /* UIApplication+Rx.swift */, - BC182783F31B0D1DD816939B95155F5D /* UIBarButtonItem+Rx.swift */, - 3F080CD3AE644C4BB12664E9BE553B42 /* UIButton+Rx.swift */, - 581ECB7EB510001F013CEE44FAD7CB93 /* UICollectionView+Rx.swift */, - BE6D3755550E71F3C4ED3DBF77FDAF45 /* UIControl+Rx.swift */, - 5E153A1EECE82F48D2805239759A549A /* UIDatePicker+Rx.swift */, - ED3E0D1A2B19426FEBE08684BE7EB997 /* UIGestureRecognizer+Rx.swift */, - 86DC6ACB03731C01E7B7EBCE23FB1BE9 /* UINavigationController+Rx.swift */, - E134AA052C1FF8D939096469FC59AE78 /* UIPickerView+Rx.swift */, - 44404E8C9D38627A655B2CEC007AAA80 /* UIRefreshControl+Rx.swift */, - 91722A08B7BCDFD99580E9A0199DF3F4 /* UIScrollView+Rx.swift */, - CC36F9E06FE49F1F4F80BB1AFA71E98E /* UISearchBar+Rx.swift */, - 3F5D93D2A26CF9078B252BF264AABC60 /* UISearchController+Rx.swift */, - 601BAA3A79806B156A41056A73088AE8 /* UISegmentedControl+Rx.swift */, - 739DC6301DF1F2FA1A37C23C38EAACB3 /* UISlider+Rx.swift */, - CB1A5BE2F78CB18678F6C66C43494879 /* UIStepper+Rx.swift */, - 2DA4834DA4941D7863F0CBE2128F1621 /* UISwitch+Rx.swift */, - 8A3BCDC3D9A45F0A36083EB4A32CBB59 /* UITabBar+Rx.swift */, - 665B7D600A93931F9FC0056B47D815E1 /* UITabBarController+Rx.swift */, - C47AF1800496AAD9455F26513BBA496B /* UITableView+Rx.swift */, - 8460862A1D5FAE753536EE93A4D4A90E /* UITextField+Rx.swift */, - E784C3A6B34056D0BBA3B30E79142A7E /* UITextView+Rx.swift */, - B4BC0F2018503D8002E78FCE926EE3DB /* URLSession+Rx.swift */, - 9D7887303BCD625A3E1124F82E25F6D2 /* WKWebView+Rx.swift */, - 5D09BBD2B21025B4C95F1E190773821B /* Support Files */, - ); - name = RxCocoa; - path = RxCocoa; + F662A60ECDBE45A7F551522E8372BFA0 /* Pods-GenderList.modulemap */, + 3C52DCC8578844B8C5AFEC3E61FC07D3 /* Pods-GenderList-acknowledgements.markdown */, + 8AD68A687DC10A841007668CF32CAD53 /* Pods-GenderList-acknowledgements.plist */, + 7738ACDE4C2E00BC16AF9185E123A3DF /* Pods-GenderList-dummy.m */, + 2B6F7B84E077EC3DDF3056FF8349A606 /* Pods-GenderList-frameworks.sh */, + 4B9DA6D679DB4EFF3EB7A39361C177AB /* Pods-GenderList-Info.plist */, + 6F76B9A485E25F7856CEB67B8CD8B569 /* Pods-GenderList-umbrella.h */, + 4BFB8D4A76E253CF05CFDE137052A178 /* Pods-GenderList.debug.xcconfig */, + EC93761C8ADB8B00344821B1B009F02E /* Pods-GenderList.release.xcconfig */, + ); + name = "Pods-GenderList"; + path = "Target Support Files/Pods-GenderList"; sourceTree = ""; }; - 576CA3A65EDD71264A53798808C6EB46 /* Support Files */ = { + 47E5DF3DD4847EE9ED6B1DF8EEC145B6 /* Support Files */ = { isa = PBXGroup; children = ( - 229AF565F8AF87313E01A4E75691BF96 /* Alamofire.modulemap */, - 5668586C4F1FBED7320E57E20FEF2209 /* Alamofire-dummy.m */, - 737D6142E61022ADE009B35BCA7D67A0 /* Alamofire-Info.plist */, - 35A5A6316F990C77C6D3727171BDF348 /* Alamofire-prefix.pch */, - A002EFCC8C0346E39E3DB06B1725881C /* Alamofire-umbrella.h */, - A0B6997E7F68410D8A6C16644E3B92AD /* Alamofire.debug.xcconfig */, - A767B65FB96753CA10F8AAB2477D9DF9 /* Alamofire.release.xcconfig */, + F71E05F1DEEA7FF4B426AFE545A829DF /* SnapKit.modulemap */, + B431141CBD5FDEE892FB07B93CFD1D51 /* SnapKit-dummy.m */, + 5223A3219D4D96425B9386779E9C3941 /* SnapKit-Info.plist */, + 6CDB776F8CD44684C79FAD47ACB1C3D7 /* SnapKit-prefix.pch */, + 8F20EB9BFC1006360D8A179A92D3A514 /* SnapKit-umbrella.h */, + C2FF21266D29953418187232F568362E /* SnapKit.debug.xcconfig */, + C92D5CEA71FB521BF9D2801EBFD0EDE3 /* SnapKit.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Alamofire"; + path = "../Target Support Files/SnapKit"; sourceTree = ""; }; - 5931C0771A99DF66D5B772E382C666C5 /* Support Files */ = { + 4D07045741207E3AC167CF1BB1014945 /* Pods */ = { isa = PBXGroup; children = ( - FF0683C05982A495A423CBDA039C3AC6 /* RxSwift.modulemap */, - 55CB4877246F52FF87A8C244384E4E42 /* RxSwift-dummy.m */, - 81E49C8041DCCA4DC4E591197550BF98 /* RxSwift-Info.plist */, - 491640A78DA05BC89FD9699B3EEA4931 /* RxSwift-prefix.pch */, - 1A988A7455383F560A9BBAA36315E494 /* RxSwift-umbrella.h */, - 12098C2818AEF2B5F2BF1C8B8C14E647 /* RxSwift.debug.xcconfig */, - 8634AC774363585D5917FFA4AEEF52DD /* RxSwift.release.xcconfig */, + 8192E069F91415DCAC4E4B54544DC0B1 /* Alamofire */, + 6BB6EAE1FA195F6B43A18ED2D2C05CA9 /* Kingfisher */, + 1E273235868D3EB9828064D8F80F060C /* RxCocoa */, + 03709846C0CA49F4A06BAA7ECD71EAA5 /* RxRelay */, + 1EE46838A2C7708E276009190038625A /* RxSwift */, + CC609D4718B877C089711554E7DB906E /* SnapKit */, ); - name = "Support Files"; - path = "../Target Support Files/RxSwift"; + name = Pods; sourceTree = ""; }; - 5D09BBD2B21025B4C95F1E190773821B /* Support Files */ = { + 4D5F1F374BAA576E550EC88BA3C48E50 /* Products */ = { isa = PBXGroup; children = ( - 999012423D4F0401601226FECBAD91DC /* RxCocoa.modulemap */, - 462935E91ED59AF6B20ADE9631564D6B /* RxCocoa-dummy.m */, - 3C14E0A58AD2EA6A4DE08C97BD42AC5D /* RxCocoa-Info.plist */, - E64546B97551BE82226EF18A88571095 /* RxCocoa-prefix.pch */, - 01122E4C4E6E936C13650AB5930C1599 /* RxCocoa-umbrella.h */, - FDCFCE5266BE0AD0A4A0EDB04177DC43 /* RxCocoa.debug.xcconfig */, - 6E29D4C339F968E99A592A06B33343DD /* RxCocoa.release.xcconfig */, + 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */, + C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */, + 0ABFB7BA27AE26BFEFF3BA732CACE191 /* Pods-GenderList */, + BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa */, + FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay */, + 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift */, + 979486118B3E90C08386079D57962701 /* SnapKit */, + ); + name = Products; + sourceTree = ""; + }; + 4FAEDA7754D51F64CF458BFD576CD4B5 /* Support Files */ = { + isa = PBXGroup; + children = ( + 399CC3775BA27EDBA362F6F43A379F61 /* RxRelay.modulemap */, + 587647AE89A8323AA8669B5ACA6201BE /* RxRelay-dummy.m */, + 470BE4027F92B24DB7E235EC209D70DC /* RxRelay-Info.plist */, + E949866D1199DFDAB2026305C0CD9F09 /* RxRelay-prefix.pch */, + 2D956866F9C4CFFCB478A2F597636FEC /* RxRelay-umbrella.h */, + 2B267869B6FE5FC5CB863F860C1C1FAD /* RxRelay.debug.xcconfig */, + F060E67EDD1C139F8C56E3FD714779CB /* RxRelay.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/RxCocoa"; + path = "../Target Support Files/RxRelay"; sourceTree = ""; }; 5EE21CBB8EFB615AB450D209E054FAE6 /* iOS */ = { @@ -1404,262 +1427,243 @@ name = iOS; sourceTree = ""; }; - 8F1F777D8F77F373A9D61D1CD6EE1B61 /* SnapKit */ = { + 6BB6EAE1FA195F6B43A18ED2D2C05CA9 /* Kingfisher */ = { isa = PBXGroup; children = ( - 28F3AB7D268A9352EE6910E3C8DCC29D /* Constraint.swift */, - 04EA0D88E6C540AA57372D94CA178C71 /* ConstraintAttributes.swift */, - F8A8A341317A3DFABDA1E41E20BEF985 /* ConstraintConfig.swift */, - 590ED942605473B4D25BE44D9207DDDE /* ConstraintConstantTarget.swift */, - 9DA099226DE912F6804ED601DCE54DA7 /* ConstraintDescription.swift */, - FBA68C43E44294E2A8A0ED20C0BDF200 /* ConstraintDirectionalInsets.swift */, - 965B3A6BE185B4673A5F58FF419A00AE /* ConstraintDirectionalInsetTarget.swift */, - F3EE251BF5CC611B7D07507D0B79D416 /* ConstraintDSL.swift */, - 49309CED1FF1518FC6DA6FB30AED2314 /* ConstraintInsets.swift */, - A3166ABA859436ACB43784064BA94408 /* ConstraintInsetTarget.swift */, - 0FAF398D151AA3B4AE228DC8266D3719 /* ConstraintItem.swift */, - BDD4A751EE1628FD6964148586377853 /* ConstraintLayoutGuide.swift */, - 74C004D11372137CC8A4B3C27854344E /* ConstraintLayoutGuide+Extensions.swift */, - A1C288444CD932974293E8EF6BDDACD6 /* ConstraintLayoutGuideDSL.swift */, - D529B43DBB7B1DA17E601A091D5305BB /* ConstraintLayoutSupport.swift */, - CEBA261C0E4D59E792E2A1E87DA48CD3 /* ConstraintLayoutSupportDSL.swift */, - 243B068FE5F3750321AB4D1D90CDF047 /* ConstraintMaker.swift */, - 88C9CBE328FA6D027532F2845F170D6F /* ConstraintMakerEditable.swift */, - C2AD9E34263C1FD6F837368810D9B6B6 /* ConstraintMakerExtendable.swift */, - BDD7993237F89658783EA88C8FA4924F /* ConstraintMakerFinalizable.swift */, - 63004A6A6B9BEFDAA58B7FA062278C43 /* ConstraintMakerPriortizable.swift */, - 3D36596C01773C3C3FC96979AD8726C1 /* ConstraintMakerRelatable.swift */, - 0E9B3BDCF2E5186E2849A421BD65BA04 /* ConstraintMultiplierTarget.swift */, - 7E52CD081388CCB8E6485B2504337448 /* ConstraintOffsetTarget.swift */, - A60CCCC9B71B8257E82BB6A53357E35F /* ConstraintPriority.swift */, - DD09C5F6714AD9AE9D5F476B1B38822D /* ConstraintPriorityTarget.swift */, - 77D4E5B389FE76E8E5A9C151697E1E3A /* ConstraintRelatableTarget.swift */, - 18D10CFF2702506F9BC66AFA9CB1A285 /* ConstraintRelation.swift */, - D0739409A23BACA2BE8DD8A961490989 /* ConstraintView.swift */, - 7E896F1E52CD239FF87B9110061B1B63 /* ConstraintView+Extensions.swift */, - 0A5F8993766833E3FBAE79C7D917DA71 /* ConstraintViewDSL.swift */, - E2863AA3C3F0EBF54E3EA897B0EB74C7 /* Debugging.swift */, - 56D6EC6EA4C2491D9C1946FFC2D0F77D /* LayoutConstraint.swift */, - A501DBEFDB319841EFCB339196BD2087 /* LayoutConstraintItem.swift */, - 66CA00697CC0D00401E693CB52991330 /* Typealiases.swift */, - 9DE2CE1E44745DF7D91F7A5994CE22A6 /* UILayoutSupport+Extensions.swift */, - AE315B7FF84CA8945EA0D7F2330C1122 /* Support Files */, + BBE61D79694AAA7EB29E379C8487EE71 /* AnimatedImageView.swift */, + D6F5ED8C35455EBE258F138A1802D306 /* AuthenticationChallengeResponsable.swift */, + F469F47D809A2E852FFAB72BFFE46D9E /* AVAssetImageDataProvider.swift */, + 8975545EC3285FA17F23C282511FAF50 /* Box.swift */, + 1156F9304249B4AC44D03B40EB30F69A /* CacheSerializer.swift */, + B6AC886A405B78BA6458877730E1591B /* CallbackQueue.swift */, + 3AFFFA4F985B09306F6EB74771AA77D9 /* Delegate.swift */, + A4ED1922D596A1522D90C5B55D697E8E /* DiskStorage.swift */, + FB92E87126CB99BA3210A3EC1AE61DF3 /* ExtensionHelpers.swift */, + BFA5D5163A1B894A0D3138DB29FAB037 /* Filter.swift */, + 9DA8D267F3F3C52824DB85F2A4558754 /* FormatIndicatedCacheSerializer.swift */, + 5C0DA1708C5DB689CED1BB733A6202C2 /* GIFAnimatedImage.swift */, + FAE5C37C514852C880072749300AF8A5 /* GraphicsContext.swift */, + 0F0123AEE5FF35F7AC3D76D8ABBF3F69 /* Image.swift */, + 952EC55F4C5F9DE9E5C6CEA37ACFE65D /* ImageBinder.swift */, + D586379F42484F03DE243BA460D48E9F /* ImageCache.swift */, + 39AD7A483064C6E2459F057D93C37603 /* ImageDataProcessor.swift */, + 796DC31A2574F842FC44B7D07E24A722 /* ImageDataProvider.swift */, + 9705F4FFEB198353334C91129FD3C7B6 /* ImageDownloader.swift */, + 8CAD8A267F66DAD110741B2A5847070E /* ImageDownloaderDelegate.swift */, + A3270291C59FE54F4233693ADDE644C7 /* ImageDrawing.swift */, + A72B315AB5C66F8B157BAB601E734E3E /* ImageFormat.swift */, + 18D8E8D89BA483ED17D2EFDD71921594 /* ImageModifier.swift */, + AF741934484C2FF24397B93BA6FE6709 /* ImagePrefetcher.swift */, + 3D1E04658D6282D9191364B13B66A898 /* ImageProcessor.swift */, + 649025AAC69E92BE8E9ABB1A2DDF2FB8 /* ImageProgressive.swift */, + 328871EC5F47DC34D9B0224D74DA7E30 /* ImageTransition.swift */, + 6FB7DC60BEE1C9BDE9A6AFE88497F85E /* ImageView+Kingfisher.swift */, + 06D41EF68321F25F5DF29DCA66512232 /* Indicator.swift */, + D6D5C72E2C612EAA4B4CEF7A4D0D3479 /* KF.swift */, + 6CA535D550AC90898448FAC2B3E839E8 /* KFImage.swift */, + 33267D6278C73D35763DC6851211D419 /* KFImageOptions.swift */, + 0C2E3D4A19A01D0F46AB591C32690E98 /* KFOptionsSetter.swift */, + BFCD8F726BA2E1ED840CB2402B98E783 /* Kingfisher.swift */, + 7D17F5C46B8A9F8C14865CEF5914AB30 /* KingfisherError.swift */, + 2E0A84821DDFA668496084FB50DA7526 /* KingfisherManager.swift */, + 9F82EB30ACBF25A82505A35ACDCE2A96 /* KingfisherOptionsInfo.swift */, + 33BA2B6551160A572CB11661696B838A /* MemoryStorage.swift */, + F2341A179F0C231C4BC79A8F07E8B04E /* NSButton+Kingfisher.swift */, + 433B692C89197DA2819292E7CB2E4ACD /* NSTextAttachment+Kingfisher.swift */, + 148FCE152B9AD264C77EA952ACA5B376 /* Placeholder.swift */, + 2C76BFDCF0D1D12711765650CA1E6C6F /* RedirectHandler.swift */, + FE75E6B4CC424ABF9C8A7EC4DD4517C7 /* RequestModifier.swift */, + BE04B2773B47F444AD15B2D3ED195A0C /* Resource.swift */, + 450683C53D82531C94866107D76A268D /* Result.swift */, + 70EB884AE386D32AAF63E0A0FAA7AC5C /* RetryStrategy.swift */, + 6D0D84CA1B759F7250F1F55706122246 /* Runtime.swift */, + F5E0AE7C857ED5E9B5ECF6AD1EED8E82 /* SessionDataTask.swift */, + D250D8F7946F2AB945B56880B4CDD35F /* SessionDelegate.swift */, + 3F77858A4515CB188A0008E88C302846 /* SizeExtensions.swift */, + C2CDA3A4DDF9E4D7E37FC3A32090E715 /* Source.swift */, + 408F9B427B8BCFDAF73895D578D2FF5C /* Storage.swift */, + CF05C45A2F67138ECA96FE19A456DA92 /* String+MD5.swift */, + 09EAE66CA22F356DDEAEC53B2972D9DB /* TVMonogramView+Kingfisher.swift */, + 82F76798AA7C42A64C4EB6B59DC95A77 /* UIButton+Kingfisher.swift */, + 35E4ECAE1002E961A1C69F1D04E24EFD /* WKInterfaceImage+Kingfisher.swift */, + E444DD663444FCDCC1323FA10B0EDFF7 /* Support Files */, ); - name = SnapKit; - path = SnapKit; + name = Kingfisher; + path = Kingfisher; sourceTree = ""; }; - A9FD7A9F4BF3E03FDF760D8E31C2880A /* Support Files */ = { + 8192E069F91415DCAC4E4B54544DC0B1 /* Alamofire */ = { isa = PBXGroup; children = ( - 72B29299DFED276BACC7D6FF6F41973B /* Kingfisher.modulemap */, - 7016AF1EC96543C2911C96C8D525402B /* Kingfisher-dummy.m */, - FEC59675D09A0CF86AEF5C3158226E1B /* Kingfisher-Info.plist */, - 5799D32A0710CD856AB9552515F6904B /* Kingfisher-prefix.pch */, - F2A6298A6E44AC15ECABBDBC9D11D79F /* Kingfisher-umbrella.h */, - 9FF466253C12307D3952E7BF6496394B /* Kingfisher.debug.xcconfig */, - AD3677E72917440D5EA45F5BCB6B5829 /* Kingfisher.release.xcconfig */, + FE0809DCB644EA1525EA9CFEE9018507 /* AFError.swift */, + F9281DB73C863EE56557931C895FA070 /* Alamofire.swift */, + E0874EF395F89BC8B395CAD49E98ECE8 /* AlamofireExtended.swift */, + 1AA261BD733B0E7D34A8B8C53BAF08E5 /* AuthenticationInterceptor.swift */, + 7E40213495C29B7EC0897128E18347B9 /* CachedResponseHandler.swift */, + 91D56807DC7DF84CD3BB6C0208B64E31 /* Combine.swift */, + C29A289EF7C91591D808694C7F3473ED /* Concurrency.swift */, + 964EB3E2D2B380D91FE17EA3BD81849A /* DispatchQueue+Alamofire.swift */, + FC6172868C69E6D61153FD817422A036 /* EventMonitor.swift */, + CD17068C473F46FDDA345E0B8F45A14E /* HTTPHeaders.swift */, + F934FE3C0472E89EDA71BECB5FC29245 /* HTTPMethod.swift */, + 0E7AF374BE13CA7EF6CEF091D12B06E2 /* MultipartFormData.swift */, + A74E5079BE8E238BED74E89B731D5157 /* MultipartUpload.swift */, + 460CC31FF924BBE87297386FE46558DC /* NetworkReachabilityManager.swift */, + DC3E9FBB96DD375A4691E77F12BAD394 /* Notifications.swift */, + 43FD0858967BD8005F603DA65EEBD563 /* OperationQueue+Alamofire.swift */, + D96C8448CD7962AF26C90A25D4D1294E /* ParameterEncoder.swift */, + 0B50EE591E7052D97A3A53393B0232A6 /* ParameterEncoding.swift */, + 054144A7760E716E29603EEDFFBA5AFF /* Protected.swift */, + 425F7E64E335FA34B416F1317A984EEB /* RedirectHandler.swift */, + 9070D35DDE49A9987567E3F308BB5221 /* Request.swift */, + 5E4760342B9E9A2D2585A3A124C49345 /* RequestInterceptor.swift */, + EF147A0D663689C5F262DA7E61709115 /* RequestTaskMap.swift */, + 66053C44365424146EEB9240C16BAF31 /* Response.swift */, + 4CE5751604115D39C388D1C4A1612A40 /* ResponseSerialization.swift */, + BB5A231091AC6A99D67423C54E54C73F /* Result+Alamofire.swift */, + 8E856C87271A41592E12866CE3C9A668 /* RetryPolicy.swift */, + AD233B7BE3779DE6C50056326BC19F22 /* ServerTrustEvaluation.swift */, + D002139C96A6306EE9B058F61088B34D /* Session.swift */, + 276D3909A04A45FFEFE39B92A608A913 /* SessionDelegate.swift */, + 1022AEF0BFB392161D650BF9E00A3D8F /* StringEncoding+Alamofire.swift */, + 475798275244D376C942E726734ADF1F /* URLConvertible+URLRequestConvertible.swift */, + 61AA2DA550B097827DA12AE1415B11B4 /* URLEncodedFormEncoder.swift */, + F5DC8DF1D5F1FD3FFAD27AF5B10C367A /* URLRequest+Alamofire.swift */, + B3291F34A83BABC8CAB3AF78E427484F /* URLSessionConfiguration+Alamofire.swift */, + 5F5D8D6E3DFEDC6651C6B2F9C4FA1FBD /* Validation.swift */, + A62FE8A76D3180146D7CA3332E982AE3 /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/Kingfisher"; + name = Alamofire; + path = Alamofire; sourceTree = ""; }; - AE315B7FF84CA8945EA0D7F2330C1122 /* Support Files */ = { + 89B87C98E9F9390A945FD3489BC6752C /* Support Files */ = { isa = PBXGroup; children = ( - 4825BC57D4C56DC940BC05B110A6178F /* SnapKit.modulemap */, - 987EC0DD92EE020800E3E03D74818D35 /* SnapKit-dummy.m */, - 0798F4AC31E16088DC2EB1526116B10F /* SnapKit-Info.plist */, - 977C506F43603C288E2B36DB0F5FE1A6 /* SnapKit-prefix.pch */, - 85293B8B83659B656B1ABF20EF57E4F1 /* SnapKit-umbrella.h */, - FE70B944EB620CD61740D3BA724EACEC /* SnapKit.debug.xcconfig */, - 241D7299EBA5825B66091F231253D7E1 /* SnapKit.release.xcconfig */, + 5DC1C2FF2C913DE532CD697CE2E82EE8 /* RxCocoa.modulemap */, + 55C7070925A0D5B91896AFBB46ADB57F /* RxCocoa-dummy.m */, + 7F92B6AFEA2D6A41A69C4B3F1F81E66F /* RxCocoa-Info.plist */, + AC9DAA4C9C6A0CA4FA72B74F3756FD48 /* RxCocoa-prefix.pch */, + E3E9BDD5EBA375AF48858939A1673F76 /* RxCocoa-umbrella.h */, + 5A1E2AE32DE9B16524DBF78CFF07F72E /* RxCocoa.debug.xcconfig */, + 61CE5FA8C390F7C5066EE1B035CF5037 /* RxCocoa.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/SnapKit"; + path = "../Target Support Files/RxCocoa"; sourceTree = ""; }; - B7046E811604754871B4A709801F98AC /* Targets Support Files */ = { + A0526F03C39EF886022F395423FF1754 /* Support Files */ = { isa = PBXGroup; children = ( - FE862947400D3043CEDB04B7387E137F /* Pods-Bunjang */, + C6A393DD2437866A291C7EC4EF3C1E0B /* RxSwift.modulemap */, + 72B9242504B8D42D2180847C1D02DD74 /* RxSwift-dummy.m */, + F0D2F124FD52C827D1220776CC40AD2C /* RxSwift-Info.plist */, + DD7C07E445E94C46C60EA60D57ACFC23 /* RxSwift-prefix.pch */, + AABBF71F11B9315AE1BF54B313097F7E /* RxSwift-umbrella.h */, + CB204A7905DC8CDA462909EB4D19A184 /* RxSwift.debug.xcconfig */, + 8FD2D1EC03E239BF0A8EF6F05A8C0BC5 /* RxSwift.release.xcconfig */, ); - name = "Targets Support Files"; + name = "Support Files"; + path = "../Target Support Files/RxSwift"; sourceTree = ""; }; - CF1408CF629C7361332E53B88F7BD30C = { + A62FE8A76D3180146D7CA3332E982AE3 /* Support Files */ = { isa = PBXGroup; children = ( - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */, - 0CE845F38E5EDD1B75746735A2D910A2 /* Pods */, - F439D2FA698D156F597BC751865E3EFC /* Products */, - B7046E811604754871B4A709801F98AC /* Targets Support Files */, + FC7BEB23F49CED3D68E031F723F0BDD0 /* Alamofire.modulemap */, + 0D7B5A7AD167A4C224BA967C65613F9E /* Alamofire-dummy.m */, + DD7C1E2C14FC38CA7DC000E07D73EC59 /* Alamofire-Info.plist */, + 6DD6F88E56C3C14732D14F6C6D64767C /* Alamofire-prefix.pch */, + CC1E8344C026E264D4315EB2020BCB3A /* Alamofire-umbrella.h */, + BF856F895F5BD4D5F260053D673E8B93 /* Alamofire.debug.xcconfig */, + 9A2F68AB3AB4B514979EC4B758CC781B /* Alamofire.release.xcconfig */, ); + name = "Support Files"; + path = "../Target Support Files/Alamofire"; sourceTree = ""; }; - E5D391B1BA7DB41E05B868639D18F32B /* Alamofire */ = { + CC609D4718B877C089711554E7DB906E /* SnapKit */ = { isa = PBXGroup; children = ( - 4B1D5E99178DC6039AA64BA30DEC3D54 /* AFError.swift */, - 129BE48ECDE18236FCECEFF00958A22E /* Alamofire.swift */, - A83C680BD4FC55B43A8CED179AD14F46 /* AlamofireExtended.swift */, - A84C5BEA876D4A87BEB5E63B35C885AC /* CachedResponseHandler.swift */, - A8830E829C546878488B268DCE7DDB4D /* DispatchQueue+Alamofire.swift */, - EFEDC3D329D65E48B3BC7FCA14CDED97 /* EventMonitor.swift */, - 22FC7E45CD1650C4C37F3C8C97FA02F7 /* HTTPHeaders.swift */, - 5663CC614EDF46B43CD113FE47D9B9AD /* HTTPMethod.swift */, - 348AE3FD864F7622AB84B36307F89F84 /* MultipartFormData.swift */, - A926E0571C383DCF3CA9610A7DD2A439 /* MultipartUpload.swift */, - EC362006304825F3407E5280F369197F /* NetworkReachabilityManager.swift */, - 6B35807BDF3E02C1B736BA4C9C9358C7 /* Notifications.swift */, - F9E69EBCE3389722923E118788F3FF7A /* OperationQueue+Alamofire.swift */, - B84BB4804259F96248E7DB341FCDFDC8 /* ParameterEncoder.swift */, - B17FE795BFDF8716FCE863719F88C915 /* ParameterEncoding.swift */, - EDF7AA432C0E4C80D47EEF000590D957 /* Protector.swift */, - C954F6DF8FF162D446F5C12EB53E01AA /* RedirectHandler.swift */, - 420B4C2C25E8A2AF22506AAC158F2AD3 /* Request.swift */, - 2466F41844E51F2D29DFCDEE4E4AD3C5 /* RequestInterceptor.swift */, - 61070FC24D3DD3C05630D2FD00ECF898 /* RequestTaskMap.swift */, - C294FFEA094D34D45BC84CEF61CF1C49 /* Response.swift */, - 2C59DF271C27008DD3524AB8E849C53F /* ResponseSerialization.swift */, - 1D7705F997A86550CBD50E3A0EF7D891 /* Result+Alamofire.swift */, - 5C000E2E307CBE72910B6A0E5625A6AC /* RetryPolicy.swift */, - 12C4D9B07775F92146D1E794C6D3572B /* ServerTrustEvaluation.swift */, - 2A57FC897450D14CF6F70161A3AB95BC /* Session.swift */, - 6BF605F4199BEDA7DC3DCD3BE09331AE /* SessionDelegate.swift */, - 46DDD7887D41973B96666E7A02C9ABF7 /* URLConvertible+URLRequestConvertible.swift */, - 9B49579A82C0539E33F8DB78641B1E64 /* URLEncodedFormEncoder.swift */, - B91BFE5181BE61CE32BA2259CFA60B89 /* URLRequest+Alamofire.swift */, - DD8374B2F9307524AA49B8C180B751A0 /* URLSessionConfiguration+Alamofire.swift */, - 08DC1AE8E928801CE8A4CF42E28E6F03 /* Validation.swift */, - 576CA3A65EDD71264A53798808C6EB46 /* Support Files */, + 8882B3B9AE691A21883DDA845199981A /* Constraint.swift */, + 68B4D2046A60FAA56B043EF6DBFDE4FE /* ConstraintAttributes.swift */, + 9D22CAA3D66865CE1343FDADF4776379 /* ConstraintConfig.swift */, + D798CB81E1C040FD4AF4AEBB9C9FD0A3 /* ConstraintConstantTarget.swift */, + 441B4B5DF69FFFA7DADD198084C7105C /* ConstraintDescription.swift */, + 5422501686FAC3E64A8018D8F903CD57 /* ConstraintDirectionalInsets.swift */, + 1B43583C37157540C0BAC4B4E7AEA76A /* ConstraintDirectionalInsetTarget.swift */, + B75D4359FA407C5BFDCA84D5DC68698E /* ConstraintDSL.swift */, + BB8779B59592C7549ADBF5AB5110B0BB /* ConstraintInsets.swift */, + D6107C17D2C9AC490E84B09E3E310181 /* ConstraintInsetTarget.swift */, + 928A9C7117C36D7FD359DDFE7E4D8CD7 /* ConstraintItem.swift */, + 5264EDC8D0DB10A5282A04C71579F2AC /* ConstraintLayoutGuide.swift */, + AED03E92814E6B1D4872D7FE4343DBFF /* ConstraintLayoutGuide+Extensions.swift */, + DC48DB40E7345B46179098B3B1AA269C /* ConstraintLayoutGuideDSL.swift */, + E1FE6F6768DE4B073C442DFEB4EA7C4D /* ConstraintLayoutSupport.swift */, + C711A78D09F3C9ED05DD103F20ED97F8 /* ConstraintLayoutSupportDSL.swift */, + 9D242FB48AEB035B24741F5EF5D470D9 /* ConstraintMaker.swift */, + FB4AC18518632E482B180EC7A9807907 /* ConstraintMakerEditable.swift */, + CC0BB8711A19D4B872ADBAE7977F2D55 /* ConstraintMakerExtendable.swift */, + 60A77062CC86E62ABF59F12FCA57E196 /* ConstraintMakerFinalizable.swift */, + F257D204D4CB255CCFEDD0564D96D030 /* ConstraintMakerPriortizable.swift */, + 8D05715E1C746DA8A57A002AD77320E2 /* ConstraintMakerRelatable.swift */, + 3578A3CC608B05A5F1CD876FDAE5D161 /* ConstraintMultiplierTarget.swift */, + C763C3301F4A9D71EA67289A30CCA5C2 /* ConstraintOffsetTarget.swift */, + 885975EFA59BAE09779F812C3088B554 /* ConstraintPriority.swift */, + D559333329A32BD7831F2E45D4FF16A7 /* ConstraintPriorityTarget.swift */, + D2EA73D174336145C16B4581B24C09AE /* ConstraintRelatableTarget.swift */, + 3161196A1725FB042806502C2CEC58A9 /* ConstraintRelation.swift */, + 1ABEBCBC6DFDA3EC47F7B3B22548DAC5 /* ConstraintView.swift */, + C2E1371BA56D60F8CA446C7DA1840DDF /* ConstraintView+Extensions.swift */, + EE5CD5014A09A8B5FEF6D3E30B7B776D /* ConstraintViewDSL.swift */, + B2FBB746560DC1E971E2EA40E423CDFB /* Debugging.swift */, + 9007FC5024FD1C48B575F77C8E3B1865 /* LayoutConstraint.swift */, + F816B43767B379812F884C578D631E88 /* LayoutConstraintItem.swift */, + 74E4D3E1255D7FA3A2EC241B99432FEF /* Typealiases.swift */, + C0F7056A97FEB5FCB2C86F9686D2C0F8 /* UILayoutSupport+Extensions.swift */, + 47E5DF3DD4847EE9ED6B1DF8EEC145B6 /* Support Files */, ); - name = Alamofire; - path = Alamofire; + name = SnapKit; + path = SnapKit; sourceTree = ""; }; - F28F6B6A96993CF1D0660DC067A15765 /* Kingfisher */ = { + CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( - FF1A11CA657EBFC3AE9A5FAA8F50C737 /* AnimatedImageView.swift */, - A86C98B190BBB18095371820610FFBA9 /* AuthenticationChallengeResponsable.swift */, - 9EC8262350C75698D71BEC19D863D711 /* AVAssetImageDataProvider.swift */, - A85637ACD268647B3D9AB2FCF1640346 /* Box.swift */, - D67131024C7367F11A6414DE7CA82CF0 /* CacheSerializer.swift */, - EABE22BF2DF69287E362BE1D2C88D65C /* CallbackQueue.swift */, - FC5FAACB2F1EFDF21330936154BF6DFA /* Delegate.swift */, - A549A9EB6AF7788C2602ACBFEB019EAF /* DiskStorage.swift */, - 149A0E263DF818421EFE73AA49E3FEC2 /* ExtensionHelpers.swift */, - E913CE22A6FD9AC2977EE4115A73181D /* Filter.swift */, - 803AA769B8BDFAFF27D2D09489678DE4 /* FormatIndicatedCacheSerializer.swift */, - E90B9C4250086CFB7483AAD87B1C4989 /* GIFAnimatedImage.swift */, - 6AEF96291CDC473DD230EFDC04E3745A /* GraphicsContext.swift */, - 93B9D54BE7D34A5488B42DC19D10A403 /* Image.swift */, - 30D6A0775465C48A70C1EEAA247354EC /* ImageBinder.swift */, - 3838BCB07EFD1D203AA7CCD91DE9C2E5 /* ImageCache.swift */, - 17C9BA669A8F668C0A88722EACEF84AF /* ImageDataProcessor.swift */, - 53223FF13560EBEA779AD3723F9BBA00 /* ImageDataProvider.swift */, - 690CBA6B46BCDC28457F1D7848E98E4F /* ImageDownloader.swift */, - 536AE0412E79AAD5D7758292B3B75D0B /* ImageDownloaderDelegate.swift */, - 565F1573A89C0E571C1C7A874625F7E9 /* ImageDrawing.swift */, - E86414347BF96F3CB7BBEE331C50AE90 /* ImageFormat.swift */, - 673EDC2A7995B2775EF3A3D7B1F1D50C /* ImageModifier.swift */, - CE864F413CB764E2D3840B6A04F5C8BB /* ImagePrefetcher.swift */, - 0D75B4BD74A428B33BC3091D935894D4 /* ImageProcessor.swift */, - 412E7CB493D9A51E0BEB16EEB73977AE /* ImageProgressive.swift */, - F938BFD201DD51B234CDAF2A7BE97279 /* ImageTransition.swift */, - DF9F7C0C096008AB17EA43C33758716D /* ImageView+Kingfisher.swift */, - 2FE7855AE606E5E11D3FBFEB5F9269BD /* Indicator.swift */, - 1D441519852483871764E8CCA75F4A95 /* KF.swift */, - 9C078D8BDF198136B167BED30F8A82E0 /* KFImage.swift */, - C3E5CBA1DB958A279FE0C629D26B7185 /* KFImageOptions.swift */, - 42216AFFF59E357B6AF1F1378A785AFF /* KFOptionsSetter.swift */, - 39B2E58EF22EE740478AB6EAD4AA54A3 /* Kingfisher.swift */, - 479AC0D0C5CE3FD96E9568934D3C050F /* KingfisherError.swift */, - B7737EEE6716D463DA348B99E54B89E6 /* KingfisherManager.swift */, - 0C8E0DF3B5987F629AE2237546036058 /* KingfisherOptionsInfo.swift */, - 877A2FD7746750C7EEA0776F7100ED51 /* MemoryStorage.swift */, - 6A2C3C1D0E6D7A4FE37D9A983BD28417 /* NSButton+Kingfisher.swift */, - 49D2664CB995F0C4C70CC1ABB49CC79A /* NSTextAttachment+Kingfisher.swift */, - 1D8BAA943C277F25473B01F1832BA866 /* Placeholder.swift */, - 6283F9E56EB235587468C6A23E30BFE0 /* RedirectHandler.swift */, - A3CBFB2E2A7835AFFD9AF09F49AB44DB /* RequestModifier.swift */, - A785ADAF5C7B8D666BB4ED42943A8662 /* Resource.swift */, - 9FB53906BE6B2C9E6204708B943C66E8 /* Result.swift */, - C12BD7A4C979860972136F7BA019630B /* RetryStrategy.swift */, - 13717D0A33898D0C1E1121E04A69AACF /* Runtime.swift */, - EC109E1398391D4E301F805F761BC5B2 /* SessionDataTask.swift */, - 1486B81E13CE29D01C4B7BB2C76A9BF8 /* SessionDelegate.swift */, - 1797BF7FAA53FCA78CC60F983304176D /* SizeExtensions.swift */, - D2089866320AF70B3661336D75B57BC0 /* Source.swift */, - C2A6AE6EEE6FB189C7673B9F58C77757 /* Storage.swift */, - EA2E3307EAC0D40402CF75CA99E59080 /* String+MD5.swift */, - B7C1CDFAC10807BB2B956A999969A0FF /* TVMonogramView+Kingfisher.swift */, - 1500F0CCD24A6A49C7EB584E63BCF842 /* UIButton+Kingfisher.swift */, - 501297031677D31F36A769809D7584A1 /* WKInterfaceImage+Kingfisher.swift */, - A9FD7A9F4BF3E03FDF760D8E31C2880A /* Support Files */, + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */, + 4D07045741207E3AC167CF1BB1014945 /* Pods */, + 4D5F1F374BAA576E550EC88BA3C48E50 /* Products */, + D0A5F6CF2FDE332AF3552EA5186699C1 /* Targets Support Files */, ); - name = Kingfisher; - path = Kingfisher; sourceTree = ""; }; - F439D2FA698D156F597BC751865E3EFC /* Products */ = { + D0A5F6CF2FDE332AF3552EA5186699C1 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */, - C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */, - 594AF42B97DD02A1DFD0047E23495757 /* Pods-Bunjang */, - BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa */, - FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay */, - 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift */, - 979486118B3E90C08386079D57962701 /* SnapKit */, + 23FC7D932CE6AF0E97539CDCC6ADE151 /* Pods-GenderList */, ); - name = Products; + name = "Targets Support Files"; sourceTree = ""; }; - F80A4E53B661E1E1D22C0E498171F559 /* RxRelay */ = { + E444DD663444FCDCC1323FA10B0EDFF7 /* Support Files */ = { isa = PBXGroup; children = ( - AEF7A990982D57F3CF18103B53C623BA /* BehaviorRelay.swift */, - 4C3315AD200F0B9AD525D212C0C41504 /* Observable+Bind.swift */, - 90A368B9BE806FE43AF910196519FC5D /* PublishRelay.swift */, - AA58654B4430250D86C1BCBD63DE43A8 /* ReplayRelay.swift */, - 390343B0F0437A9ED750B8657080C49C /* Utils.swift */, - 22C54E34AE5A13837A9CB189FF4844DF /* Support Files */, + 7773B6A17EBF60A6676CD1478F2FA2B0 /* Kingfisher.modulemap */, + E724CE2180A86CA9D4D2A7FEF873464B /* Kingfisher-dummy.m */, + 45ED0DD251CA18C7D67361199D5DE10F /* Kingfisher-Info.plist */, + E3FCD724B7B1AF75B0FDC252E28E6D0E /* Kingfisher-prefix.pch */, + C2C8987AD5E008F7FF45922286EB79F0 /* Kingfisher-umbrella.h */, + 535245D6165D831E74CCF68877E016BC /* Kingfisher.debug.xcconfig */, + FAAF3645DF88E1E0DA21560E63737408 /* Kingfisher.release.xcconfig */, ); - name = RxRelay; - path = RxRelay; - sourceTree = ""; - }; - FE862947400D3043CEDB04B7387E137F /* Pods-Bunjang */ = { - isa = PBXGroup; - children = ( - 24DE341833137F7E412379EA3C5B44B6 /* Pods-Bunjang.modulemap */, - 4C0AC7C0A13AE44CF85E744BFD4FB822 /* Pods-Bunjang-acknowledgements.markdown */, - 5DCC04F3693DED5FA68286618AD2C348 /* Pods-Bunjang-acknowledgements.plist */, - 81596965EC2DAB2BF48389645FC00166 /* Pods-Bunjang-dummy.m */, - EA90122D850DDF57AA5D6CB8903DD8FB /* Pods-Bunjang-frameworks.sh */, - 6024A9A382EF8A747BF3EF7F6CB93279 /* Pods-Bunjang-Info.plist */, - 45740A99F06B13415E6AB7855CA64512 /* Pods-Bunjang-umbrella.h */, - 191B10FB8FC2B7DDBC84A8208CA00B22 /* Pods-Bunjang.debug.xcconfig */, - 44BED1C4650C3E0D28DE12A7A809D753 /* Pods-Bunjang.release.xcconfig */, - ); - name = "Pods-Bunjang"; - path = "Target Support Files/Pods-Bunjang"; + name = "Support Files"; + path = "../Target Support Files/Kingfisher"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 0B6B329938BD952A8994B296B9A26B75 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - EEA7A2B1F6816985A1E409C674EE8D64 /* RxRelay-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 0C9ED7F80C58C162BDF0D2A96D8615F6 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -1682,41 +1686,73 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 63967AF61B6DC743C218D7F992A0C94B /* Headers */ = { + 52E6F7B26483BE3BC9393C6C05D32424 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - ED81033ECA0A6C579EE97116D225C11B /* Pods-Bunjang-umbrella.h in Headers */, + 005B319B494ED2DAA239B9939A504DFC /* Alamofire-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 921A630E59DB08C171E3478243F46992 /* Headers */ = { + 5A5E7E6635553B3A8EC32F172957BCFD /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 26415B02C09B34CFEB3027EC9AC305DD /* RxSwift-umbrella.h in Headers */, + 0BC5830BB75BEEF69930604F6B1B53EE /* Pods-GenderList-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - B8A9A87054AC338A9F206F5236807BDE /* Headers */ = { + BC482071C83767B68D04E95A98B7715B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 481AEC9854D434ABFCBDA297619AB35F /* Alamofire-umbrella.h in Headers */, + 93209671B01B76711F6E2022CADBAC9A /* Kingfisher-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - BC482071C83767B68D04E95A98B7715B /* Headers */ = { + C73A0CBF71A2C181D7AC364A3F950106 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 93209671B01B76711F6E2022CADBAC9A /* Kingfisher-umbrella.h in Headers */, + 7BCA04E89CE537D96BC53943ACDDD305 /* RxRelay-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB41EE51AFB0DC480527169660505109 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A026156F75FE82816C8564F0189D3E66 /* RxSwift-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 02AC1F5B77CF25FEDF5287022EEF3F65 /* Pods-GenderList */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3638F4146E7C5BF6C43C20F5C8D552DC /* Build configuration list for PBXNativeTarget "Pods-GenderList" */; + buildPhases = ( + 5A5E7E6635553B3A8EC32F172957BCFD /* Headers */, + 711D0196C287AF2F310C1BF8488B6A06 /* Sources */, + ECFF7A1DCB8C536B1B8981BC7123E8CF /* Frameworks */, + 271B2CB061E335EB53BE9D9812A0099C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 81B32B604895087FD5D600570570DE06 /* PBXTargetDependency */, + 2D3C3CF86E9D6AF5642D889394EB7D56 /* PBXTargetDependency */, + 3FBB9763FAD09D117A8570A1FA16A303 /* PBXTargetDependency */, + EDE1009088AD01D2D679023D4D60AB52 /* PBXTargetDependency */, + F1D006641AF99F2AE2AF2B4900B141ED /* PBXTargetDependency */, + 11823FDA34AC4E6828EFCEC550D288D6 /* PBXTargetDependency */, + ); + name = "Pods-GenderList"; + productName = Pods_GenderList; + productReference = 0ABFB7BA27AE26BFEFF3BA732CACE191 /* Pods-GenderList */; + productType = "com.apple.product-type.framework"; + }; 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */ = { isa = PBXNativeTarget; buildConfigurationList = 4949A940CD53B7E293859B71C91C88F3 /* Build configuration list for PBXNativeTarget "SnapKit" */; @@ -1737,17 +1773,17 @@ }; 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */ = { isa = PBXNativeTarget; - buildConfigurationList = E6C32045F55A5C3BD79BFA54CFC9431F /* Build configuration list for PBXNativeTarget "RxRelay" */; + buildConfigurationList = 43D72C4AD858D20A6E2750CD96CBE4DD /* Build configuration list for PBXNativeTarget "RxRelay" */; buildPhases = ( - 0B6B329938BD952A8994B296B9A26B75 /* Headers */, - 45C3BC4897B6591A550A9A098F2F5AC9 /* Sources */, - B3FD44A81D6BB69C90D069361E98B2A6 /* Frameworks */, - DCCB22E4BC1B16B4E2B3C87AF889564D /* Resources */, + C73A0CBF71A2C181D7AC364A3F950106 /* Headers */, + 349A571C5C18BB9C6DBF0C9D0198BCFF /* Sources */, + 45D55D72D6D5C20BC82FF77452BE7744 /* Frameworks */, + B1223E8D4185135324B215B00BA2FE32 /* Resources */, ); buildRules = ( ); dependencies = ( - 3334D74C832F10DED70E9EEEB8D9F92F /* PBXTargetDependency */, + C2C2D4AAD7E76229F98BE0C058AF1ED7 /* PBXTargetDependency */, ); name = RxRelay; productName = RxRelay; @@ -1766,8 +1802,8 @@ buildRules = ( ); dependencies = ( - 007F2342B3F2B82A413D556E9C9A469D /* PBXTargetDependency */, - EC7034FC667E1A3EF994D32000A3FF66 /* PBXTargetDependency */, + 7999EB1FB260270C1210F82B94A6337C /* PBXTargetDependency */, + B668BDE011A5EB670307B4F521A12F3E /* PBXTargetDependency */, ); name = RxCocoa; productName = RxCocoa; @@ -1794,12 +1830,12 @@ }; EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 6C713B4993AB2D74A2656348044AC07D /* Build configuration list for PBXNativeTarget "RxSwift" */; + buildConfigurationList = 6D9C7492118475169EBD3549EFC60B45 /* Build configuration list for PBXNativeTarget "RxSwift" */; buildPhases = ( - 921A630E59DB08C171E3478243F46992 /* Headers */, - 7DBB2CB1F7CA60E80AAA32AB49B80823 /* Sources */, - D20FE8C9788757E0BF68768B4C17D59A /* Frameworks */, - 6E6D88BB003EEC58A454C46767E34AE5 /* Resources */, + DB41EE51AFB0DC480527169660505109 /* Headers */, + A9243C3B30674855204D62AE94A26B72 /* Sources */, + E4AB0452F719F6CBD11E27B1B3ECC4E7 /* Frameworks */, + A17DC84ED607EB2EB34643634DAFA397 /* Resources */, ); buildRules = ( ); @@ -1812,12 +1848,12 @@ }; EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */ = { isa = PBXNativeTarget; - buildConfigurationList = F286D0E597A0EFD8015B1A73656F64EB /* Build configuration list for PBXNativeTarget "Alamofire" */; + buildConfigurationList = 8A212264186B8822192F9C369D7DE4BB /* Build configuration list for PBXNativeTarget "Alamofire" */; buildPhases = ( - B8A9A87054AC338A9F206F5236807BDE /* Headers */, - 5D28D6962A06E93A50CCF281C680B008 /* Sources */, - 6CDBE85C1FF2D1940AA1F0F792DCC589 /* Frameworks */, - 4F53D562E3B1C79041E7F38C90D4F8AB /* Resources */, + 52E6F7B26483BE3BC9393C6C05D32424 /* Headers */, + F5D2A45FBA06D86A537CB441D5BF4FF4 /* Sources */, + 15DC142A7EE833251AA37FC8E2B8E01F /* Frameworks */, + E9D4145FA41F60FFAB33A07796D9ED97 /* Resources */, ); buildRules = ( ); @@ -1828,38 +1864,14 @@ productReference = 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */; productType = "com.apple.product-type.framework"; }; - EFC7BDAAC984A24C60CD76D4396B24D6 /* Pods-Bunjang */ = { - isa = PBXNativeTarget; - buildConfigurationList = D6686C9622B349A28A6EA8B43CE42228 /* Build configuration list for PBXNativeTarget "Pods-Bunjang" */; - buildPhases = ( - 63967AF61B6DC743C218D7F992A0C94B /* Headers */, - 60E9B9EDF3B805933006483196471DDE /* Sources */, - 79906E3FD9696ED1D66D5AD4FFFE0FDF /* Frameworks */, - D7A9E6A2B4E39563087AEC2A94DD1501 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5C31A9C3AE650740BE3434E650656588 /* PBXTargetDependency */, - C2444E07E0A400983946A9CF1D821DEB /* PBXTargetDependency */, - 965340EF18D1993D6B9F952A89F8AE10 /* PBXTargetDependency */, - C445127F601CED97C76052A8A7C8961C /* PBXTargetDependency */, - 916E624A3930B2A5F289F9646BB1413E /* PBXTargetDependency */, - C9BB3A81247B5BC6B43AFC5334A58EE1 /* PBXTargetDependency */, - ); - name = "Pods-Bunjang"; - productName = Pods_Bunjang; - productReference = 594AF42B97DD02A1DFD0047E23495757 /* Pods-Bunjang */; - productType = "com.apple.product-type.framework"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ BFDFE7DC352907FC980B868725387E98 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1240; - LastUpgradeCheck = 1240; + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1500; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 13.0"; @@ -1870,13 +1882,13 @@ en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = F439D2FA698D156F597BC751865E3EFC /* Products */; + productRefGroup = 4D5F1F374BAA576E550EC88BA3C48E50 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */, E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */, - EFC7BDAAC984A24C60CD76D4396B24D6 /* Pods-Bunjang */, + 02AC1F5B77CF25FEDF5287022EEF3F65 /* Pods-GenderList */, 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */, 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */, EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */, @@ -1886,7 +1898,7 @@ /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 4F53D562E3B1C79041E7F38C90D4F8AB /* Resources */ = { + 271B2CB061E335EB53BE9D9812A0099C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1900,14 +1912,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6E6D88BB003EEC58A454C46767E34AE5 /* Resources */ = { + A17DC84ED607EB2EB34643634DAFA397 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D7A9E6A2B4E39563087AEC2A94DD1501 /* Resources */ = { + B1223E8D4185135324B215B00BA2FE32 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1921,7 +1933,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DCCB22E4BC1B16B4E2B3C87AF889564D /* Resources */ = { + E9D4145FA41F60FFAB33A07796D9ED97 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -2046,6 +2058,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 349A571C5C18BB9C6DBF0C9D0198BCFF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 782D51D7299EA0505DF697FF0E1A5D2D /* BehaviorRelay.swift in Sources */, + 94DD2520F1E5BDC7BAE2AA9414929AB8 /* Observable+Bind.swift in Sources */, + 5B958EBBC4FFF8E0E4FC78DB49E09C68 /* PublishRelay.swift in Sources */, + F036F4A375A2DC7D0E02A9FD523B3BEB /* ReplayRelay.swift in Sources */, + DBAB6D10C12919914BDDFB9F0B4C51AF /* RxRelay-dummy.m in Sources */, + E49F560E9968AD5B0333FB656D6E0454 /* Utils.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3DA8F71AF3BF41150950832BA8D64BFE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2158,298 +2183,289 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 45C3BC4897B6591A550A9A098F2F5AC9 /* Sources */ = { + 711D0196C287AF2F310C1BF8488B6A06 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 59C20AD81D8A3D0D24C365BE682D2044 /* BehaviorRelay.swift in Sources */, - 14DD900A869D976EEC05A4813F679F9B /* Observable+Bind.swift in Sources */, - D4281D376BB29F2F96DF52757BA89912 /* PublishRelay.swift in Sources */, - 944AF90199777093145684047F9B6EF0 /* ReplayRelay.swift in Sources */, - 9E3B20F28C8C31E0394B6D493B31CB43 /* RxRelay-dummy.m in Sources */, - B1ACEE046056D3B9457C03BF28B1AA4A /* Utils.swift in Sources */, + C6BC5D2F6DBEFF403E7C9FB77DF5CFA1 /* Pods-GenderList-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5D28D6962A06E93A50CCF281C680B008 /* Sources */ = { + A9243C3B30674855204D62AE94A26B72 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 822B70E128AA35F7DED0473AD11C89E4 /* AFError.swift in Sources */, - 0D8821DA7F4A20C4E52375DE9EC7B3C8 /* Alamofire.swift in Sources */, - A08D8736FE6C8059C87375D944E21CCE /* Alamofire-dummy.m in Sources */, - 1511A1B3AAE6EA7518B9F27064AED034 /* AlamofireExtended.swift in Sources */, - E7F5132BB0CB075F62DE7233B1E8D815 /* CachedResponseHandler.swift in Sources */, - 9CABA1A19C31DE6C3584C3401C92AF51 /* DispatchQueue+Alamofire.swift in Sources */, - 61158247CA68DF1C2AA169178DFD43AB /* EventMonitor.swift in Sources */, - 11D7AF9C6C5DF6D54FB9BB57FF95C789 /* HTTPHeaders.swift in Sources */, - 52BC0E84656F7A31868BE9E1E826B861 /* HTTPMethod.swift in Sources */, - FA912508169DBC6AE52589B4499BE6A2 /* MultipartFormData.swift in Sources */, - 58FF69B2022DF80F0CFE59CB5DC1169C /* MultipartUpload.swift in Sources */, - E6E9A5BB0387E3074B7BA055474CDE59 /* NetworkReachabilityManager.swift in Sources */, - D088CDD616285144B06805DAC3E47543 /* Notifications.swift in Sources */, - 8E788A72E56879B3ED1A70D386AB95F4 /* OperationQueue+Alamofire.swift in Sources */, - 32339670CD2AA246DD7A83E12958CB32 /* ParameterEncoder.swift in Sources */, - 5CFA5A0140CC19B2DAC917D2B7FE50F1 /* ParameterEncoding.swift in Sources */, - 76016889CAF09F56BDCBAF164A7BD69E /* Protector.swift in Sources */, - 9D7E94CA1A80F71F0F36935EBD962BA6 /* RedirectHandler.swift in Sources */, - EE2101E9CCE79962CDBD4DC80820F0B5 /* Request.swift in Sources */, - 6809F42AF2E7EF87D708DB9257980AF2 /* RequestInterceptor.swift in Sources */, - 4053ECC897CAC1F62BC99C732FCF580B /* RequestTaskMap.swift in Sources */, - CA5984DF04522F23CBDC05BD8D26CB46 /* Response.swift in Sources */, - 4E4FA63E47752799E2D6C2FD52174D25 /* ResponseSerialization.swift in Sources */, - B1B2DF0164DB3B361FAD1518990042F4 /* Result+Alamofire.swift in Sources */, - 58BC77C4865C8C2A99EC1D93BF2B3E55 /* RetryPolicy.swift in Sources */, - 4B20D5B43F5C7A0643124D1C40FB5EE8 /* ServerTrustEvaluation.swift in Sources */, - B3C7C0BD02306392F5842FD94F4E0963 /* Session.swift in Sources */, - C9B8095CA60D3719A0E3E5B20E7317BA /* SessionDelegate.swift in Sources */, - D7485F98CA583821F27B453525AE3FC4 /* URLConvertible+URLRequestConvertible.swift in Sources */, - 1451EF8D38345972B7802EC526427399 /* URLEncodedFormEncoder.swift in Sources */, - D80F8F9C519042D5C4963C3C6EB38EDB /* URLRequest+Alamofire.swift in Sources */, - 610044A23AE8E11EBFDADF534B1521A1 /* URLSessionConfiguration+Alamofire.swift in Sources */, - 8CDD7DDE4746E8DB08FD5347452EAB88 /* Validation.swift in Sources */, + F34578BEEDA58C8BDF8702399A238306 /* AddRef.swift in Sources */, + ADD49C3CC3A47AC337AF803D2B5B4FE4 /* Amb.swift in Sources */, + 9B4F0DB0CEA7727BBC0843626D2348DD /* AnonymousDisposable.swift in Sources */, + 3953280F8C27DD40045ECE5587F04113 /* AnonymousObserver.swift in Sources */, + C4D8634C6869EB91981E145F18775A64 /* AnyObserver.swift in Sources */, + 9D647894171B5678D7B8D4F0DD977E46 /* AsMaybe.swift in Sources */, + B47E0A20015DE86B789B6A3E4FA754EB /* AsSingle.swift in Sources */, + D716934FDB93FCCC0BA121FC16F86003 /* AsyncLock.swift in Sources */, + 4C9977C27EEB2F70FC2960A8F25F20E1 /* AsyncSubject.swift in Sources */, + 8B7AE8992E8C60B42CE14F1872BD4C45 /* AtomicInt.swift in Sources */, + EE5C6659976F87DF6888948A75E58F45 /* Bag.swift in Sources */, + 3B192E4F4FD9236B7377A1E736B252F5 /* Bag+Rx.swift in Sources */, + BB80D663FC32A2B643E8EFE8671A8AF9 /* BehaviorSubject.swift in Sources */, + DB065281A8ACCBF9F5AFB9C5CD5C488E /* BinaryDisposable.swift in Sources */, + 8E1AB4F2C63A8078B1C5C2922465AF7E /* Binder.swift in Sources */, + 6FF209306C29489DF512C727B4E4DCC3 /* BooleanDisposable.swift in Sources */, + BFBB09BD0FC31CA7FC9FAF63F25EAB49 /* Buffer.swift in Sources */, + D7FFB20DEF62B5311AA24C09E90C5696 /* Cancelable.swift in Sources */, + C3B55E6E14235355F0D858809F96318F /* Catch.swift in Sources */, + E0523EFFB9B91BFE897AF4EA59992528 /* CombineLatest.swift in Sources */, + 50009D0F858892024A16085E8B346B17 /* CombineLatest+arity.swift in Sources */, + 633A41FA0728734F44C49A443754C45D /* CombineLatest+Collection.swift in Sources */, + 335964ACF4856C6B63F2B31C4FE80C0D /* CompactMap.swift in Sources */, + E408A0761AF60EC8947CF34CBACBAF83 /* Completable.swift in Sources */, + EED0FA7D328B5BCC64D1F1A1C07F4F17 /* Completable+AndThen.swift in Sources */, + 143B498E689291494AD40758D734F974 /* CompositeDisposable.swift in Sources */, + F2637EBEAB45BA2D52A80EB3BE34D0F0 /* Concat.swift in Sources */, + ED1E4EBA6AC82C9BE22E8E05FF04B00F /* ConcurrentDispatchQueueScheduler.swift in Sources */, + 2BB7186EA78C0BEA6074FA94DC89EF93 /* ConcurrentMainScheduler.swift in Sources */, + D10AD22245405AE890465C359AE813DC /* ConnectableObservableType.swift in Sources */, + 726CC8E67AEF2AECA324D73D91F86E5E /* Create.swift in Sources */, + 12CB7722128E10A05B97E964648176A9 /* CurrentThreadScheduler.swift in Sources */, + A0EAE575DF5FE7FF693B676BD39D1628 /* Date+Dispatch.swift in Sources */, + 59E4C80E4BFC34BBDC3843468E7F5C9F /* Debounce.swift in Sources */, + 262D15F6C2011395F33AB0501C7461E1 /* Debug.swift in Sources */, + FC24217137CD93C7004E0FE6C888C711 /* Decode.swift in Sources */, + 638A599E130C01F966B9CC278E8F03A2 /* DefaultIfEmpty.swift in Sources */, + 224AAE0A17EFBA22B5BB1C6ED639F402 /* Deferred.swift in Sources */, + 244D5334C89FF0F1985C9D808A76BAAB /* Delay.swift in Sources */, + 84FB94B98DBAD3F0C0100684A1688F8E /* DelaySubscription.swift in Sources */, + 825016F72360D2F15B9E6C5B26E8C5FE /* Dematerialize.swift in Sources */, + 5E5A0F9120F5C46656492BBD936C1C35 /* DispatchQueue+Extensions.swift in Sources */, + 2908872F21FB19B361D3652D0056DFDB /* DispatchQueueConfiguration.swift in Sources */, + 080E0523C9BBA39EF80A71980E51DA5E /* Disposable.swift in Sources */, + BDBD294E7476703843206D8CF206FAE1 /* Disposables.swift in Sources */, + 17FAB8774A648669CA75A478645DF845 /* DisposeBag.swift in Sources */, + 5E73FEAB8A1545E0C163D1839944F0A1 /* DisposeBase.swift in Sources */, + B88BD26F9E6E1815FD277AA2EAA42A6B /* DistinctUntilChanged.swift in Sources */, + E0A9ED57BC88DF643279F8146984E452 /* Do.swift in Sources */, + C2C5D8B4AF75769B70EB40321609D4E5 /* ElementAt.swift in Sources */, + 0C2471C1F78F47C8696883DA70244567 /* Empty.swift in Sources */, + 8BB2A01CEAD519EFCA788C230C4CE749 /* Enumerated.swift in Sources */, + 2E54617FA1E9EC5685D2A4B074AC6933 /* Error.swift in Sources */, + 775E21559F53F43E4718A6702A8E14D9 /* Errors.swift in Sources */, + 4DD16CA967818B2FEB373D8CA1F7EBBE /* Event.swift in Sources */, + 5F3F75D02881D26486C189483E69ACA8 /* Filter.swift in Sources */, + A1219B093051C45CDB7785A418B9F2E1 /* First.swift in Sources */, + F73ED54E02EC026FB2F7DC28629E1E7C /* Generate.swift in Sources */, + 857B833BCB63CD49D92586E88C015EFD /* GroupBy.swift in Sources */, + D3B02ADE07B83FE23250F00B136ECD4D /* GroupedObservable.swift in Sources */, + 14103A1B6CD67EF986AD72A427DAE05D /* HistoricalScheduler.swift in Sources */, + 11C98784D59E26A28BAA5B6C6E124171 /* HistoricalSchedulerTimeConverter.swift in Sources */, + A56DD9B245C6C527525315654E2AD44C /* ImmediateSchedulerType.swift in Sources */, + 8AEC3BF02D80F6C75FB754802E1641DB /* Infallible.swift in Sources */, + 54F25F05FDC2C9ED679D2F07D5918CA6 /* Infallible+CombineLatest+arity.swift in Sources */, + 2A7A4AA32A47E5F76D5852627E847709 /* Infallible+Concurrency.swift in Sources */, + 33F9D0BE9DCCCD1D5CD5E031DA5658AA /* Infallible+Create.swift in Sources */, + 4955DFA99D7133906B964B9EE450AF0B /* Infallible+Operators.swift in Sources */, + 47BBB96A017E25A9A46FB25B67005A0A /* Infallible+Zip+arity.swift in Sources */, + CFDB98312025EA51DD6FF7F4BF65EB53 /* InfiniteSequence.swift in Sources */, + 48E7D5060B8D84903A3B3ED21E4B5AB8 /* InvocableScheduledItem.swift in Sources */, + E8BDED8DBAE36031B05D2F2BDF8B72F3 /* InvocableType.swift in Sources */, + 958EBCEB7DDEAE24ED5FCAF0F89A3AAF /* Just.swift in Sources */, + C80C3B232CDBC4596819D48611CD3F3C /* Lock.swift in Sources */, + 272DA99C6C6A82CCEF70E8CF8B873D94 /* LockOwnerType.swift in Sources */, + 50472850F81811172F8C41BFAB77D6DC /* MainScheduler.swift in Sources */, + 93AA229451CA5480337B1EE292631D31 /* Map.swift in Sources */, + 05A8F828C4201F7676F7CF8EB8702202 /* Materialize.swift in Sources */, + AB39D86F22CEF5983E1DAFFEAEEEB62E /* Maybe.swift in Sources */, + E9BCADF22375CC2F8E6EB4E0B1BC565C /* Merge.swift in Sources */, + 6621E9558615DCE7B0D32A0FA29D1591 /* Multicast.swift in Sources */, + DB8C1AD404036A35DDED5CD6660BAB39 /* Never.swift in Sources */, + F93C4E366639FD5D2A32446038DD7E60 /* NopDisposable.swift in Sources */, + 35ED77A85463DDBF1675121107B5CFF6 /* Observable.swift in Sources */, + E54F0E7CEDDAC5664A8C83E4686D6CBB /* Observable+Concurrency.swift in Sources */, + 34105401692F3D13E36B351C7DC642F8 /* ObservableConvertibleType.swift in Sources */, + 07166547D925FBEA343B0422FD7DEB7E /* ObservableConvertibleType+Infallible.swift in Sources */, + 3AD67A2DC04944CE5AE9B9BD8721542E /* ObservableType.swift in Sources */, + 74834D7DA6CD66CF130C58E3E08994EB /* ObservableType+Extensions.swift in Sources */, + B969B7566F02943CD0E6225B99046B7A /* ObservableType+PrimitiveSequence.swift in Sources */, + 10AD2C259E9DECD6516963DB76B0C6E7 /* ObserveOn.swift in Sources */, + A94A3108B2C0BF641D8844073D6AA4E5 /* ObserverBase.swift in Sources */, + 9A4DAB9C0D2A74A496D10C7A648E3162 /* ObserverType.swift in Sources */, + EC225E6F8AF67896298772E4C76F724D /* OperationQueueScheduler.swift in Sources */, + 40B0E9A4872CE86561E028853C812D79 /* Optional.swift in Sources */, + DAA64B0B05454217B68219FE3382E2FF /* Platform.Darwin.swift in Sources */, + B7C50E1B30639A2AEA990DAEA803D877 /* Platform.Linux.swift in Sources */, + E94BCEDFF9A03206CFEBBE8F3F432C68 /* PrimitiveSequence.swift in Sources */, + B7073CAE42F064FE8640EC42C0C02C94 /* PrimitiveSequence+Concurrency.swift in Sources */, + 10E168448465F345FD4B066137DDE094 /* PrimitiveSequence+Zip+arity.swift in Sources */, + 07582CEA8DC77C25931E0DDACC0C3269 /* PriorityQueue.swift in Sources */, + 7D6988D0E6DAFBFD5F7653036BAD1172 /* Producer.swift in Sources */, + 30861AE693796F9D18ADE3D3C5035775 /* PublishSubject.swift in Sources */, + E4DDB40B82C96C4FCB820E5B2ED5EC2F /* Queue.swift in Sources */, + 6E12D7E0202CB4077514D77014910636 /* Range.swift in Sources */, + 9D68AB68528E2196882E63F5253B803A /* Reactive.swift in Sources */, + DAB3CB1F3375E2DF78FED00410552E18 /* RecursiveLock.swift in Sources */, + 9CE4F36B67C9DAEC1DC2DE6CA692D0C4 /* RecursiveScheduler.swift in Sources */, + 9BAAAA76EE3244511BBD43460DE1AAB6 /* Reduce.swift in Sources */, + 6B4D7AE51568761741BACB3CE30BC275 /* RefCountDisposable.swift in Sources */, + 7BD154ABB5889C5A57C73038BC1046AF /* Repeat.swift in Sources */, + 0B12E30FD2871EBA945FCB86CC41E19F /* ReplaySubject.swift in Sources */, + 34CBBF97D5515146BBA198F412D71863 /* RetryWhen.swift in Sources */, + 253D546E5EB89E7C442A752B69564D13 /* Rx.swift in Sources */, + 8BCD24C9CB7B9B8C7E9A5E67C33D7474 /* RxMutableBox.swift in Sources */, + 58291D4289D4B0CC40B2C905DA32D991 /* RxSwift-dummy.m in Sources */, + BB4D9C116889C08F6B6D1B54C39FC843 /* Sample.swift in Sources */, + 792F9356B8A8971A54A4AB8AA8D0A917 /* Scan.swift in Sources */, + F4AECC16327D7D58BC13201D44914534 /* ScheduledDisposable.swift in Sources */, + F731500D5D34F172EB459E8ADEE76116 /* ScheduledItem.swift in Sources */, + 27BA74FBFD8AD9ADF754DF034688F72E /* ScheduledItemType.swift in Sources */, + 60283BFFCB1E70EFF8D69CA3012E4D6C /* SchedulerServices+Emulation.swift in Sources */, + 68C8CB4EEC0D15EBBD6EFE6E11CD2BA9 /* SchedulerType.swift in Sources */, + BED0BB02AEC5E805083AB1C27FFABD47 /* Sequence.swift in Sources */, + A35744339D7CDDB79F14A079F613690F /* SerialDispatchQueueScheduler.swift in Sources */, + D8AD61EB551C0149A4E73B329453A728 /* SerialDisposable.swift in Sources */, + 5050D694CF073366EC942B2D517ED517 /* ShareReplayScope.swift in Sources */, + 68627C9B9C94CBE9310082E5F3B80CB8 /* Single.swift in Sources */, + 070B0668A4816AA8D209CE03F1AA1745 /* SingleAssignmentDisposable.swift in Sources */, + 759FF7C6BA173954BA0BE5F3B5D77E24 /* SingleAsync.swift in Sources */, + CD5F9A08105A83748118F9C42AE9A59B /* Sink.swift in Sources */, + 0DB401851069F210560BA725D4F4CAF6 /* Skip.swift in Sources */, + D5345CAD9E5F5AF025A6DC493CC5012F /* SkipUntil.swift in Sources */, + A43E1C231F1C28313CF575404CEE0545 /* SkipWhile.swift in Sources */, + 040F811D74F46D9E5E2E21E279A286BE /* StartWith.swift in Sources */, + F6DA3B5199D0556BBF9D1EFF83ACE7F6 /* SubjectType.swift in Sources */, + 82599CDDE7F5D00506446BDB932AEB5C /* SubscribeOn.swift in Sources */, + 05DB3398410D00A29CAB5182BF082F2E /* SubscriptionDisposable.swift in Sources */, + DC6376BDCF34BB4FACC68A1787340936 /* SwiftSupport.swift in Sources */, + 8FB6F81C2CAD8C37AED9FAE35CC8F8CB /* Switch.swift in Sources */, + CD7328672FB232064C60AF7F5846F2AC /* SwitchIfEmpty.swift in Sources */, + BFAFD7E071AA3B256C9DD2FD4FE462D3 /* SynchronizedDisposeType.swift in Sources */, + 43E32A0D5CFF0E59D7A2182666D07FCF /* SynchronizedOnType.swift in Sources */, + 19BADD00C75B7763A633262950845DAD /* SynchronizedUnsubscribeType.swift in Sources */, + FBD01C51DBA0CD35DA12E49D3A67CB7A /* TailRecursiveSink.swift in Sources */, + 484F54DC8118EEE2B1A4C75255E7F8B7 /* Take.swift in Sources */, + EE82D9114F96C918AA152FA0B7AA597C /* TakeLast.swift in Sources */, + B41169CFD62EFFFE57DA3CA725B8461A /* TakeWithPredicate.swift in Sources */, + AC0F2D4998FF0301C35D35076221D223 /* Throttle.swift in Sources */, + E099A76F2AF38F26409311E143CD92EC /* Timeout.swift in Sources */, + D8EDE74BEBFFF3EA4FB0A6223EF2E1C8 /* Timer.swift in Sources */, + F789D652321ABC8CADCF962C85B1B80C /* ToArray.swift in Sources */, + 1B7FA91C59963D6D4ACFEAE8A4A57346 /* Using.swift in Sources */, + 7AF4F47073D13BB9B24AC26CED06E503 /* VirtualTimeConverterType.swift in Sources */, + 5684D133C829112C7ADF363416BE1023 /* VirtualTimeScheduler.swift in Sources */, + 52E98DC0EC5189A4A8979FCAA0C329AB /* Window.swift in Sources */, + 58E22287DB9EDE093A147780A1F65203 /* WithLatestFrom.swift in Sources */, + B4738CD9680FAC78FE01FF5BBC400038 /* WithUnretained.swift in Sources */, + 1A332D930FE477DE8318B47F7803A563 /* Zip.swift in Sources */, + 50462A7E9A48D23F5CFE2064EE003681 /* Zip+arity.swift in Sources */, + DCA42663650B6F75040B37A900E2C869 /* Zip+Collection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 60E9B9EDF3B805933006483196471DDE /* Sources */ = { + F5D2A45FBA06D86A537CB441D5BF4FF4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC3B023EC3C6BE247CB08313FD0E2483 /* Pods-Bunjang-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7DBB2CB1F7CA60E80AAA32AB49B80823 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1637E895C6DF5D03D94B7FB4D4058094 /* AddRef.swift in Sources */, - DBF30FEB15CAB9CFE1DC70FF95DD03ED /* Amb.swift in Sources */, - 2513FB19DADC28C9C34578D1E1E4AB49 /* AnonymousDisposable.swift in Sources */, - 209DFCE93A5CF41A91DCEC111EB56FB8 /* AnonymousObserver.swift in Sources */, - 0AAED9A61C81D9CB80C27AB80B3042F0 /* AnyObserver.swift in Sources */, - DAFDAD884F67D6AA40088987D130DC69 /* AsMaybe.swift in Sources */, - 56773BCCC6027789CC30E65B945FE7D5 /* AsSingle.swift in Sources */, - FA716F33C3239E937506439FE68C732B /* AsyncLock.swift in Sources */, - 6FB7A5C90343ED969159858AEA885639 /* AsyncSubject.swift in Sources */, - FA9A2BA92C72AFEF5E1E8F2141B792B1 /* AtomicInt.swift in Sources */, - B6AFF30D6B83658083BB0EB7F85B31CA /* Bag.swift in Sources */, - 9B4D9E5E699A755F9013731FB60B7307 /* Bag+Rx.swift in Sources */, - 38931F9E5F98AA760F597D471120E2D8 /* BehaviorSubject.swift in Sources */, - 0D5C6C08DC865F5735FFC53083A87E34 /* BinaryDisposable.swift in Sources */, - 6FE1C0099BB8E039449105BC0820A834 /* Binder.swift in Sources */, - 74A20606A8ABFD4E9EA4072EAE731A0D /* BooleanDisposable.swift in Sources */, - B6CD84CFA3C7E07113D00386C040154B /* Buffer.swift in Sources */, - 95401E770FE8BA7DFC627DD4E0DF9332 /* Cancelable.swift in Sources */, - 9BB83D2CE954C1BCC44121855A24C138 /* Catch.swift in Sources */, - 39C9D0DD86007D936C1EF580BBCBECD8 /* CombineLatest.swift in Sources */, - 2EBACF29960484C3DD698ED9CE49DE8B /* CombineLatest+arity.swift in Sources */, - 003529825227D8DD63F0BF82EC1495D3 /* CombineLatest+Collection.swift in Sources */, - CEA1126250329AC5A8181BBCBA80CD5A /* CompactMap.swift in Sources */, - 67C3CC2453D19199BC14F0E8BD183F3A /* Completable.swift in Sources */, - 5F9AECE565196E2EB2CEF43694CDAC08 /* Completable+AndThen.swift in Sources */, - 5AAE664159A7CE1263984D03D674CC57 /* CompositeDisposable.swift in Sources */, - 90A13F35A0D225B2FC6A5FE32F656CCD /* Concat.swift in Sources */, - 3A9561E1B5358D977E435B6EB6A4F6CB /* ConcurrentDispatchQueueScheduler.swift in Sources */, - 25D532E8E212D1E6D3A57ADFC56A4BA8 /* ConcurrentMainScheduler.swift in Sources */, - B991B7EFAB91CF6280270C2E939EEDBF /* ConnectableObservableType.swift in Sources */, - C2A71FE4B9A99CB90127EC09B40CEFE7 /* Create.swift in Sources */, - 3E77C4C09A0F4336872981489D54B383 /* CurrentThreadScheduler.swift in Sources */, - 829B41365DFC653EE4B09C3ABAAF2EC9 /* Date+Dispatch.swift in Sources */, - A7DB13E49A7C583C9162D51AF461A42B /* Debounce.swift in Sources */, - 62F7E0692A2C56BA6C97B3B1673865C0 /* Debug.swift in Sources */, - E2DD0D46EBDC369F2679C8652EFF57D3 /* Decode.swift in Sources */, - CC3A80A9DCB4EBE43A7E6CF0BFBFAF40 /* DefaultIfEmpty.swift in Sources */, - FFE11DF8D55C540876E9DDDC8AEEF5F4 /* Deferred.swift in Sources */, - 6C45AF088F0853A8BAAB07D760346418 /* Delay.swift in Sources */, - 436E17890492213E314F4522A84066E9 /* DelaySubscription.swift in Sources */, - F99C7F747D5923B1FA1BD0391689DD02 /* Dematerialize.swift in Sources */, - 45B5AB484F2602A280ADA0A58F37DC44 /* DispatchQueue+Extensions.swift in Sources */, - F86B6E741E98823EFF48A83143AB2DE5 /* DispatchQueueConfiguration.swift in Sources */, - 5CB24643A7A71F1C5B71662C275DD1B1 /* Disposable.swift in Sources */, - 6DDAA0D48EB19B7474873856BEF70E60 /* Disposables.swift in Sources */, - 0EC603595AF7780DCAD4BB7B627429BD /* DisposeBag.swift in Sources */, - 2BA426F407BDD206249741EE13AB5B96 /* DisposeBase.swift in Sources */, - 694F385519AE5B93B76AA6B631A3FE6D /* DistinctUntilChanged.swift in Sources */, - 2EB095DFF0B594D56E26FE6B1F74EB4E /* Do.swift in Sources */, - 3FDCE9C2E56ABA304C073C50BAD9D846 /* ElementAt.swift in Sources */, - CE2DEFBFB3BE1FCBDE3F2E31E31523B8 /* Empty.swift in Sources */, - 739248AE796F5C0C2EE3B203A588F053 /* Enumerated.swift in Sources */, - A3BF27E4FF783118AF78BEA42B84F276 /* Error.swift in Sources */, - EB0B3FE0AC29ABE1F29157FF00372579 /* Errors.swift in Sources */, - D6789C85077D096CA8207A1D9506855A /* Event.swift in Sources */, - D94A213784584A035BCBD920F5523BED /* Filter.swift in Sources */, - D09D3D5580E233C6F91C67602EDCCAEA /* First.swift in Sources */, - 24B2DFC51D8E53D808B5AC4FEC136A8C /* Generate.swift in Sources */, - 3A65F4B7F9CB8CEB5AC5EE4BE071F147 /* GroupBy.swift in Sources */, - DA5010F0D48E5F17A1354FE9A04A54B0 /* GroupedObservable.swift in Sources */, - 6D0F7BA524BBC46B5AA273E74D1F1350 /* HistoricalScheduler.swift in Sources */, - 0711535FB48EC83DBCE90D4E9CCE53DE /* HistoricalSchedulerTimeConverter.swift in Sources */, - E66514C0F6827614A173DAC5EE6A488E /* ImmediateSchedulerType.swift in Sources */, - D1176BD914607FCC189C844DCD985300 /* Infallible.swift in Sources */, - 24C5A0C0ED89D44C92D190198464F891 /* Infallible+CombineLatest+arity.swift in Sources */, - 65012CCC998A71F7171507D3D9926743 /* Infallible+Concurrency.swift in Sources */, - 23C85249FB680DCA52B7BA19476D5CE4 /* Infallible+Create.swift in Sources */, - 006A2002DB7553ED9AB3618CBC63E855 /* Infallible+Operators.swift in Sources */, - 2217757B24795601647F0A8F172A4612 /* Infallible+Zip+arity.swift in Sources */, - 5A225B75EBBF38DEA451267FA35A4A4B /* InfiniteSequence.swift in Sources */, - 62312BD25740FFB6F894687787F19895 /* InvocableScheduledItem.swift in Sources */, - 8EAF6BAB0FAC544040F4D9525886B4F0 /* InvocableType.swift in Sources */, - A4ABC2AEBD37D5B207258ECEEF37262B /* Just.swift in Sources */, - 1274F535FAD2AB23DA7B5D68770F529D /* Lock.swift in Sources */, - DEEB75010ED18CFCC5FA49B8AFF4F58F /* LockOwnerType.swift in Sources */, - 4D2795A04C8D7F78E90CE57F8E46D2DE /* MainScheduler.swift in Sources */, - AF82ABAD5431E3BF68E7F7EEE6703790 /* Map.swift in Sources */, - FAFC45EC2A1770619807DFC5722F4B6A /* Materialize.swift in Sources */, - 598CCA9A622AB8C28137F88F2F81946A /* Maybe.swift in Sources */, - 4BB57F93FFEE136168CE36C6FE8FD36A /* Merge.swift in Sources */, - 1676EBFB2688BEF9C5735FC4367BE9AB /* Multicast.swift in Sources */, - 6CD459A51DEC60BFE1BEEEA5B7AE9A1F /* Never.swift in Sources */, - 51F6DE8F86098D052F18DB94A0B591DF /* NopDisposable.swift in Sources */, - DA0B42F2B99DE08DA649A2D34E014EDF /* Observable.swift in Sources */, - 4831619FAA4A43853E9C48F30BDDED66 /* Observable+Concurrency.swift in Sources */, - D180D3EC24CE4493964AB67D1D6AD011 /* ObservableConvertibleType.swift in Sources */, - 4B9A3ACA475440CCA081FD2829B1B2E4 /* ObservableConvertibleType+Infallible.swift in Sources */, - 650D5723A58F1250568D3E47E7423564 /* ObservableType.swift in Sources */, - D318EAAE231337A1B12B985FFC561C8C /* ObservableType+Extensions.swift in Sources */, - F06F8EFE57A2F601B0D79E47A80DD6C7 /* ObservableType+PrimitiveSequence.swift in Sources */, - FB10CE2650787118D7250EA1A14A157B /* ObserveOn.swift in Sources */, - 1ABA1120B49E8646A878BBFA7C8BB8F1 /* ObserverBase.swift in Sources */, - 65D3F59FCA86FA9AE473EA080B95FFDA /* ObserverType.swift in Sources */, - CDA2A03D0C1CB2DA6C6C155F4A6B4DC6 /* OperationQueueScheduler.swift in Sources */, - 4BFD24472E22B70B71809D3B63DCFDCC /* Optional.swift in Sources */, - 24A65E78F2118F2166E6B18444780FBE /* Platform.Darwin.swift in Sources */, - C1EAEBA09776DA989D99A07A34029DE0 /* Platform.Linux.swift in Sources */, - 731CF1B7C9778F1758FB8E444C847E69 /* PrimitiveSequence.swift in Sources */, - 541417E3C2DE409F8EB4EEB0DA9E94AE /* PrimitiveSequence+Concurrency.swift in Sources */, - 9BCBD89FB47D8651F43CC3038F478D08 /* PrimitiveSequence+Zip+arity.swift in Sources */, - C09DE156BA8C2313CD4FCA9F2D78066E /* PriorityQueue.swift in Sources */, - E4991F3EEC8667D7EF0298765B0D7615 /* Producer.swift in Sources */, - EC96B25961BF365B71E26EC3A3DC2E74 /* PublishSubject.swift in Sources */, - D86E9AA28F30B9D4F2DB59F1CB006BDB /* Queue.swift in Sources */, - B48F081B2FF54539CC191A120592F17E /* Range.swift in Sources */, - 2E73AAE2F6805B99206072ED5F1277D3 /* Reactive.swift in Sources */, - 6BBFC14EA40F3BC8986B26D5B75573C3 /* RecursiveLock.swift in Sources */, - FDBED395B752051186CD060058C112A2 /* RecursiveScheduler.swift in Sources */, - 8F68369EEC708827854493097B84E7BE /* Reduce.swift in Sources */, - 6923E83262B245A9B8FF71B89ECC8155 /* RefCountDisposable.swift in Sources */, - 08C84EEEE16985BD11B48DE78F6CE6D8 /* Repeat.swift in Sources */, - 0F92B9A07E035FA87974066F7F77324D /* ReplaySubject.swift in Sources */, - DC309086C2612291A6B8D6A8D9A94836 /* RetryWhen.swift in Sources */, - 3765A7BB07948D911C3967CA00ABD8D8 /* Rx.swift in Sources */, - E1FC31214C2340E23E72E185CC628C9D /* RxMutableBox.swift in Sources */, - 956D43D9E3DB5A3A4AE69E9F412D1112 /* RxSwift-dummy.m in Sources */, - 03B10230C0061FFC0A8DFEE43D89E34E /* Sample.swift in Sources */, - 3480362213CE1B3E13CA6FAFFD8BF9AE /* Scan.swift in Sources */, - 05B17AA3CBF543D79BB998C04CC622A5 /* ScheduledDisposable.swift in Sources */, - ADC265B95181064F5E1C8FA0F1978B0F /* ScheduledItem.swift in Sources */, - 087E291F962A0417B329954FD7C3F893 /* ScheduledItemType.swift in Sources */, - 038AB96B88DB40E752F02C8FCE7660DD /* SchedulerServices+Emulation.swift in Sources */, - 40F3DAF1936046738D56C2C9756233B9 /* SchedulerType.swift in Sources */, - B39E291F03ACB2AB079AE475BB6DADC1 /* Sequence.swift in Sources */, - 4064E1BA55209CB585990AC94219994A /* SerialDispatchQueueScheduler.swift in Sources */, - C36D23C03A0ECE1CF1807CEB233F822D /* SerialDisposable.swift in Sources */, - 87D4D0B024FB3E0DB6AA42AE272922A1 /* ShareReplayScope.swift in Sources */, - 0C71B7665BA02D8C812B1BAB001AFBF3 /* Single.swift in Sources */, - 062FE837FDFE764F1D436E09091F603F /* SingleAssignmentDisposable.swift in Sources */, - 3A6190395ABD4FAB0D01396D60ECEE90 /* SingleAsync.swift in Sources */, - 2FCB2ACD70577ABB671FE45F3C9070BB /* Sink.swift in Sources */, - 98E063B537BCA078F9EFF48CD9189E11 /* Skip.swift in Sources */, - E14E0F5CD9A3C6D97ABE3593D74A675E /* SkipUntil.swift in Sources */, - 89A2957DD94EE24A18A5CE0D99DA9B8C /* SkipWhile.swift in Sources */, - 8ED2643A0938F45F07DC3FFDAB9E87BF /* StartWith.swift in Sources */, - FE30D82C6943E1BFE447A6401F60F9C7 /* SubjectType.swift in Sources */, - 817E128FA1E910EC38D6B727766A2AFD /* SubscribeOn.swift in Sources */, - 1FDAC05CC3009148EDA8F5430102BCFA /* SubscriptionDisposable.swift in Sources */, - F3DAFB3407F9AA3DC771780393571F44 /* SwiftSupport.swift in Sources */, - D62994E37E5361799FAED88CB599F54C /* Switch.swift in Sources */, - BD37ABCE3F0BD0C29FDEFC3874E5A0F6 /* SwitchIfEmpty.swift in Sources */, - E74C07C3ADC2EC1297C9DD792F4705EA /* SynchronizedDisposeType.swift in Sources */, - 7FFF6C6E9ECB38992B4BE97E686DF2E0 /* SynchronizedOnType.swift in Sources */, - 02EFA6ACF4D3AE6304BC14E70446620B /* SynchronizedUnsubscribeType.swift in Sources */, - 1FFFBA87BB294E55ABCE4D9D0B3A7F0C /* TailRecursiveSink.swift in Sources */, - 42BB3620C4E2FBAB5B2C7FCD6DF2E4A3 /* Take.swift in Sources */, - ED3EFCEEC0DECC4B0075A3590045C90F /* TakeLast.swift in Sources */, - 7C9CEB951E1388233F0617DD97837946 /* TakeWithPredicate.swift in Sources */, - 7E28AE7A43EB26775F385138B147CDC9 /* Throttle.swift in Sources */, - E714A429777E3DC4B0FD85923B8152E0 /* Timeout.swift in Sources */, - 3A4BE47A7EA1BFB1F541C2CD484DBF00 /* Timer.swift in Sources */, - 8A9103B004B8EBE5AB836433B9662E16 /* ToArray.swift in Sources */, - FE3FB93D29E138FEF654FB00C5427502 /* Using.swift in Sources */, - 604CEEDB74A6AD3269EC939A3FEF5065 /* VirtualTimeConverterType.swift in Sources */, - 495D9476F1A771F92F04EB5B3D41A38A /* VirtualTimeScheduler.swift in Sources */, - 6468384FBFE289485D6B3C17A072948C /* Window.swift in Sources */, - F76AEE9A262B7167CA91A6D655B5E1ED /* WithLatestFrom.swift in Sources */, - 0DDEB8F8134858BFE1BD79BEE1306D5B /* WithUnretained.swift in Sources */, - FB780B6BCB35FF39AD890C2EA6A643D6 /* Zip.swift in Sources */, - 2A0CB23553025DF5BB5B60EFFFFEA7C2 /* Zip+arity.swift in Sources */, - 81B51CA6E417CF7D14C7BB733506C7DF /* Zip+Collection.swift in Sources */, + D0EA90FBF83350C49E6EF6C8A98D6F00 /* AFError.swift in Sources */, + F17A4CA4664CABB331D39FE902E06843 /* Alamofire.swift in Sources */, + 55AABB1FB38F61A3369ACC555FF3046D /* Alamofire-dummy.m in Sources */, + 1EE44196E7BCE57AD96A2C751651EF40 /* AlamofireExtended.swift in Sources */, + 7483E5327027263F7E4B94A2997191C4 /* AuthenticationInterceptor.swift in Sources */, + 2CBE3651CA006E19F5D64A2DE9B9A028 /* CachedResponseHandler.swift in Sources */, + 46A64A43AFA057B6B63C8F0C12F509B4 /* Combine.swift in Sources */, + 9C9030DEDB0DF955B16FE08C50892D57 /* Concurrency.swift in Sources */, + EEC150B66BCCD6C80FDA7E4D1975166B /* DispatchQueue+Alamofire.swift in Sources */, + CEBFFEED65D877702B2F36102528CF6D /* EventMonitor.swift in Sources */, + 7E02F5B62BE00E97847DF549FFED2490 /* HTTPHeaders.swift in Sources */, + D6B4751CED01D53E4A1B6A571AAA2F83 /* HTTPMethod.swift in Sources */, + 7FE695DA8EE7FF1286556E06B692009B /* MultipartFormData.swift in Sources */, + E9B4C89E7EB3B27D46AFCA452C3D426F /* MultipartUpload.swift in Sources */, + A29100AA1876DDEFF6F54694A51FDB0E /* NetworkReachabilityManager.swift in Sources */, + 2CCD13099063CD560E3067BD132914FA /* Notifications.swift in Sources */, + E54654D504A42C24F284A68F87F7671D /* OperationQueue+Alamofire.swift in Sources */, + 99D058E53EFEE3AC4857CDE3DBA5C004 /* ParameterEncoder.swift in Sources */, + 68FB2DCB4C77DBCAF9A6037E470F2BDE /* ParameterEncoding.swift in Sources */, + A53BDE589BDD6483F3EEDCE5EA1DCCD3 /* Protected.swift in Sources */, + 045DE6EBF9B2F63F60F5BE60C1198E06 /* RedirectHandler.swift in Sources */, + B3658C29BBDE1033F6269A92E612CB30 /* Request.swift in Sources */, + DD902FE8D6824681C929D028655AE121 /* RequestInterceptor.swift in Sources */, + DA34899BEF0668D76CBCE8C4CE47B97B /* RequestTaskMap.swift in Sources */, + 75966A9262648D4647D764E3E76BC6AC /* Response.swift in Sources */, + 824D816B1EE404F2DD400EE678695CBE /* ResponseSerialization.swift in Sources */, + 04A896288CE3A59B530250337A5F8362 /* Result+Alamofire.swift in Sources */, + 33A7D0F2D03004CE256A75E03DF33C70 /* RetryPolicy.swift in Sources */, + B704B198B9B520D449260877E300D821 /* ServerTrustEvaluation.swift in Sources */, + 81B8D2B7CEB25C2448B0BC9B33591A65 /* Session.swift in Sources */, + 1976BB7D7E26A12E29283E71154B63B3 /* SessionDelegate.swift in Sources */, + 7F1BB526AAE3ECDCE90127D9D0E10261 /* StringEncoding+Alamofire.swift in Sources */, + 8D75FC8D7476C9674234F39F1A820D8C /* URLConvertible+URLRequestConvertible.swift in Sources */, + 7930C94414B4C661867AC4FBE82E996C /* URLEncodedFormEncoder.swift in Sources */, + BC0ECA8F22DEDE8886E189CD0EAA1197 /* URLRequest+Alamofire.swift in Sources */, + 808C960C82D708FC1A42C581D6CB4940 /* URLSessionConfiguration+Alamofire.swift in Sources */, + 3C4059621E23842C19D4EB5D35B41989 /* Validation.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 007F2342B3F2B82A413D556E9C9A469D /* PBXTargetDependency */ = { + 11823FDA34AC4E6828EFCEC550D288D6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RxRelay; - target = 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */; - targetProxy = 854F098BFBDFA3723D6AEF7777467E06 /* PBXContainerItemProxy */; + name = SnapKit; + target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; + targetProxy = AF3BA24C3AF41AF3F89BF553B16F8FBE /* PBXContainerItemProxy */; }; - 3334D74C832F10DED70E9EEEB8D9F92F /* PBXTargetDependency */ = { + 2D3C3CF86E9D6AF5642D889394EB7D56 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RxSwift; - target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = C6BB5C37F54D38D25E46826777F121DC /* PBXContainerItemProxy */; + name = Kingfisher; + target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; + targetProxy = 96478020010384C4399E507618699E23 /* PBXContainerItemProxy */; }; - 5C31A9C3AE650740BE3434E650656588 /* PBXTargetDependency */ = { + 3FBB9763FAD09D117A8570A1FA16A303 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RxCocoa; + target = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */; + targetProxy = C6778CF39955835DA559F05115A4D9BD /* PBXContainerItemProxy */; + }; + 7999EB1FB260270C1210F82B94A6337C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RxRelay; + target = 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */; + targetProxy = 173BC9B3F5881CACC0CE1437A920FF38 /* PBXContainerItemProxy */; + }; + 81B32B604895087FD5D600570570DE06 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Alamofire; target = EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */; - targetProxy = C7F5300CAF31ED6AFE918DD939CA64D7 /* PBXContainerItemProxy */; + targetProxy = 79BFB001A8D6A44190A7FD4F46F046A1 /* PBXContainerItemProxy */; }; - 916E624A3930B2A5F289F9646BB1413E /* PBXTargetDependency */ = { + B668BDE011A5EB670307B4F521A12F3E /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = RxSwift; target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = 81F5647B19920D027D25D5BB99ED534E /* PBXContainerItemProxy */; + targetProxy = 22A1E6E92313779CBA6A3900B2D0CFE7 /* PBXContainerItemProxy */; }; - 965340EF18D1993D6B9F952A89F8AE10 /* PBXTargetDependency */ = { + C2C2D4AAD7E76229F98BE0C058AF1ED7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RxCocoa; - target = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */; - targetProxy = D6D10408CDC0FF1FE5DCB07182FCA8E9 /* PBXContainerItemProxy */; - }; - C2444E07E0A400983946A9CF1D821DEB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Kingfisher; - target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; - targetProxy = 0B478B41E95A2DC5598F23099F3895FB /* PBXContainerItemProxy */; + name = RxSwift; + target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; + targetProxy = 93E0660CA03CCFC2E35AEA166761669E /* PBXContainerItemProxy */; }; - C445127F601CED97C76052A8A7C8961C /* PBXTargetDependency */ = { + EDE1009088AD01D2D679023D4D60AB52 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = RxRelay; target = 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */; - targetProxy = E50211E3BFDF1DA64DB10E833C1B626E /* PBXContainerItemProxy */; + targetProxy = 1D024D715351BD74D6E027FF9CE20970 /* PBXContainerItemProxy */; }; - C9BB3A81247B5BC6B43AFC5334A58EE1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = SnapKit; - target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; - targetProxy = C836154FF498635455AFF8CCEC9B2B7C /* PBXContainerItemProxy */; - }; - EC7034FC667E1A3EF994D32000A3FF66 /* PBXTargetDependency */ = { + F1D006641AF99F2AE2AF2B4900B141ED /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = RxSwift; target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = D1C5985FCB75FF02E43174AB01BAC0C1 /* PBXContainerItemProxy */; + targetProxy = 8D7FCB7443BE2C836E75E00DE584C139 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 0FC3E35022B08B5C44926F83A908044F /* Debug */ = { + 1B72DC1FF379CAA1851CA031C1BA49BB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2B7CB3FCA9A4B086818B0611E2E9A449 /* RxRelay.debug.xcconfig */; + baseConfigurationReference = 8FD2D1EC03E239BF0A8EF6F05A8C0BC5 /* RxSwift.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2459,8 +2475,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2468,81 +2484,9 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; - PRODUCT_MODULE_NAME = RxRelay; - PRODUCT_NAME = RxRelay; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 226E962545103472EEDE5C263E40AFDC /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 191B10FB8FC2B7DDBC84A8208CA00B22 /* Pods-Bunjang.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Bunjang/Pods-Bunjang-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Bunjang/Pods-Bunjang.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 4473798B5CC9BCAEDCA9DD865ED30510 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A767B65FB96753CA10F8AAB2477D9DF9 /* Alamofire.release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Alamofire/Alamofire-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; - PRODUCT_MODULE_NAME = Alamofire; - PRODUCT_NAME = Alamofire; + MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; + PRODUCT_MODULE_NAME = RxSwift; + PRODUCT_NAME = RxSwift; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -2620,9 +2564,9 @@ }; name = Debug; }; - 52416C32B5ACD7A6426905C42AA1BC5E /* Debug */ = { + 577A24D81FA00BED9154F445BE58F743 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 12098C2818AEF2B5F2BF1C8B8C14E647 /* RxSwift.debug.xcconfig */; + baseConfigurationReference = 61CE5FA8C390F7C5066EE1B035CF5037 /* RxCocoa.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2632,8 +2576,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2641,22 +2585,23 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; - PRODUCT_MODULE_NAME = RxSwift; - PRODUCT_NAME = RxSwift; + MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; + PRODUCT_MODULE_NAME = RxCocoa; + PRODUCT_NAME = RxCocoa; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 577A24D81FA00BED9154F445BE58F743 /* Release */ = { + 67E3395D5CDC57F5024E2D316B5D98C5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E29D4C339F968E99A592A06B33343DD /* RxCocoa.release.xcconfig */; + baseConfigurationReference = 2B267869B6FE5FC5CB863F860C1C1FAD /* RxRelay.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2666,8 +2611,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2675,23 +2620,22 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; - PRODUCT_MODULE_NAME = RxCocoa; - PRODUCT_NAME = RxCocoa; + MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; + PRODUCT_MODULE_NAME = RxRelay; + PRODUCT_NAME = RxRelay; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - 68D0E20D9A42D50B2A8BFE359B341DFA /* Release */ = { + 7F1BDB8ADFF075205F793BDDB2551E08 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 44BED1C4650C3E0D28DE12A7A809D753 /* Pods-Bunjang.release.xcconfig */; + baseConfigurationReference = 4BFB8D4A76E253CF05CFDE137052A178 /* Pods-GenderList.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; @@ -2703,7 +2647,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Bunjang/Pods-Bunjang-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-GenderList/Pods-GenderList-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2712,7 +2656,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Bunjang/Pods-Bunjang.modulemap"; + MODULEMAP_FILE = "Target Support Files/Pods-GenderList/Pods-GenderList.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -2721,46 +2665,10 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; - }; - 716E6C3F92481897BE5758152D3165CE /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8634AC774363585D5917FFA4AEEF52DD /* RxSwift.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; - PRODUCT_MODULE_NAME = RxSwift; - PRODUCT_NAME = RxSwift; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; + name = Debug; }; 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */ = { isa = XCBuildConfiguration; @@ -2824,9 +2732,45 @@ }; name = Release; }; + 90A4588B06F8745E7FCD1B00204D6241 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9A2F68AB3AB4B514979EC4B758CC781B /* Alamofire.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Alamofire/Alamofire-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; + PRODUCT_MODULE_NAME = Alamofire; + PRODUCT_NAME = Alamofire; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.5; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 98A2FED692332B059F72A0554AB30342 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AD3677E72917440D5EA45F5BCB6B5829 /* Kingfisher.release.xcconfig */; + baseConfigurationReference = FAAF3645DF88E1E0DA21560E63737408 /* Kingfisher.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2860,9 +2804,9 @@ }; name = Release; }; - AE8273D7FD48350BA3135667E9B3CFA9 /* Debug */ = { + 9E98C04A5FA16D8AD5D48C1861179497 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A0B6997E7F68410D8A6C16644E3B92AD /* Alamofire.debug.xcconfig */; + baseConfigurationReference = BF856F895F5BD4D5F260053D673E8B93 /* Alamofire.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2888,16 +2832,16 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; + SWIFT_VERSION = 5.5; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - C12D9C5CC8F2071662A98F549A9E6FB4 /* Debug */ = { + B52E10CE08B56AC6873AB4C312F37FA8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FDCFCE5266BE0AD0A4A0EDB04177DC43 /* RxCocoa.debug.xcconfig */; + baseConfigurationReference = F060E67EDD1C139F8C56E3FD714779CB /* RxRelay.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2907,8 +2851,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2916,22 +2860,23 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; - PRODUCT_MODULE_NAME = RxCocoa; - PRODUCT_NAME = RxCocoa; + MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; + PRODUCT_MODULE_NAME = RxRelay; + PRODUCT_NAME = RxRelay; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - C4DB7F424087DF2800EF2ADD8443ECE0 /* Release */ = { + C12D9C5CC8F2071662A98F549A9E6FB4 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3C18A26F23ECE9BE8D5B1A6A198A0600 /* RxRelay.release.xcconfig */; + baseConfigurationReference = 5A1E2AE32DE9B16524DBF78CFF07F72E /* RxCocoa.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2941,8 +2886,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2950,23 +2895,22 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; - PRODUCT_MODULE_NAME = RxRelay; - PRODUCT_NAME = RxRelay; + MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; + PRODUCT_MODULE_NAME = RxCocoa; + PRODUCT_NAME = RxCocoa; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.1; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; CB8A79F7382B0A1227C38D59E7968EEA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FE70B944EB620CD61740D3BA724EACEC /* SnapKit.debug.xcconfig */; + baseConfigurationReference = C2FF21266D29953418187232F568362E /* SnapKit.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2999,9 +2943,81 @@ }; name = Debug; }; + D04E549320232F40C10BBCB3C0F8837C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CB204A7905DC8CDA462909EB4D19A184 /* RxSwift.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; + PRODUCT_MODULE_NAME = RxSwift; + PRODUCT_NAME = RxSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.1; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D4CDDB0166E2AA221EF687673B6E7F37 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EC93761C8ADB8B00344821B1B009F02E /* Pods-GenderList.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-GenderList/Pods-GenderList-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-GenderList/Pods-GenderList.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; DFFD31690F9CC8449FD1F803388E1D46 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 241D7299EBA5825B66091F231253D7E1 /* SnapKit.release.xcconfig */; + baseConfigurationReference = C92D5CEA71FB521BF9D2801EBFD0EDE3 /* SnapKit.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -3037,7 +3053,7 @@ }; E92C9F6CB6CB254B819BE03ABA462867 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9FF466253C12307D3952E7BF6496394B /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = 535245D6165D831E74CCF68877E016BC /* Kingfisher.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -3082,65 +3098,65 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + 3638F4146E7C5BF6C43C20F5C8D552DC /* Build configuration list for PBXNativeTarget "Pods-GenderList" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4BC7450F9457737EE3E637BA155B56F7 /* Debug */, - 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */, + 7F1BDB8ADFF075205F793BDDB2551E08 /* Debug */, + D4CDDB0166E2AA221EF687673B6E7F37 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4949A940CD53B7E293859B71C91C88F3 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { + 43D72C4AD858D20A6E2750CD96CBE4DD /* Build configuration list for PBXNativeTarget "RxRelay" */ = { isa = XCConfigurationList; buildConfigurations = ( - CB8A79F7382B0A1227C38D59E7968EEA /* Debug */, - DFFD31690F9CC8449FD1F803388E1D46 /* Release */, + 67E3395D5CDC57F5024E2D316B5D98C5 /* Debug */, + B52E10CE08B56AC6873AB4C312F37FA8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 54C4FCC4FD912A11231F09292F7C93A1 /* Build configuration list for PBXNativeTarget "Kingfisher" */ = { + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - E92C9F6CB6CB254B819BE03ABA462867 /* Debug */, - 98A2FED692332B059F72A0554AB30342 /* Release */, + 4BC7450F9457737EE3E637BA155B56F7 /* Debug */, + 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6C713B4993AB2D74A2656348044AC07D /* Build configuration list for PBXNativeTarget "RxSwift" */ = { + 4949A940CD53B7E293859B71C91C88F3 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { isa = XCConfigurationList; buildConfigurations = ( - 52416C32B5ACD7A6426905C42AA1BC5E /* Debug */, - 716E6C3F92481897BE5758152D3165CE /* Release */, + CB8A79F7382B0A1227C38D59E7968EEA /* Debug */, + DFFD31690F9CC8449FD1F803388E1D46 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D6686C9622B349A28A6EA8B43CE42228 /* Build configuration list for PBXNativeTarget "Pods-Bunjang" */ = { + 54C4FCC4FD912A11231F09292F7C93A1 /* Build configuration list for PBXNativeTarget "Kingfisher" */ = { isa = XCConfigurationList; buildConfigurations = ( - 226E962545103472EEDE5C263E40AFDC /* Debug */, - 68D0E20D9A42D50B2A8BFE359B341DFA /* Release */, + E92C9F6CB6CB254B819BE03ABA462867 /* Debug */, + 98A2FED692332B059F72A0554AB30342 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E6C32045F55A5C3BD79BFA54CFC9431F /* Build configuration list for PBXNativeTarget "RxRelay" */ = { + 6D9C7492118475169EBD3549EFC60B45 /* Build configuration list for PBXNativeTarget "RxSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 0FC3E35022B08B5C44926F83A908044F /* Debug */, - C4DB7F424087DF2800EF2ADD8443ECE0 /* Release */, + D04E549320232F40C10BBCB3C0F8837C /* Debug */, + 1B72DC1FF379CAA1851CA031C1BA49BB /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F286D0E597A0EFD8015B1A73656F64EB /* Build configuration list for PBXNativeTarget "Alamofire" */ = { + 8A212264186B8822192F9C369D7DE4BB /* Build configuration list for PBXNativeTarget "Alamofire" */ = { isa = XCConfigurationList; buildConfigurations = ( - AE8273D7FD48350BA3135667E9B3CFA9 /* Debug */, - 4473798B5CC9BCAEDCA9DD865ED30510 /* Release */, + 9E98C04A5FA16D8AD5D48C1861179497 /* Debug */, + 90A4588B06F8745E7FCD1B00204D6241 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/Alamofire.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/Alamofire.xcscheme index 120775c..fe38b07 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/Alamofire.xcscheme +++ b/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/Alamofire.xcscheme @@ -1,6 +1,6 @@ diff --git a/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/RxCocoa.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/RxCocoa.xcscheme index 3b88af8..29bd0b9 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/RxCocoa.xcscheme +++ b/Pods/Pods.xcodeproj/xcuserdata/ronick.xcuserdatad/xcschemes/RxCocoa.xcscheme @@ -1,6 +1,6 @@ orderHint 1 - Pods-Bunjang.xcscheme + Pods-GenderList.xcscheme isShown diff --git a/Pods/Target Support Files/Alamofire/Alamofire-Info.plist b/Pods/Target Support Files/Alamofire/Alamofire-Info.plist index fba50a6..ab3c8aa 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire-Info.plist +++ b/Pods/Target Support Files/Alamofire/Alamofire-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.0.5 + 5.5.0 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/Alamofire/Alamofire.debug.xcconfig b/Pods/Target Support Files/Alamofire/Alamofire.debug.xcconfig index 7d169c4..dbfd4d1 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire.debug.xcconfig +++ b/Pods/Target Support Files/Alamofire/Alamofire.debug.xcconfig @@ -1,11 +1,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Alamofire GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/Alamofire/Alamofire.release.xcconfig b/Pods/Target Support Files/Alamofire/Alamofire.release.xcconfig index 7d169c4..dbfd4d1 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire.release.xcconfig +++ b/Pods/Target Support Files/Alamofire/Alamofire.release.xcconfig @@ -1,11 +1,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Alamofire GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/Kingfisher/Kingfisher-Info.plist b/Pods/Target Support Files/Kingfisher/Kingfisher-Info.plist index e9068b0..d523b3a 100644 --- a/Pods/Target Support Files/Kingfisher/Kingfisher-Info.plist +++ b/Pods/Target Support Files/Kingfisher/Kingfisher-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig b/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig index 2dcd91e..33b15fb 100644 --- a/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig +++ b/Pods/Target Support Files/Kingfisher/Kingfisher.debug.xcconfig @@ -1,11 +1,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "CFNetwork" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig b/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig index 2dcd91e..33b15fb 100644 --- a/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig +++ b/Pods/Target Support Files/Kingfisher/Kingfisher.release.xcconfig @@ -1,11 +1,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "CFNetwork" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-dummy.m b/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-dummy.m deleted file mode 100644 index eac313a..0000000 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-dummy.m +++ /dev/null @@ -1,5 +0,0 @@ -#import -@interface PodsDummy_Pods_Bunjang : NSObject -@end -@implementation PodsDummy_Pods_Bunjang -@end diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.modulemap b/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.modulemap deleted file mode 100644 index 99572f6..0000000 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module Pods_Bunjang { - umbrella header "Pods-Bunjang-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-Info.plist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-Info.plist similarity index 94% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-Info.plist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-Info.plist index 2243fe6..19cf209 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-Info.plist +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.markdown b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.markdown similarity index 99% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.markdown rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.markdown index a804100..4bcca10 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.markdown @@ -3,7 +3,7 @@ This application makes use of the following third party libraries: ## Alamofire -Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) +Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.plist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.plist similarity index 99% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.plist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.plist index d17443a..cd9b294 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-acknowledgements.plist @@ -14,7 +14,7 @@ FooterText - Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) + Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-dummy.m b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-dummy.m new file mode 100644 index 0000000..6339964 --- /dev/null +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_GenderList : NSObject +@end +@implementation PodsDummy_Pods_GenderList +@end diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Debug-input-files.xcfilelist similarity index 78% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Debug-input-files.xcfilelist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Debug-input-files.xcfilelist index 2c1d106..7f7ccef 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Debug-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Debug-input-files.xcfilelist @@ -1,4 +1,4 @@ -${PODS_ROOT}/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh +${PODS_ROOT}/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework ${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Debug-output-files.xcfilelist similarity index 100% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Debug-output-files.xcfilelist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Debug-output-files.xcfilelist diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Release-input-files.xcfilelist similarity index 78% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Release-input-files.xcfilelist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Release-input-files.xcfilelist index 2c1d106..7f7ccef 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Release-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Release-input-files.xcfilelist @@ -1,4 +1,4 @@ -${PODS_ROOT}/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh +${PODS_ROOT}/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework ${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Release-output-files.xcfilelist similarity index 100% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks-Release-output-files.xcfilelist rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks-Release-output-files.xcfilelist diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh similarity index 98% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh index 9e93aa7..eab90e5 100755 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-frameworks.sh +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-frameworks.sh @@ -18,7 +18,7 @@ echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" -SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" BCSYMBOLMAP_DIR="BCSymbolMaps" @@ -41,7 +41,7 @@ install_framework() if [ -L "${source}" ]; then echo "Symlinked..." - source="$(readlink "${source}")" + source="$(readlink -f "${source}")" fi if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-umbrella.h b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-umbrella.h similarity index 61% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-umbrella.h rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList-umbrella.h index 828a7b3..7c73b1f 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang-umbrella.h +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList-umbrella.h @@ -11,6 +11,6 @@ #endif -FOUNDATION_EXPORT double Pods_BunjangVersionNumber; -FOUNDATION_EXPORT const unsigned char Pods_BunjangVersionString[]; +FOUNDATION_EXPORT double Pods_GenderListVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_GenderListVersionString[]; diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.debug.xcconfig b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.debug.xcconfig similarity index 94% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.debug.xcconfig rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList.debug.xcconfig index 5d6eedb..1b63661 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.debug.xcconfig +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.debug.xcconfig @@ -4,7 +4,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "Kingfisher" -framework "RxCocoa" -framework "RxRelay" -framework "RxSwift" -framework "SnapKit" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} diff --git a/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.modulemap b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.modulemap new file mode 100644 index 0000000..1d1f319 --- /dev/null +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.modulemap @@ -0,0 +1,6 @@ +framework module Pods_GenderList { + umbrella header "Pods-GenderList-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.release.xcconfig b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.release.xcconfig similarity index 94% rename from Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.release.xcconfig rename to Pods/Target Support Files/Pods-GenderList/Pods-GenderList.release.xcconfig index 5d6eedb..1b63661 100644 --- a/Pods/Target Support Files/Pods-Bunjang/Pods-Bunjang.release.xcconfig +++ b/Pods/Target Support Files/Pods-GenderList/Pods-GenderList.release.xcconfig @@ -4,7 +4,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa/RxCocoa.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay/RxRelay.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift/RxSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "Kingfisher" -framework "RxCocoa" -framework "RxRelay" -framework "RxSwift" -framework "SnapKit" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} diff --git a/Pods/Target Support Files/RxCocoa/RxCocoa-Info.plist b/Pods/Target Support Files/RxCocoa/RxCocoa-Info.plist index 891b375..ff0337d 100644 --- a/Pods/Target Support Files/RxCocoa/RxCocoa-Info.plist +++ b/Pods/Target Support Files/RxCocoa/RxCocoa-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/RxCocoa/RxCocoa.debug.xcconfig b/Pods/Target Support Files/RxCocoa/RxCocoa.debug.xcconfig index 493ddf9..55e3379 100644 --- a/Pods/Target Support Files/RxCocoa/RxCocoa.debug.xcconfig +++ b/Pods/Target Support Files/RxCocoa/RxCocoa.debug.xcconfig @@ -2,11 +2,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "RxRelay" -framework "RxSwift" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxCocoa PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/RxCocoa/RxCocoa.release.xcconfig b/Pods/Target Support Files/RxCocoa/RxCocoa.release.xcconfig index 493ddf9..55e3379 100644 --- a/Pods/Target Support Files/RxCocoa/RxCocoa.release.xcconfig +++ b/Pods/Target Support Files/RxCocoa/RxCocoa.release.xcconfig @@ -2,11 +2,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxCocoa FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RxRelay" "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "RxRelay" -framework "RxSwift" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxCocoa PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/RxRelay/RxRelay-Info.plist b/Pods/Target Support Files/RxRelay/RxRelay-Info.plist index 891b375..ff0337d 100644 --- a/Pods/Target Support Files/RxRelay/RxRelay-Info.plist +++ b/Pods/Target Support Files/RxRelay/RxRelay-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/RxRelay/RxRelay.debug.xcconfig b/Pods/Target Support Files/RxRelay/RxRelay.debug.xcconfig index f76af3e..e5b669d 100644 --- a/Pods/Target Support Files/RxRelay/RxRelay.debug.xcconfig +++ b/Pods/Target Support Files/RxRelay/RxRelay.debug.xcconfig @@ -2,11 +2,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxRelay FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "RxSwift" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxRelay PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/RxRelay/RxRelay.release.xcconfig b/Pods/Target Support Files/RxRelay/RxRelay.release.xcconfig index f76af3e..e5b669d 100644 --- a/Pods/Target Support Files/RxRelay/RxRelay.release.xcconfig +++ b/Pods/Target Support Files/RxRelay/RxRelay.release.xcconfig @@ -2,11 +2,12 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxRelay FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RxSwift" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "RxSwift" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxRelay PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/RxSwift/RxSwift-Info.plist b/Pods/Target Support Files/RxSwift/RxSwift-Info.plist index 891b375..ff0337d 100644 --- a/Pods/Target Support Files/RxSwift/RxSwift-Info.plist +++ b/Pods/Target Support Files/RxSwift/RxSwift-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/RxSwift/RxSwift.debug.xcconfig b/Pods/Target Support Files/RxSwift/RxSwift.debug.xcconfig index 6baebfc..d985331 100644 --- a/Pods/Target Support Files/RxSwift/RxSwift.debug.xcconfig +++ b/Pods/Target Support Files/RxSwift/RxSwift.debug.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxSwift GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxSwift PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/RxSwift/RxSwift.release.xcconfig b/Pods/Target Support Files/RxSwift/RxSwift.release.xcconfig index 6baebfc..d985331 100644 --- a/Pods/Target Support Files/RxSwift/RxSwift.release.xcconfig +++ b/Pods/Target Support Files/RxSwift/RxSwift.release.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RxSwift GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/RxSwift PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/SnapKit/SnapKit-Info.plist b/Pods/Target Support Files/SnapKit/SnapKit-Info.plist index 8d87a1a..8136e62 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit-Info.plist +++ b/Pods/Target Support Files/SnapKit/SnapKit-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig b/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig index 03fb3c1..3aab1a8 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig +++ b/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig b/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig index 03fb3c1..3aab1a8 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig +++ b/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/README.md b/README.md new file mode 100644 index 0000000..126679a --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# GenderList + + +

+simulator +

+ +#### open API: https://randomuser.me/documentation + +#### 구현사항 + +1. 현업에서 해왔던 기술들 기반으로 작업하였습니다 +2. open source 사용에 제한을 두지 않았습니다 +3. 남자/여자 탭을 구현하여 남자탭에는 남자리스트만, 여자탬에는 여자 리스트만 노출되도록 하였습니다. + - 남자/여자 탭은 예시일 뿐 탭 구성은 자유롭게(유동성있게) 만들었습니다. +4. 좌우 스와이프 기능을 구현하였습니다. +5. 탭 선택시 해당 리스트로 이동이 되도록 하였습니다. +6. 스크롤뷰를 당겨서 놓을 경우 새로고침이 되는 Pull to refresh 기능을 구현하였습니다. +7. 스크롤링시 자동으로 다음 리스트를 가져 올 수 있도록 하였습니다.(무한 스크롤링) +8. 에러 예외처리를 하였습니다. +9. 리스트중 하나 혹은 여러개를 선택하여 삭제할 수 있도록 하였습니다. +10. 사진 선택시 사진을 자세히 볼 수 있는 화면으로 이동해야 합니다. + - 사진은 2배까지 볼 수 있도록 확대 / 축소 기능이 있어야 합니다. +11. 리스트 구현시 1단형/2단형 (1열, 2열) 구성으로 전환할 수 있는 형태로 구현하였습니다. + - 1/2단 변경 버튼 클릭시 모든 탭의 화면에 영향을 주도록 하였습니다. +12. UI 구성에는 제한을 두지 않았습니다. + +#### 아키텍처 패턴: Clean Architecture +#### 디자인 패턴: MVVM, Input/Output +#### 라이브러리: SnapKit, RxSwift, RxCocoa, Alamofire(HTTP통신), Kingfisher(이미지캐싱) + +#### 레이어 구조 +``` +├── Application +│   ├── AppDelegate.swift +│   ├── AppFlowCoordinator.swift +│   ├── DIContainer +│   │   ├── AppDIContainer.swift +│   │   ├── GenderListDetailDIContainer.swift +│   │   └── GenderListSceneDIContainer.swift +│   └── SceneDelegate.swift +├── Data +│   ├── Network +│   │   ├── GenderListQuery.swift +│   │   └── GenderListResponseDTO+Mapping.swift +│   └── Repositories +│   └── DefaultGenderListRepository.swift +├── Domain +│   ├── Entities +│   │   └── GenderProfile.swift +│   ├── Interfaces +│   │   └── Repositories +│   │   └── GenderListRepository.swift +│   └── Usecases +│   └── GenderListUsecase.swift +├── Infrastructure +│   └── Network +│   └── NetworkService.swift +└── Presentation + ├── ListScene + │   ├── Flow + │   │   ├── GenderListDetailFlowCoordinator.swift + │   │   └── GenderListFlowCoordinator.swift + │   ├── ViewModels + │   │   ├── GenderProfileItemViewModel.swift + │   │   ├── InitialViewModel.swift + │   │   ├── ListPageViewModel.swift + │   │   ├── ListViewModel.swift + │   │   ├── OutputHelpers + │   │   │   └── ListViewOutputHelper.swift + │   │   ├── TabListViewModel.swift + │   │   └── TabViewModel.swift + │   └── Views + │   ├── Detail + │   │   ├── DetailView.swift + │   │   └── DetailViewController.swift + │   ├── GenderListViewController.swift + │   ├── List + │   │   ├── ListCollectionView.swift + │   │   ├── ListCollectionViewCell.swift + │   │   ├── PageCollectionView.swift + │   │   ├── PageCollectionViewCell.swift + │   │   └── TabPageView.swift + │   └── Tab + │   ├── TabCollectionView.swift + │   └── TabCollectionViewCell.swift + ├── Protocols + │   ├── Bindable.swift + │   ├── OutputProtocols + │   │   └── ListViewOutput.swift + │   ├── PagenationGenerator.swift + │   └── ViewModelType.swift + └── Utils + ├── ColumnStyle.swift + ├── DefaultPagenationGenerator.swift + ├── Extensions + │   ├── ListPageView+Rx.swift + │   ├── TabView+Rx.swift + │   ├── UICollectionView+Extension.swift + │   ├── UICollectionView+Rx.swift + │   └── UIView+Extension.swift + ├── FetchStatus.swift + └── GenderListFetchHelper.swift +```