├── Alamofire-Tutorial ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── Country.swift ├── Service.swift ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── ViewController.swift ├── Info.plist └── SceneDelegate.swift ├── Pods ├── Target Support Files │ ├── Pods-Alamofire-Tutorial │ │ ├── Pods-Alamofire-Tutorial-frameworks-Debug-output-files.xcfilelist │ │ ├── Pods-Alamofire-Tutorial-frameworks-Release-output-files.xcfilelist │ │ ├── Pods-Alamofire-Tutorial.modulemap │ │ ├── Pods-Alamofire-Tutorial-dummy.m │ │ ├── Pods-Alamofire-Tutorial-frameworks-Debug-input-files.xcfilelist │ │ ├── Pods-Alamofire-Tutorial-frameworks-Release-input-files.xcfilelist │ │ ├── Pods-Alamofire-Tutorial-umbrella.h │ │ ├── Pods-Alamofire-Tutorial.debug.xcconfig │ │ ├── Pods-Alamofire-Tutorial.release.xcconfig │ │ ├── Pods-Alamofire-Tutorial-Info.plist │ │ ├── Pods-Alamofire-Tutorial-acknowledgements.markdown │ │ ├── Pods-Alamofire-Tutorial-acknowledgements.plist │ │ └── Pods-Alamofire-Tutorial-frameworks.sh │ └── Alamofire │ │ ├── Alamofire.modulemap │ │ ├── Alamofire-dummy.m │ │ ├── Alamofire-prefix.pch │ │ ├── Alamofire-umbrella.h │ │ ├── Alamofire.xcconfig │ │ └── Alamofire-Info.plist ├── Manifest.lock ├── Pods.xcodeproj │ └── xcuserdata │ │ └── amanaggarwal.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ ├── Pods-Alamofire-Tutorial.xcscheme │ │ └── Alamofire.xcscheme └── Alamofire │ ├── LICENSE │ ├── Source │ ├── DispatchQueue+Alamofire.swift │ ├── URLRequest+Alamofire.swift │ ├── URLSessionConfiguration+Alamofire.swift │ ├── AlamofireExtended.swift │ ├── HTTPMethod.swift │ ├── OperationQueue+Alamofire.swift │ ├── MultipartUpload.swift │ ├── CachedResponseHandler.swift │ ├── URLConvertible+URLRequestConvertible.swift │ ├── RedirectHandler.swift │ ├── Result+Alamofire.swift │ ├── Protector.swift │ ├── RequestTaskMap.swift │ ├── Notifications.swift │ ├── ParameterEncoder.swift │ ├── RequestInterceptor.swift │ ├── Validation.swift │ ├── NetworkReachabilityManager.swift │ ├── ParameterEncoding.swift │ ├── SessionDelegate.swift │ └── HTTPHeaders.swift │ └── README.md ├── Alamofire-Tutorial.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── amanaggarwal.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── Alamofire-Tutorial.xcworkspace ├── xcuserdata │ └── amanaggarwal.xcuserdatad │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── Podfile └── Podfile.lock /Alamofire-Tutorial/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire.modulemap: -------------------------------------------------------------------------------- 1 | framework module Alamofire { 2 | umbrella header "Alamofire-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Alamofire : NSObject 3 | @end 4 | @implementation PodsDummy_Alamofire 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Alamofire_Tutorial { 2 | umbrella header "Pods-Alamofire-Tutorial-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Alamofire_Tutorial : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Alamofire_Tutorial 5 | @end 6 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcworkspace/xcuserdata/amanaggarwal.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Alamofire-Tutorial' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for Alamofire-Tutorial 9 | pod 'Alamofire', '~> 5.0.0-rc.3' 10 | end 11 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (5.0.0-rc.3) 3 | 4 | DEPENDENCIES: 5 | - Alamofire (~> 5.0.0-rc.3) 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - Alamofire 10 | 11 | SPEC CHECKSUMS: 12 | Alamofire: ca8c0de6906873be89d6deec5c8de279e00bf872 13 | 14 | PODFILE CHECKSUM: 3368e29d7690ccaab5dcd156211b720e2c101556 15 | 16 | COCOAPODS: 1.7.5 17 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Alamofire (5.0.0-rc.3) 3 | 4 | DEPENDENCIES: 5 | - Alamofire (~> 5.0.0-rc.3) 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - Alamofire 10 | 11 | SPEC CHECKSUMS: 12 | Alamofire: ca8c0de6906873be89d6deec5c8de279e00bf872 13 | 14 | PODFILE CHECKSUM: 3368e29d7690ccaab5dcd156211b720e2c101556 15 | 16 | COCOAPODS: 1.7.5 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double AlamofireVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char AlamofireVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Alamofire_TutorialVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Alamofire_TutorialVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcodeproj/xcuserdata/amanaggarwal.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Alamofire-Tutorial.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/Country.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Country.swift 3 | // Alamofire-Tutorial 4 | // 5 | // Created by Aman Aggarwal on 28/01/20. 6 | // Copyright © 2020 Aman Aggarwal. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Country: Decodable { 12 | var name: String? 13 | var capital: String? 14 | var countryCode:String? 15 | 16 | enum CodingKeys: String, CodingKey { 17 | case name = "name" 18 | case capital = "capital" 19 | case countryCode = "alpha3Code" 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Alamofire 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/amanaggarwal.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Alamofire.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | Pods-Alamofire-Tutorial.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | 22 | SuppressBuildableAutocreation 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Alamofire/Alamofire-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 5.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Alamofire/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Alamofire 5 | 6 | Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/Service.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Service.swift 3 | // Alamofire-Tutorial 4 | // 5 | // Created by Aman Aggarwal on 28/01/20. 6 | // Copyright © 2020 Aman Aggarwal. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | class Service { 13 | //https://restcountries.eu/rest/v2 14 | fileprivate var baseUrl = "" 15 | typealias countriesCallBack = (_ countries:[Country]?, _ status: Bool, _ message:String) -> Void 16 | 17 | var callBack:countriesCallBack? 18 | 19 | init(baseUrl: String) { 20 | self.baseUrl = baseUrl 21 | } 22 | 23 | //MARK:- getAllCountryNameFrom 24 | func getAllCountryNameFrom(endPoint:String) { 25 | AF.request(self.baseUrl + endPoint, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).response { (responseData) in 26 | guard let data = responseData.data else { 27 | self.callBack?(nil, false, "") 28 | 29 | return} 30 | do { 31 | let countries = try JSONDecoder().decode([Country].self, from: data) 32 | self.callBack?(countries, true,"") 33 | } catch { 34 | self.callBack?(nil, false, error.localizedDescription) 35 | } 36 | 37 | } 38 | } 39 | 40 | func completionHandler(callBack: @escaping countriesCallBack) { 41 | self.callBack = callBack 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Alamofire-Tutorial 4 | // 5 | // Created by Aman Aggarwal on 28/01/20. 6 | // Copyright © 2020 Aman Aggarwal. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | // MARK: UISceneSession Lifecycle 22 | 23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | // Called when a new scene session is being created. 25 | // Use this method to select a configuration to create the new scene with. 26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 27 | } 28 | 29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 30 | // Called when the user discards a scene session. 31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 33 | } 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/DispatchQueue+Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DispatchQueue+Alamofire.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Dispatch 26 | import Foundation 27 | 28 | extension DispatchQueue { 29 | /// Execute the provided closure after a `TimeInterval`. 30 | /// 31 | /// - Parameters: 32 | /// - delay: `TimeInterval` to delay execution. 33 | /// - closure: Closure to execute. 34 | func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) { 35 | asyncAfter(deadline: .now() + delay, execute: closure) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/URLRequest+Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URLRequest+Alamofire.swift 3 | // 4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | public extension URLRequest { 28 | /// Returns the `httpMethod` as Alamofire's `HTTPMethod` type. 29 | var method: HTTPMethod? { 30 | get { return httpMethod.flatMap(HTTPMethod.init) } 31 | set { httpMethod = newValue?.rawValue } 32 | } 33 | 34 | func validate() throws { 35 | if method == .get, let bodyData = httpBody { 36 | throw AFError.urlRequestValidationFailed(reason: .bodyDataInGETRequest(bodyData)) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Alamofire-Tutorial 4 | // 5 | // Created by Aman Aggarwal on 28/01/20. 6 | // Copyright © 2020 Aman Aggarwal. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak var tblCountries: UITableView! 14 | var countries = [Country]() 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | // Do any additional setup after loading the view. 19 | 20 | tblCountries.dataSource = self 21 | 22 | let service = Service(baseUrl: "https://restcountries.eu/rest/v2/") 23 | service.getAllCountryNameFrom(endPoint: "all") 24 | service.completionHandler { [weak self] (countries, status, message) in 25 | if status { 26 | guard let self = self else {return} 27 | guard let _countries = countries else {return} 28 | self.countries = _countries 29 | self.tblCountries.reloadData() 30 | } 31 | } 32 | } 33 | 34 | 35 | } 36 | 37 | 38 | extension ViewController : UITableViewDataSource { 39 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 40 | return countries.count 41 | } 42 | 43 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 44 | var cell = tableView.dequeueReusableCell(withIdentifier: "countrycell") 45 | if cell == nil { 46 | cell = UITableViewCell(style: .subtitle, reuseIdentifier: "countrycell") 47 | } 48 | 49 | let country = countries[indexPath.row] 50 | 51 | cell?.textLabel?.text = (country.name ?? "") + " " + (country.countryCode ?? "") 52 | cell?.detailTextLabel?.text = country.capital ?? "" 53 | return cell! 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URLSessionConfiguration+Alamofire.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension URLSessionConfiguration: AlamofireExtended {} 28 | extension AlamofireExtension where ExtendedType: URLSessionConfiguration { 29 | /// Alamofire's default configuration. Same as `URLSessionConfiguration.default` but adds Alamofire default 30 | /// `Accept-Language`, `Accept-Encoding`, and `User-Agent` headers. 31 | public static var `default`: URLSessionConfiguration { 32 | let configuration = URLSessionConfiguration.default 33 | configuration.headers = .default 34 | 35 | return configuration 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Alamofire-Tutorial/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/amanaggarwal.xcuserdatad/xcschemes/Pods-Alamofire-Tutorial.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/amanaggarwal.xcuserdatad/xcschemes/Alamofire.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | Alamofire 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/AlamofireExtended.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlamofireExtended.swift 3 | // 4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /// Type that acts as a generic extension point for all `AlamofireExtended` types. 26 | public struct AlamofireExtension { 27 | /// Stores the type or metatype of any extended type. 28 | let type: ExtendedType 29 | 30 | init(_ type: ExtendedType) { 31 | self.type = type 32 | } 33 | } 34 | 35 | /// Protocol describing the `af` extension points for Alamofire extended types. 36 | public protocol AlamofireExtended { 37 | /// Type being extended. 38 | associatedtype ExtendedType 39 | 40 | /// Static Alamofire extension point. 41 | static var af: AlamofireExtension.Type { get set } 42 | /// Instance Alamofire extension point. 43 | var af: AlamofireExtension { get set } 44 | } 45 | 46 | public extension AlamofireExtended { 47 | /// Static Alamofire extension point. 48 | static var af: AlamofireExtension.Type { 49 | get { return AlamofireExtension.self } 50 | set {} 51 | } 52 | 53 | /// Instance Alamofire extension point. 54 | var af: AlamofireExtension { 55 | get { return AlamofireExtension(self) } 56 | set {} 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/HTTPMethod.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HTTPMethod.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | /// Type representing HTTP methods. Raw `String` value is stored and compared case-sensitively, so 26 | /// `HTTPMethod.get != HTTPMethod(rawValue: "get")`. 27 | /// 28 | /// See https://tools.ietf.org/html/rfc7231#section-4.3 29 | public struct HTTPMethod: RawRepresentable, Equatable, Hashable { 30 | /// `CONNECT` method. 31 | public static let connect = HTTPMethod(rawValue: "CONNECT") 32 | /// `DELETE` method. 33 | public static let delete = HTTPMethod(rawValue: "DELETE") 34 | /// `GET` method. 35 | public static let get = HTTPMethod(rawValue: "GET") 36 | /// `HEAD` method. 37 | public static let head = HTTPMethod(rawValue: "HEAD") 38 | /// `OPTIONS` method. 39 | public static let options = HTTPMethod(rawValue: "OPTIONS") 40 | /// `PATCH` method. 41 | public static let patch = HTTPMethod(rawValue: "PATCH") 42 | /// `POST` method. 43 | public static let post = HTTPMethod(rawValue: "POST") 44 | /// `PUT` method. 45 | public static let put = HTTPMethod(rawValue: "PUT") 46 | /// `TRACE` method. 47 | public static let trace = HTTPMethod(rawValue: "TRACE") 48 | 49 | public let rawValue: String 50 | 51 | public init(rawValue: String) { 52 | self.rawValue = rawValue 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Alamofire-Tutorial 4 | // 5 | // Created by Aman Aggarwal on 28/01/20. 6 | // Copyright © 2020 Aman Aggarwal. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | } 34 | 35 | func sceneWillResignActive(_ scene: UIScene) { 36 | // Called when the scene will move from an active state to an inactive state. 37 | // This may occur due to temporary interruptions (ex. an incoming phone call). 38 | } 39 | 40 | func sceneWillEnterForeground(_ scene: UIScene) { 41 | // Called as the scene transitions from the background to the foreground. 42 | // Use this method to undo the changes made on entering the background. 43 | } 44 | 45 | func sceneDidEnterBackground(_ scene: UIScene) { 46 | // Called as the scene transitions from the foreground to the background. 47 | // Use this method to save data, release shared resources, and store enough scene-specific state information 48 | // to restore the scene back to its current state. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/OperationQueue+Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OperationQueue+Alamofire.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension OperationQueue { 28 | /// Creates an instance using the provided parameters. 29 | /// 30 | /// - Parameters: 31 | /// - qualityOfService: `QualityOfService` to be applied to the queue. `.default` by default. 32 | /// - maxConcurrentOperationCount: Maximum concurrent operations. 33 | /// `OperationQueue.defaultMaxConcurrentOperationCount` by default. 34 | /// - underlyingQueue: Underlying `DispatchQueue`. `nil` by default. 35 | /// - name: Name for the queue. `nil` by default. 36 | /// - startSuspended: Whether the queue starts suspended. `false` by default. 37 | convenience init(qualityOfService: QualityOfService = .default, 38 | maxConcurrentOperationCount: Int = OperationQueue.defaultMaxConcurrentOperationCount, 39 | underlyingQueue: DispatchQueue? = nil, 40 | name: String? = nil, 41 | startSuspended: Bool = false) { 42 | self.init() 43 | self.qualityOfService = qualityOfService 44 | self.maxConcurrentOperationCount = maxConcurrentOperationCount 45 | self.underlyingQueue = underlyingQueue 46 | self.name = name 47 | isSuspended = startSuspended 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Alamofire-Tutorial/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/MultipartUpload.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultipartUpload.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Internal type which encapsulates a `MultipartFormData` upload. 28 | final class MultipartUpload { 29 | lazy var result = Result { try build() } 30 | 31 | let isInBackgroundSession: Bool 32 | let multipartFormData: MultipartFormData 33 | let encodingMemoryThreshold: UInt64 34 | let request: URLRequestConvertible 35 | let fileManager: FileManager 36 | 37 | init(isInBackgroundSession: Bool, 38 | encodingMemoryThreshold: UInt64, 39 | request: URLRequestConvertible, 40 | multipartFormData: MultipartFormData) { 41 | self.isInBackgroundSession = isInBackgroundSession 42 | self.encodingMemoryThreshold = encodingMemoryThreshold 43 | self.request = request 44 | fileManager = multipartFormData.fileManager 45 | self.multipartFormData = multipartFormData 46 | } 47 | 48 | func build() throws -> (request: URLRequest, uploadable: UploadRequest.Uploadable) { 49 | var urlRequest = try request.asURLRequest() 50 | urlRequest.setValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") 51 | 52 | let uploadable: UploadRequest.Uploadable 53 | if multipartFormData.contentLength < encodingMemoryThreshold && !isInBackgroundSession { 54 | let data = try multipartFormData.encode() 55 | 56 | uploadable = .data(data) 57 | } else { 58 | let tempDirectoryURL = fileManager.temporaryDirectory 59 | let directoryURL = tempDirectoryURL.appendingPathComponent("org.alamofire.manager/multipart.form.data") 60 | let fileName = UUID().uuidString 61 | let fileURL = directoryURL.appendingPathComponent(fileName) 62 | 63 | try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil) 64 | 65 | do { 66 | try multipartFormData.writeEncodedData(to: fileURL) 67 | } catch { 68 | // Cleanup after attempted write if it fails. 69 | try? fileManager.removeItem(at: fileURL) 70 | } 71 | 72 | uploadable = .file(fileURL, shouldRemove: true) 73 | } 74 | 75 | return (request: urlRequest, uploadable: uploadable) 76 | } 77 | } 78 | 79 | extension MultipartUpload: UploadConvertible { 80 | func asURLRequest() throws -> URLRequest { 81 | return try result.get().request 82 | } 83 | 84 | func createUploadable() throws -> UploadRequest.Uploadable { 85 | return try result.get().uploadable 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/CachedResponseHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CachedResponseHandler.swift 3 | // 4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A type that handles whether the data task should store the HTTP response in the cache. 28 | public protocol CachedResponseHandler { 29 | /// Determines whether the HTTP response should be stored in the cache. 30 | /// 31 | /// The `completion` closure should be passed one of three possible options: 32 | /// 33 | /// 1. The cached response provided by the server (this is the most common use case). 34 | /// 2. A modified version of the cached response (you may want to modify it in some way before caching). 35 | /// 3. A `nil` value to prevent the cached response from being stored in the cache. 36 | /// 37 | /// - Parameters: 38 | /// - task: The data task whose request resulted in the cached response. 39 | /// - response: The cached response to potentially store in the cache. 40 | /// - completion: The closure to execute containing cached response, a modified response, or `nil`. 41 | func dataTask(_ task: URLSessionDataTask, 42 | willCacheResponse response: CachedURLResponse, 43 | completion: @escaping (CachedURLResponse?) -> Void) 44 | } 45 | 46 | // MARK: - 47 | 48 | /// `ResponseCacher` is a convenience `CachedResponseHandler` making it easy to cache, not cache, or modify a cached 49 | /// response. 50 | public struct ResponseCacher { 51 | /// Defines the behavior of the `ResponseCacher` type. 52 | public enum Behavior { 53 | /// Stores the cached response in the cache. 54 | case cache 55 | /// Prevents the cached response from being stored in the cache. 56 | case doNotCache 57 | /// Modifies the cached response before storing it in the cache. 58 | case modify((URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?) 59 | } 60 | 61 | /// Returns a `ResponseCacher` with a follow `Behavior`. 62 | public static let cache = ResponseCacher(behavior: .cache) 63 | /// Returns a `ResponseCacher` with a do not follow `Behavior`. 64 | public static let doNotCache = ResponseCacher(behavior: .doNotCache) 65 | 66 | /// The `Behavior` of the `ResponseCacher`. 67 | public let behavior: Behavior 68 | 69 | /// Creates a `ResponseCacher` instance from the `Behavior`. 70 | /// 71 | /// - Parameter behavior: The `Behavior`. 72 | public init(behavior: Behavior) { 73 | self.behavior = behavior 74 | } 75 | } 76 | 77 | extension ResponseCacher: CachedResponseHandler { 78 | public func dataTask(_ task: URLSessionDataTask, 79 | willCacheResponse response: CachedURLResponse, 80 | completion: @escaping (CachedURLResponse?) -> Void) { 81 | switch behavior { 82 | case .cache: 83 | completion(response) 84 | case .doNotCache: 85 | completion(nil) 86 | case let .modify(closure): 87 | let response = closure(task, response) 88 | completion(response) 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URLConvertible+URLRequestConvertible.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Types adopting the `URLConvertible` protocol can be used to construct `URL`s, which can then be used to construct 28 | /// `URLRequests`. 29 | public protocol URLConvertible { 30 | /// Returns a `URL` from the conforming instance or throws. 31 | /// 32 | /// - Returns: The `URL` created from the instance. 33 | /// - Throws: Any error thrown while creating the `URL`. 34 | func asURL() throws -> URL 35 | } 36 | 37 | extension String: URLConvertible { 38 | /// Returns a `URL` if `self` can be used to initialize a `URL` instance, otherwise throws. 39 | /// 40 | /// - Returns: The `URL` initialized with `self`. 41 | /// - Throws: An `AFError.invalidURL` instance. 42 | public func asURL() throws -> URL { 43 | guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) } 44 | 45 | return url 46 | } 47 | } 48 | 49 | extension URL: URLConvertible { 50 | /// Returns `self`. 51 | public func asURL() throws -> URL { return self } 52 | } 53 | 54 | extension URLComponents: URLConvertible { 55 | /// Returns a `URL` if the `self`'s `url` is not nil, otherwise throws. 56 | /// 57 | /// - Returns: The `URL` from the `url` property. 58 | /// - Throws: An `AFError.invalidURL` instance. 59 | public func asURL() throws -> URL { 60 | guard let url = url else { throw AFError.invalidURL(url: self) } 61 | 62 | return url 63 | } 64 | } 65 | 66 | // MARK: - 67 | 68 | /// Types adopting the `URLRequestConvertible` protocol can be used to safely construct `URLRequest`s. 69 | public protocol URLRequestConvertible { 70 | /// Returns a `URLRequest` or throws if an `Error` was encountered. 71 | /// 72 | /// - Returns: A `URLRequest`. 73 | /// - Throws: Any error thrown while constructing the `URLRequest`. 74 | func asURLRequest() throws -> URLRequest 75 | } 76 | 77 | extension URLRequestConvertible { 78 | /// The `URLRequest` returned by discarding any `Error` encountered. 79 | public var urlRequest: URLRequest? { return try? asURLRequest() } 80 | } 81 | 82 | extension URLRequest: URLRequestConvertible { 83 | /// Returns `self`. 84 | public func asURLRequest() throws -> URLRequest { return self } 85 | } 86 | 87 | // MARK: - 88 | 89 | extension URLRequest { 90 | /// Creates an instance with the specified `url`, `method`, and `headers`. 91 | /// 92 | /// - Parameters: 93 | /// - url: The `URLConvertible` value. 94 | /// - method: The `HTTPMethod`. 95 | /// - headers: The `HTTPHeaders`, `nil` by default. 96 | /// - Throws: Any error thrown while converting the `URLConvertible` to a `URL`. 97 | public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws { 98 | let url = try url.asURL() 99 | 100 | self.init(url: url) 101 | 102 | httpMethod = method.rawValue 103 | allHTTPHeaderFields = headers?.dictionary 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/RedirectHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RedirectHandler.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A type that handles how an HTTP redirect response from a remote server should be redirected to the new request. 28 | public protocol RedirectHandler { 29 | /// Determines how the HTTP redirect response should be redirected to the new request. 30 | /// 31 | /// The `completion` closure should be passed one of three possible options: 32 | /// 33 | /// 1. The new request specified by the redirect (this is the most common use case). 34 | /// 2. A modified version of the new request (you may want to route it somewhere else). 35 | /// 3. A `nil` value to deny the redirect request and return the body of the redirect response. 36 | /// 37 | /// - Parameters: 38 | /// - task: The task whose request resulted in a redirect. 39 | /// - request: The URL request object to the new location specified by the redirect response. 40 | /// - response: The response containing the server's response to the original request. 41 | /// - completion: The closure to execute containing the new request, a modified request, or `nil`. 42 | func task(_ task: URLSessionTask, 43 | willBeRedirectedTo request: URLRequest, 44 | for response: HTTPURLResponse, 45 | completion: @escaping (URLRequest?) -> Void) 46 | } 47 | 48 | // MARK: - 49 | 50 | /// `Redirector` is a convenience `RedirectHandler` making it easy to follow, not follow, or modify a redirect. 51 | public struct Redirector { 52 | /// Defines the behavior of the `Redirector` type. 53 | public enum Behavior { 54 | /// Follow the redirect as defined in the response. 55 | case follow 56 | /// Do not follow the redirect defined in the response. 57 | case doNotFollow 58 | /// Modify the redirect request defined in the response. 59 | case modify((URLSessionTask, URLRequest, HTTPURLResponse) -> URLRequest?) 60 | } 61 | 62 | /// Returns a `Redirector` with a `.follow` `Behavior`. 63 | public static let follow = Redirector(behavior: .follow) 64 | /// Returns a `Redirector` with a `.doNotFollow` `Behavior`. 65 | public static let doNotFollow = Redirector(behavior: .doNotFollow) 66 | 67 | /// The `Behavior` of the `Redirector`. 68 | public let behavior: Behavior 69 | 70 | /// Creates a `Redirector` instance from the `Behavior`. 71 | /// 72 | /// - Parameter behavior: The `Behavior`. 73 | public init(behavior: Behavior) { 74 | self.behavior = behavior 75 | } 76 | } 77 | 78 | // MARK: - 79 | 80 | extension Redirector: RedirectHandler { 81 | public func task(_ task: URLSessionTask, 82 | willBeRedirectedTo request: URLRequest, 83 | for response: HTTPURLResponse, 84 | completion: @escaping (URLRequest?) -> Void) { 85 | switch behavior { 86 | case .follow: 87 | completion(request) 88 | case .doNotFollow: 89 | completion(nil) 90 | case let .modify(closure): 91 | let request = closure(task, request, response) 92 | completion(request) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Result+Alamofire.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Result+Alamofire.swift 3 | // 4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Default type of `Result` returned by Alamofire, with an `AFError` `Failure` type. 28 | public typealias AFResult = Result 29 | 30 | // MARK: - Internal APIs 31 | 32 | extension Result { 33 | /// Returns the associated value if the result is a success, `nil` otherwise. 34 | var success: Success? { 35 | guard case let .success(value) = self else { return nil } 36 | return value 37 | } 38 | 39 | /// Returns the associated error value if the result is a failure, `nil` otherwise. 40 | var failure: Failure? { 41 | guard case let .failure(error) = self else { return nil } 42 | return error 43 | } 44 | 45 | /// Initializes a `Result` from value or error. Returns `.failure` if the error is non-nil, `.success` otherwise. 46 | /// 47 | /// - Parameters: 48 | /// - value: A value. 49 | /// - error: An `Error`. 50 | init(value: Success, error: Failure?) { 51 | if let error = error { 52 | self = .failure(error) 53 | } else { 54 | self = .success(value) 55 | } 56 | } 57 | 58 | /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter. 59 | /// 60 | /// Use the `tryMap` method with a closure that may throw an error. For example: 61 | /// 62 | /// let possibleData: Result = .success(Data(...)) 63 | /// let possibleObject = possibleData.tryMap { 64 | /// try JSONSerialization.jsonObject(with: $0) 65 | /// } 66 | /// 67 | /// - parameter transform: A closure that takes the success value of the instance. 68 | /// 69 | /// - returns: A `Result` containing the result of the given closure. If this instance is a failure, returns the 70 | /// same failure. 71 | func tryMap(_ transform: (Success) throws -> NewSuccess) -> Result { 72 | switch self { 73 | case let .success(value): 74 | do { 75 | return try .success(transform(value)) 76 | } catch { 77 | return .failure(error) 78 | } 79 | case let .failure(error): 80 | return .failure(error) 81 | } 82 | } 83 | 84 | /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter. 85 | /// 86 | /// Use the `tryMapError` function with a closure that may throw an error. For example: 87 | /// 88 | /// let possibleData: Result = .success(Data(...)) 89 | /// let possibleObject = possibleData.tryMapError { 90 | /// try someFailableFunction(taking: $0) 91 | /// } 92 | /// 93 | /// - Parameter transform: A throwing closure that takes the error of the instance. 94 | /// 95 | /// - Returns: A `Result` instance containing the result of the transform. If this instance is a success, returns 96 | /// the same success. 97 | func tryMapError(_ transform: (Failure) throws -> NewFailure) -> Result { 98 | switch self { 99 | case let .failure(error): 100 | do { 101 | return try .failure(transform(error)) 102 | } catch { 103 | return .failure(error) 104 | } 105 | case let .success(value): 106 | return .success(value) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Protector.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Protector.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | // MARK: - 28 | 29 | /// An `os_unfair_lock` wrapper. 30 | final class UnfairLock { 31 | private let unfairLock: os_unfair_lock_t 32 | 33 | init() { 34 | unfairLock = .allocate(capacity: 1) 35 | unfairLock.initialize(to: os_unfair_lock()) 36 | } 37 | 38 | deinit { 39 | unfairLock.deinitialize(count: 1) 40 | unfairLock.deallocate() 41 | } 42 | 43 | private func lock() { 44 | os_unfair_lock_lock(unfairLock) 45 | } 46 | 47 | private func unlock() { 48 | os_unfair_lock_unlock(unfairLock) 49 | } 50 | 51 | /// Executes a closure returning a value while acquiring the lock. 52 | /// 53 | /// - Parameter closure: The closure to run. 54 | /// 55 | /// - Returns: The value the closure generated. 56 | func around(_ closure: () -> T) -> T { 57 | lock(); defer { unlock() } 58 | return closure() 59 | } 60 | 61 | /// Execute a closure while acquiring the lock. 62 | /// 63 | /// - Parameter closure: The closure to run. 64 | func around(_ closure: () -> Void) { 65 | lock(); defer { unlock() } 66 | return closure() 67 | } 68 | } 69 | 70 | /// A thread-safe wrapper around a value. 71 | final class Protector { 72 | private let lock = UnfairLock() 73 | private var value: T 74 | 75 | init(_ value: T) { 76 | self.value = value 77 | } 78 | 79 | /// The contained value. Unsafe for anything more than direct read or write. 80 | var directValue: T { 81 | get { return lock.around { value } } 82 | set { lock.around { value = newValue } } 83 | } 84 | 85 | /// Synchronously read or transform the contained value. 86 | /// 87 | /// - Parameter closure: The closure to execute. 88 | /// 89 | /// - Returns: The return value of the closure passed. 90 | func read(_ closure: (T) -> U) -> U { 91 | return lock.around { closure(self.value) } 92 | } 93 | 94 | /// Synchronously modify the protected value. 95 | /// 96 | /// - Parameter closure: The closure to execute. 97 | /// 98 | /// - Returns: The modified value. 99 | @discardableResult 100 | func write(_ closure: (inout T) -> U) -> U { 101 | return lock.around { closure(&self.value) } 102 | } 103 | } 104 | 105 | extension Protector where T: RangeReplaceableCollection { 106 | /// Adds a new element to the end of this protected collection. 107 | /// 108 | /// - Parameter newElement: The `Element` to append. 109 | func append(_ newElement: T.Element) { 110 | write { (ward: inout T) in 111 | ward.append(newElement) 112 | } 113 | } 114 | 115 | /// Adds the elements of a sequence to the end of this protected collection. 116 | /// 117 | /// - Parameter newElements: The `Sequence` to append. 118 | func append(contentsOf newElements: S) where S.Element == T.Element { 119 | write { (ward: inout T) in 120 | ward.append(contentsOf: newElements) 121 | } 122 | } 123 | 124 | /// Add the elements of a collection to the end of the protected collection. 125 | /// 126 | /// - Parameter newElements: The `Collection` to append. 127 | func append(contentsOf newElements: C) where C.Element == T.Element { 128 | write { (ward: inout T) in 129 | ward.append(contentsOf: newElements) 130 | } 131 | } 132 | } 133 | 134 | extension Protector where T == Data? { 135 | /// Adds the contents of a `Data` value to the end of the protected `Data`. 136 | /// 137 | /// - Parameter data: The `Data` to be appended. 138 | func append(_ data: Data) { 139 | write { (ward: inout T) in 140 | ward?.append(data) 141 | } 142 | } 143 | } 144 | 145 | extension Protector where T == Request.MutableState { 146 | /// Attempts to transition to the passed `State`. 147 | /// 148 | /// - Parameter state: The `State` to attempt transition to. 149 | /// 150 | /// - Returns: Whether the transition occurred. 151 | func attemptToTransitionTo(_ state: Request.State) -> Bool { 152 | return lock.around { 153 | guard value.state.canTransitionTo(state) else { return false } 154 | 155 | value.state = state 156 | 157 | return true 158 | } 159 | } 160 | 161 | /// Perform a closure while locked with the provided `Request.State`. 162 | /// 163 | /// - Parameter perform: The closure to perform while locked. 164 | func withState(perform: (Request.State) -> Void) { 165 | lock.around { perform(value.state) } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/RequestTaskMap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RequestTaskMap.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A type that maintains a two way, one to one map of `URLSessionTask`s to `Request`s. 28 | struct RequestTaskMap { 29 | private var tasksToRequests: [URLSessionTask: Request] 30 | private var requestsToTasks: [Request: URLSessionTask] 31 | private var taskEvents: [URLSessionTask: (completed: Bool, metricsGathered: Bool)] 32 | 33 | var requests: [Request] { 34 | return Array(tasksToRequests.values) 35 | } 36 | 37 | init(tasksToRequests: [URLSessionTask: Request] = [:], 38 | requestsToTasks: [Request: URLSessionTask] = [:], 39 | taskEvents: [URLSessionTask: (completed: Bool, metricsGathered: Bool)] = [:]) { 40 | self.tasksToRequests = tasksToRequests 41 | self.requestsToTasks = requestsToTasks 42 | self.taskEvents = taskEvents 43 | } 44 | 45 | subscript(_ request: Request) -> URLSessionTask? { 46 | get { return requestsToTasks[request] } 47 | set { 48 | guard let newValue = newValue else { 49 | guard let task = requestsToTasks[request] else { 50 | fatalError("RequestTaskMap consistency error: no task corresponding to request found.") 51 | } 52 | 53 | requestsToTasks.removeValue(forKey: request) 54 | tasksToRequests.removeValue(forKey: task) 55 | taskEvents.removeValue(forKey: task) 56 | 57 | return 58 | } 59 | 60 | requestsToTasks[request] = newValue 61 | tasksToRequests[newValue] = request 62 | taskEvents[newValue] = (completed: false, metricsGathered: false) 63 | } 64 | } 65 | 66 | subscript(_ task: URLSessionTask) -> Request? { 67 | get { return tasksToRequests[task] } 68 | set { 69 | guard let newValue = newValue else { 70 | guard let request = tasksToRequests[task] else { 71 | fatalError("RequestTaskMap consistency error: no request corresponding to task found.") 72 | } 73 | 74 | tasksToRequests.removeValue(forKey: task) 75 | requestsToTasks.removeValue(forKey: request) 76 | taskEvents.removeValue(forKey: task) 77 | 78 | return 79 | } 80 | 81 | tasksToRequests[task] = newValue 82 | requestsToTasks[newValue] = task 83 | taskEvents[task] = (completed: false, metricsGathered: false) 84 | } 85 | } 86 | 87 | var count: Int { 88 | precondition(tasksToRequests.count == requestsToTasks.count, 89 | "RequestTaskMap.count invalid, requests.count: \(tasksToRequests.count) != tasks.count: \(requestsToTasks.count)") 90 | 91 | return tasksToRequests.count 92 | } 93 | 94 | var eventCount: Int { 95 | precondition(taskEvents.count == count, "RequestTaskMap.eventCount invalid, count: \(count) != taskEvents.count: \(taskEvents.count)") 96 | 97 | return taskEvents.count 98 | } 99 | 100 | var isEmpty: Bool { 101 | precondition(tasksToRequests.isEmpty == requestsToTasks.isEmpty, 102 | "RequestTaskMap.isEmpty invalid, requests.isEmpty: \(tasksToRequests.isEmpty) != tasks.isEmpty: \(requestsToTasks.isEmpty)") 103 | 104 | return tasksToRequests.isEmpty 105 | } 106 | 107 | var isEventsEmpty: Bool { 108 | precondition(taskEvents.isEmpty == isEmpty, "RequestTaskMap.isEventsEmpty invalid, isEmpty: \(isEmpty) != taskEvents.isEmpty: \(taskEvents.isEmpty)") 109 | 110 | return taskEvents.isEmpty 111 | } 112 | 113 | mutating func disassociateIfNecessaryAfterGatheringMetricsForTask(_ task: URLSessionTask) { 114 | guard let events = taskEvents[task] else { 115 | fatalError("RequestTaskMap consistency error: no events corresponding to task found.") 116 | } 117 | 118 | switch (events.completed, events.metricsGathered) { 119 | case (_, true): fatalError("RequestTaskMap consistency error: duplicate metricsGatheredForTask call.") 120 | case (false, false): taskEvents[task] = (completed: false, metricsGathered: true) 121 | case (true, false): self[task] = nil 122 | } 123 | } 124 | 125 | mutating func disassociateIfNecessaryAfterCompletingTask(_ task: URLSessionTask) { 126 | guard let events = taskEvents[task] else { 127 | fatalError("RequestTaskMap consistency error: no events corresponding to task found.") 128 | } 129 | 130 | switch (events.completed, events.metricsGathered) { 131 | case (true, _): fatalError("RequestTaskMap consistency error: duplicate completionReceivedForTask call.") 132 | case (false, false): taskEvents[task] = (completed: true, metricsGathered: false) 133 | case (false, true): self[task] = nil 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Notifications.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Notifications.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | public extension Request { 28 | /// Posted when a `Request` is resumed. The `Notification` contains the resumed `Request`. 29 | static let didResumeNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResume") 30 | /// Posted when a `Request` is suspended. The `Notification` contains the suspended `Request`. 31 | static let didSuspendNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspend") 32 | /// Posted when a `Request` is cancelled. The `Notification` contains the cancelled `Request`. 33 | static let didCancelNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancel") 34 | /// Posted when a `Request` is finished. The `Notification` contains the completed `Request`. 35 | static let didFinishNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didFinish") 36 | 37 | /// Posted when a `URLSessionTask` is resumed. The `Notification` contains the `Request` associated with the `URLSessionTask`. 38 | static let didResumeTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResumeTask") 39 | /// Posted when a `URLSessionTask` is suspended. The `Notification` contains the `Request` associated with the `URLSessionTask`. 40 | static let didSuspendTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspendTask") 41 | /// Posted when a `URLSessionTask` is cancelled. The `Notification` contains the `Request` associated with the `URLSessionTask`. 42 | static let didCancelTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancelTask") 43 | /// Posted when a `URLSessionTask` is completed. The `Notification` contains the `Request` associated with the `URLSessionTask`. 44 | static let didCompleteTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCompleteTask") 45 | } 46 | 47 | // MARK: - 48 | 49 | extension Notification { 50 | /// The `Request` contained by the instance's `userInfo`, `nil` otherwise. 51 | public var request: Request? { 52 | return userInfo?[String.requestKey] as? Request 53 | } 54 | 55 | /// Convenience initializer for a `Notification` containing a `Request` payload. 56 | /// 57 | /// - Parameters: 58 | /// - name: The name of the notification. 59 | /// - request: The `Request` payload. 60 | init(name: Notification.Name, request: Request) { 61 | self.init(name: name, object: nil, userInfo: [String.requestKey: request]) 62 | } 63 | } 64 | 65 | extension NotificationCenter { 66 | /// Convenience function for posting notifications with `Request` payloads. 67 | /// 68 | /// - Parameters: 69 | /// - name: The name of the notification. 70 | /// - request: The `Request` payload. 71 | func postNotification(named name: Notification.Name, with request: Request) { 72 | let notification = Notification(name: name, request: request) 73 | post(notification) 74 | } 75 | } 76 | 77 | extension String { 78 | /// User info dictionary key representing the `Request` associated with the notification. 79 | fileprivate static let requestKey = "org.alamofire.notification.key.request" 80 | } 81 | 82 | /// `EventMonitor` that provides Alamofire's notifications. 83 | public final class AlamofireNotifications: EventMonitor { 84 | public func requestDidResume(_ request: Request) { 85 | NotificationCenter.default.postNotification(named: Request.didResumeNotification, with: request) 86 | } 87 | 88 | public func requestDidSuspend(_ request: Request) { 89 | NotificationCenter.default.postNotification(named: Request.didSuspendNotification, with: request) 90 | } 91 | 92 | public func requestDidCancel(_ request: Request) { 93 | NotificationCenter.default.postNotification(named: Request.didCancelNotification, with: request) 94 | } 95 | 96 | public func requestDidFinish(_ request: Request) { 97 | NotificationCenter.default.postNotification(named: Request.didFinishNotification, with: request) 98 | } 99 | 100 | public func request(_ request: Request, didResumeTask task: URLSessionTask) { 101 | NotificationCenter.default.postNotification(named: Request.didResumeTaskNotification, with: request) 102 | } 103 | 104 | public func request(_ request: Request, didSuspendTask task: URLSessionTask) { 105 | NotificationCenter.default.postNotification(named: Request.didSuspendTaskNotification, with: request) 106 | } 107 | 108 | public func request(_ request: Request, didCancelTask task: URLSessionTask) { 109 | NotificationCenter.default.postNotification(named: Request.didCancelTaskNotification, with: request) 110 | } 111 | 112 | public func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) { 113 | NotificationCenter.default.postNotification(named: Request.didCompleteTaskNotification, with: request) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | if [ -r "$source" ]; then 88 | # Copy the dSYM into a the targets temp dir. 89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 91 | 92 | local basename 93 | basename="$(basename -s .framework.dSYM "$source")" 94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 95 | 96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 97 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 98 | strip_invalid_archs "$binary" 99 | fi 100 | 101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 102 | # Move the stripped file into its final destination. 103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 105 | else 106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 108 | fi 109 | fi 110 | } 111 | 112 | # Copies the bcsymbolmap files of a vendored framework 113 | install_bcsymbolmap() { 114 | local bcsymbolmap_path="$1" 115 | local destination="${BUILT_PRODUCTS_DIR}" 116 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 117 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 118 | } 119 | 120 | # Signs a framework with the provided identity 121 | code_sign_if_enabled() { 122 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 123 | # Use the current code_sign_identity 124 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 125 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 126 | 127 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 128 | code_sign_cmd="$code_sign_cmd &" 129 | fi 130 | echo "$code_sign_cmd" 131 | eval "$code_sign_cmd" 132 | fi 133 | } 134 | 135 | # Strip invalid architectures 136 | strip_invalid_archs() { 137 | binary="$1" 138 | # Get architectures for current target binary 139 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 140 | # Intersect them with the architectures we are building for 141 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 142 | # If there are no archs supported by this binary then warn the user 143 | if [[ -z "$intersected_archs" ]]; then 144 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 145 | STRIP_BINARY_RETVAL=0 146 | return 147 | fi 148 | stripped="" 149 | for arch in $binary_archs; do 150 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 151 | # Strip non-valid architectures in-place 152 | lipo -remove "$arch" -output "$binary" "$binary" 153 | stripped="$stripped $arch" 154 | fi 155 | done 156 | if [[ "$stripped" ]]; then 157 | echo "Stripped $binary of architectures:$stripped" 158 | fi 159 | STRIP_BINARY_RETVAL=1 160 | } 161 | 162 | 163 | if [[ "$CONFIGURATION" == "Debug" ]]; then 164 | install_framework "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework" 165 | fi 166 | if [[ "$CONFIGURATION" == "Release" ]]; then 167 | install_framework "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework" 168 | fi 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | wait 171 | fi 172 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/ParameterEncoder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ParameterEncoder.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A type that can encode any `Encodable` type into a `URLRequest`. 28 | public protocol ParameterEncoder { 29 | /// Encode the provided `Encodable` parameters into `request`. 30 | /// 31 | /// - Parameters: 32 | /// - parameters: The `Encodable` parameter value. 33 | /// - request: The `URLRequest` into which to encode the parameters. 34 | /// 35 | /// - Returns: A `URLRequest` with the result of the encoding. 36 | /// - Throws: An `Error` when encoding fails. For Alamofire provided encoders, this will be an instance of 37 | /// `AFError.parameterEncoderFailed` with an associated `ParameterEncoderFailureReason`. 38 | func encode(_ parameters: Parameters?, into request: URLRequest) throws -> URLRequest 39 | } 40 | 41 | /// A `ParameterEncoder` that encodes types as JSON body data. 42 | /// 43 | /// If no `Content-Type` header is already set on the provided `URLRequest`s, it's set to `application/json`. 44 | open class JSONParameterEncoder: ParameterEncoder { 45 | /// Returns an encoder with default parameters. 46 | public static var `default`: JSONParameterEncoder { return JSONParameterEncoder() } 47 | 48 | /// Returns an encoder with `JSONEncoder.outputFormatting` set to `.prettyPrinted`. 49 | public static var prettyPrinted: JSONParameterEncoder { 50 | let encoder = JSONEncoder() 51 | encoder.outputFormatting = .prettyPrinted 52 | 53 | return JSONParameterEncoder(encoder: encoder) 54 | } 55 | 56 | /// Returns an encoder with `JSONEncoder.outputFormatting` set to `.sortedKeys`. 57 | @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) 58 | public static var sortedKeys: JSONParameterEncoder { 59 | let encoder = JSONEncoder() 60 | encoder.outputFormatting = .sortedKeys 61 | 62 | return JSONParameterEncoder(encoder: encoder) 63 | } 64 | 65 | /// `JSONEncoder` used to encode parameters. 66 | public let encoder: JSONEncoder 67 | 68 | /// Creates an instance with the provided `JSONEncoder`. 69 | /// 70 | /// - Parameter encoder: The `JSONEncoder`. `JSONEncoder()` by default. 71 | public init(encoder: JSONEncoder = JSONEncoder()) { 72 | self.encoder = encoder 73 | } 74 | 75 | open func encode(_ parameters: Parameters?, 76 | into request: URLRequest) throws -> URLRequest { 77 | guard let parameters = parameters else { return request } 78 | 79 | var request = request 80 | 81 | do { 82 | let data = try encoder.encode(parameters) 83 | request.httpBody = data 84 | if request.headers["Content-Type"] == nil { 85 | request.headers.update(.contentType("application/json")) 86 | } 87 | } catch { 88 | throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) 89 | } 90 | 91 | return request 92 | } 93 | } 94 | 95 | /// A `ParameterEncoder` that encodes types as URL-encoded query strings to be set on the URL or as body data, depending 96 | /// on the `Destination` set. 97 | /// 98 | /// If no `Content-Type` header is already set on the provided `URLRequest`s, it will be set to 99 | /// `application/x-www-form-urlencoded; charset=utf-8`. 100 | /// 101 | /// Encoding behavior can be customized by passing an instance of `URLEncodedFormEncoder` to the initializer. 102 | open class URLEncodedFormParameterEncoder: ParameterEncoder { 103 | /// Defines where the URL-encoded string should be set for each `URLRequest`. 104 | public enum Destination { 105 | /// Applies the encoded query string to any existing query string for `.get`, `.head`, and `.delete` request. 106 | /// Sets it to the `httpBody` for all other methods. 107 | case methodDependent 108 | /// Applies the encoded query string to any existing query string from the `URLRequest`. 109 | case queryString 110 | /// Applies the encoded query string to the `httpBody` of the `URLRequest`. 111 | case httpBody 112 | 113 | /// Determines whether the URL-encoded string should be applied to the `URLRequest`'s `url`. 114 | /// 115 | /// - Parameter method: The `HTTPMethod`. 116 | /// 117 | /// - Returns: Whether the URL-encoded string should be applied to a `URL`. 118 | func encodesParametersInURL(for method: HTTPMethod) -> Bool { 119 | switch self { 120 | case .methodDependent: return [.get, .head, .delete].contains(method) 121 | case .queryString: return true 122 | case .httpBody: return false 123 | } 124 | } 125 | } 126 | 127 | /// Returns an encoder with default parameters. 128 | public static var `default`: URLEncodedFormParameterEncoder { return URLEncodedFormParameterEncoder() } 129 | 130 | /// The `URLEncodedFormEncoder` to use. 131 | public let encoder: URLEncodedFormEncoder 132 | 133 | /// The `Destination` for the URL-encoded string. 134 | public let destination: Destination 135 | 136 | /// Creates an instance with the provided `URLEncodedFormEncoder` instance and `Destination` value. 137 | /// 138 | /// - Parameters: 139 | /// - encoder: The `URLEncodedFormEncoder`. `URLEncodedFormEncoder()` by default. 140 | /// - destination: The `Destination`. `.methodDependent` by default. 141 | public init(encoder: URLEncodedFormEncoder = URLEncodedFormEncoder(), destination: Destination = .methodDependent) { 142 | self.encoder = encoder 143 | self.destination = destination 144 | } 145 | 146 | open func encode(_ parameters: Parameters?, 147 | into request: URLRequest) throws -> URLRequest { 148 | guard let parameters = parameters else { return request } 149 | 150 | var request = request 151 | 152 | guard let url = request.url else { 153 | throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.url)) 154 | } 155 | 156 | guard let method = request.method else { 157 | let rawValue = request.method?.rawValue ?? "nil" 158 | throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.httpMethod(rawValue: rawValue))) 159 | } 160 | 161 | if destination.encodesParametersInURL(for: method), 162 | var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { 163 | let query: String = try Result { try encoder.encode(parameters) } 164 | .mapError { AFError.parameterEncoderFailed(reason: .encoderFailed(error: $0)) }.get() 165 | let newQueryString = [components.percentEncodedQuery, query].compactMap { $0 }.joinedWithAmpersands() 166 | components.percentEncodedQuery = newQueryString.isEmpty ? nil : newQueryString 167 | 168 | guard let newURL = components.url else { 169 | throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.url)) 170 | } 171 | 172 | request.url = newURL 173 | } else { 174 | if request.headers["Content-Type"] == nil { 175 | request.headers.update(.contentType("application/x-www-form-urlencoded; charset=utf-8")) 176 | } 177 | 178 | request.httpBody = try Result { try encoder.encode(parameters) } 179 | .mapError { AFError.parameterEncoderFailed(reason: .encoderFailed(error: $0)) }.get() 180 | } 181 | 182 | return request 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/RequestInterceptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RequestInterceptor.swift 3 | // 4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A type that can inspect and optionally adapt a `URLRequest` in some manner if necessary. 28 | public protocol RequestAdapter { 29 | /// Inspects and adapts the specified `URLRequest` in some manner and calls the completion handler with the Result. 30 | /// 31 | /// - Parameters: 32 | /// - urlRequest: The `URLRequest` to adapt. 33 | /// - session: The `Session` that will execute the `URLRequest`. 34 | /// - completion: The completion handler that must be called when adaptation is complete. 35 | func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) 36 | } 37 | 38 | // MARK: - 39 | 40 | /// Outcome of determination whether retry is necessary. 41 | public enum RetryResult { 42 | /// Retry should be attempted immediately. 43 | case retry 44 | /// Retry should be attempted after the associated `TimeInterval`. 45 | case retryWithDelay(TimeInterval) 46 | /// Do not retry. 47 | case doNotRetry 48 | /// Do not retry due to the associated `AFError`. 49 | case doNotRetryWithError(Error) 50 | } 51 | 52 | extension RetryResult { 53 | var retryRequired: Bool { 54 | switch self { 55 | case .retry, .retryWithDelay: return true 56 | default: return false 57 | } 58 | } 59 | 60 | var delay: TimeInterval? { 61 | switch self { 62 | case let .retryWithDelay(delay): return delay 63 | default: return nil 64 | } 65 | } 66 | 67 | var error: Error? { 68 | guard case let .doNotRetryWithError(error) = self else { return nil } 69 | return error 70 | } 71 | } 72 | 73 | /// A type that determines whether a request should be retried after being executed by the specified session manager 74 | /// and encountering an error. 75 | public protocol RequestRetrier { 76 | /// Determines whether the `Request` should be retried by calling the `completion` closure. 77 | /// 78 | /// This operation is fully asynchronous. Any amount of time can be taken to determine whether the request needs 79 | /// to be retried. The one requirement is that the completion closure is called to ensure the request is properly 80 | /// cleaned up after. 81 | /// 82 | /// - Parameters: 83 | /// - request: `Request` that failed due to the provided `Error`. 84 | /// - session: `Session` that produced the `Request`. 85 | /// - error: `Error` encountered while executing the `Request`. 86 | /// - completion: Completion closure to be executed when a retry decision has been determined. 87 | func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) 88 | } 89 | 90 | // MARK: - 91 | 92 | /// Type that provides both `RequestAdapter` and `RequestRetrier` functionality. 93 | public protocol RequestInterceptor: RequestAdapter, RequestRetrier {} 94 | 95 | extension RequestInterceptor { 96 | public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { 97 | completion(.success(urlRequest)) 98 | } 99 | 100 | public func retry(_ request: Request, 101 | for session: Session, 102 | dueTo error: Error, 103 | completion: @escaping (RetryResult) -> Void) { 104 | completion(.doNotRetry) 105 | } 106 | } 107 | 108 | /// `RequestAdapter` closure definition. 109 | public typealias AdaptHandler = (URLRequest, Session, _ completion: @escaping (Result) -> Void) -> Void 110 | /// `RequestRetrier` closure definition. 111 | public typealias RetryHandler = (Request, Session, Error, _ completion: @escaping (RetryResult) -> Void) -> Void 112 | 113 | // MARK: - 114 | 115 | /// Closure-based `RequestAdapter`. 116 | open class Adapter: RequestInterceptor { 117 | private let adaptHandler: AdaptHandler 118 | 119 | /// Creates an instance using the provided closure. 120 | /// 121 | /// - Parameter adaptHandler: `AdaptHandler` closure to be executed when handling request adaptation. 122 | public init(_ adaptHandler: @escaping AdaptHandler) { 123 | self.adaptHandler = adaptHandler 124 | } 125 | 126 | open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { 127 | adaptHandler(urlRequest, session, completion) 128 | } 129 | } 130 | 131 | // MARK: - 132 | 133 | /// Closure-based `RequestRetrier`. 134 | open class Retrier: RequestInterceptor { 135 | private let retryHandler: RetryHandler 136 | 137 | /// Creates an instance using the provided closure. 138 | /// 139 | /// - Parameter retryHandler: `RetryHandler` closure to be executed when handling request retry. 140 | public init(_ retryHandler: @escaping RetryHandler) { 141 | self.retryHandler = retryHandler 142 | } 143 | 144 | open func retry(_ request: Request, 145 | for session: Session, 146 | dueTo error: Error, 147 | completion: @escaping (RetryResult) -> Void) { 148 | retryHandler(request, session, error, completion) 149 | } 150 | } 151 | 152 | // MARK: - 153 | 154 | /// `RequestInterceptor` which can use multiple `RequestAdapter` and `RequestRetrier` values. 155 | open class Interceptor: RequestInterceptor { 156 | /// All `RequestAdapter`s associated with the instance. These adapters will be run until one fails. 157 | public let adapters: [RequestAdapter] 158 | /// All `RequestRetrier`s associated with the instance. These retriers will be run one at a time until one triggers retry. 159 | public let retriers: [RequestRetrier] 160 | 161 | /// Creates an instance from `AdaptHandler` and `RetryHandler` closures. 162 | /// 163 | /// - Parameters: 164 | /// - adaptHandler: `AdaptHandler` closure to be used. 165 | /// - retryHandler: `RetryHandler` closure to be used. 166 | public init(adaptHandler: @escaping AdaptHandler, retryHandler: @escaping RetryHandler) { 167 | adapters = [Adapter(adaptHandler)] 168 | retriers = [Retrier(retryHandler)] 169 | } 170 | 171 | /// Creates an instance from `RequestAdapter` and `RequestRetrier` values. 172 | /// 173 | /// - Parameters: 174 | /// - adapter: `RequestAdapter` value to be used. 175 | /// - retrier: `RequestRetrier` value to be used. 176 | public init(adapter: RequestAdapter, retrier: RequestRetrier) { 177 | adapters = [adapter] 178 | retriers = [retrier] 179 | } 180 | 181 | /// Creates an instance from the arrays of `RequestAdapter` and `RequestRetrier` values. 182 | /// 183 | /// - Parameters: 184 | /// - adapters: `RequestAdapter` values to be used. 185 | /// - retriers: `RequestRetrier` values to be used. 186 | public init(adapters: [RequestAdapter] = [], retriers: [RequestRetrier] = []) { 187 | self.adapters = adapters 188 | self.retriers = retriers 189 | } 190 | 191 | open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { 192 | adapt(urlRequest, for: session, using: adapters, completion: completion) 193 | } 194 | 195 | private func adapt(_ urlRequest: URLRequest, 196 | for session: Session, 197 | using adapters: [RequestAdapter], 198 | completion: @escaping (Result) -> Void) { 199 | var pendingAdapters = adapters 200 | 201 | guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return } 202 | 203 | let adapter = pendingAdapters.removeFirst() 204 | 205 | adapter.adapt(urlRequest, for: session) { result in 206 | switch result { 207 | case let .success(urlRequest): 208 | self.adapt(urlRequest, for: session, using: pendingAdapters, completion: completion) 209 | case .failure: 210 | completion(result) 211 | } 212 | } 213 | } 214 | 215 | open func retry(_ request: Request, 216 | for session: Session, 217 | dueTo error: Error, 218 | completion: @escaping (RetryResult) -> Void) { 219 | retry(request, for: session, dueTo: error, using: retriers, completion: completion) 220 | } 221 | 222 | private func retry(_ request: Request, 223 | for session: Session, 224 | dueTo error: Error, 225 | using retriers: [RequestRetrier], 226 | completion: @escaping (RetryResult) -> Void) { 227 | var pendingRetriers = retriers 228 | 229 | guard !pendingRetriers.isEmpty else { completion(.doNotRetry); return } 230 | 231 | let retrier = pendingRetriers.removeFirst() 232 | 233 | retrier.retry(request, for: session, dueTo: error) { result in 234 | switch result { 235 | case .retry, .retryWithDelay, .doNotRetryWithError: 236 | completion(result) 237 | case .doNotRetry: 238 | // Only continue to the next retrier if retry was not triggered and no error was encountered 239 | self.retry(request, for: session, dueTo: error, using: pendingRetriers, completion: completion) 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/Validation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Validation.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension Request { 28 | // MARK: Helper Types 29 | 30 | fileprivate typealias ErrorReason = AFError.ResponseValidationFailureReason 31 | 32 | /// Used to represent whether a validation succeeded or failed. 33 | public typealias ValidationResult = Result 34 | 35 | fileprivate struct MIMEType { 36 | let type: String 37 | let subtype: String 38 | 39 | var isWildcard: Bool { return type == "*" && subtype == "*" } 40 | 41 | init?(_ string: String) { 42 | let components: [String] = { 43 | let stripped = string.trimmingCharacters(in: .whitespacesAndNewlines) 44 | let split = stripped[..<(stripped.range(of: ";")?.lowerBound ?? stripped.endIndex)] 45 | 46 | return split.components(separatedBy: "/") 47 | }() 48 | 49 | if let type = components.first, let subtype = components.last { 50 | self.type = type 51 | self.subtype = subtype 52 | } else { 53 | return nil 54 | } 55 | } 56 | 57 | func matches(_ mime: MIMEType) -> Bool { 58 | switch (type, subtype) { 59 | case (mime.type, mime.subtype), (mime.type, "*"), ("*", mime.subtype), ("*", "*"): 60 | return true 61 | default: 62 | return false 63 | } 64 | } 65 | } 66 | 67 | // MARK: Properties 68 | 69 | fileprivate var acceptableStatusCodes: Range { return 200..<300 } 70 | 71 | fileprivate var acceptableContentTypes: [String] { 72 | if let accept = request?.value(forHTTPHeaderField: "Accept") { 73 | return accept.components(separatedBy: ",") 74 | } 75 | 76 | return ["*/*"] 77 | } 78 | 79 | // MARK: Status Code 80 | 81 | fileprivate func validate(statusCode acceptableStatusCodes: S, 82 | response: HTTPURLResponse) 83 | -> ValidationResult 84 | where S.Iterator.Element == Int { 85 | if acceptableStatusCodes.contains(response.statusCode) { 86 | return .success(Void()) 87 | } else { 88 | let reason: ErrorReason = .unacceptableStatusCode(code: response.statusCode) 89 | return .failure(AFError.responseValidationFailed(reason: reason)) 90 | } 91 | } 92 | 93 | // MARK: Content Type 94 | 95 | fileprivate func validate(contentType acceptableContentTypes: S, 96 | response: HTTPURLResponse, 97 | data: Data?) 98 | -> ValidationResult 99 | where S.Iterator.Element == String { 100 | guard let data = data, data.count > 0 else { return .success(Void()) } 101 | 102 | guard 103 | let responseContentType = response.mimeType, 104 | let responseMIMEType = MIMEType(responseContentType) 105 | else { 106 | for contentType in acceptableContentTypes { 107 | if let mimeType = MIMEType(contentType), mimeType.isWildcard { 108 | return .success(Void()) 109 | } 110 | } 111 | 112 | let error: AFError = { 113 | let reason: ErrorReason = .missingContentType(acceptableContentTypes: Array(acceptableContentTypes)) 114 | return AFError.responseValidationFailed(reason: reason) 115 | }() 116 | 117 | return .failure(error) 118 | } 119 | 120 | for contentType in acceptableContentTypes { 121 | if let acceptableMIMEType = MIMEType(contentType), acceptableMIMEType.matches(responseMIMEType) { 122 | return .success(Void()) 123 | } 124 | } 125 | 126 | let error: AFError = { 127 | let reason: ErrorReason = .unacceptableContentType(acceptableContentTypes: Array(acceptableContentTypes), 128 | responseContentType: responseContentType) 129 | 130 | return AFError.responseValidationFailed(reason: reason) 131 | }() 132 | 133 | return .failure(error) 134 | } 135 | } 136 | 137 | // MARK: - 138 | 139 | extension DataRequest { 140 | /// A closure used to validate a request that takes a URL request, a URL response and data, and returns whether the 141 | /// request was valid. 142 | public typealias Validation = (URLRequest?, HTTPURLResponse, Data?) -> ValidationResult 143 | 144 | /// Validates that the response has a status code in the specified sequence. 145 | /// 146 | /// If validation fails, subsequent calls to response handlers will have an associated error. 147 | /// 148 | /// - parameter range: The range of acceptable status codes. 149 | /// 150 | /// - returns: The request. 151 | @discardableResult 152 | public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { 153 | return validate { [unowned self] _, response, _ in 154 | self.validate(statusCode: acceptableStatusCodes, response: response) 155 | } 156 | } 157 | 158 | /// Validates that the response has a content type in the specified sequence. 159 | /// 160 | /// If validation fails, subsequent calls to response handlers will have an associated error. 161 | /// 162 | /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. 163 | /// 164 | /// - returns: The request. 165 | @discardableResult 166 | public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { 167 | return validate { [unowned self] _, response, data in 168 | self.validate(contentType: acceptableContentTypes(), response: response, data: data) 169 | } 170 | } 171 | 172 | /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content 173 | /// type matches any specified in the Accept HTTP header field. 174 | /// 175 | /// If validation fails, subsequent calls to response handlers will have an associated error. 176 | /// 177 | /// - returns: The request. 178 | @discardableResult 179 | public func validate() -> Self { 180 | let contentTypes: () -> [String] = { [unowned self] in 181 | self.acceptableContentTypes 182 | } 183 | return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) 184 | } 185 | } 186 | 187 | // MARK: - 188 | 189 | extension DownloadRequest { 190 | /// A closure used to validate a request that takes a URL request, a URL response, a temporary URL and a 191 | /// destination URL, and returns whether the request was valid. 192 | public typealias Validation = (_ request: URLRequest?, 193 | _ response: HTTPURLResponse, 194 | _ fileURL: URL?) 195 | -> ValidationResult 196 | 197 | /// Validates that the response has a status code in the specified sequence. 198 | /// 199 | /// If validation fails, subsequent calls to response handlers will have an associated error. 200 | /// 201 | /// - parameter range: The range of acceptable status codes. 202 | /// 203 | /// - returns: The request. 204 | @discardableResult 205 | public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { 206 | return validate { [unowned self] _, response, _ in 207 | self.validate(statusCode: acceptableStatusCodes, response: response) 208 | } 209 | } 210 | 211 | /// Validates that the response has a content type in the specified sequence. 212 | /// 213 | /// If validation fails, subsequent calls to response handlers will have an associated error. 214 | /// 215 | /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. 216 | /// 217 | /// - returns: The request. 218 | @discardableResult 219 | public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { 220 | return validate { [unowned self] _, response, fileURL in 221 | guard let validFileURL = fileURL else { 222 | return .failure(AFError.responseValidationFailed(reason: .dataFileNil)) 223 | } 224 | 225 | do { 226 | let data = try Data(contentsOf: validFileURL) 227 | return self.validate(contentType: acceptableContentTypes(), response: response, data: data) 228 | } catch { 229 | return .failure(AFError.responseValidationFailed(reason: .dataFileReadFailed(at: validFileURL))) 230 | } 231 | } 232 | } 233 | 234 | /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content 235 | /// type matches any specified in the Accept HTTP header field. 236 | /// 237 | /// If validation fails, subsequent calls to response handlers will have an associated error. 238 | /// 239 | /// - returns: The request. 240 | @discardableResult 241 | public func validate() -> Self { 242 | let contentTypes = { [unowned self] in 243 | self.acceptableContentTypes 244 | } 245 | return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/NetworkReachabilityManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkReachabilityManager.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | #if !(os(watchOS) || os(Linux)) 26 | 27 | import Foundation 28 | import SystemConfiguration 29 | 30 | /// The `NetworkReachabilityManager` class listens for reachability changes of hosts and addresses for both cellular and 31 | /// WiFi network interfaces. 32 | /// 33 | /// Reachability can be used to determine background information about why a network operation failed, or to retry 34 | /// network requests when a connection is established. It should not be used to prevent a user from initiating a network 35 | /// request, as it's possible that an initial request may be required to establish reachability. 36 | open class NetworkReachabilityManager { 37 | /// Defines the various states of network reachability. 38 | public enum NetworkReachabilityStatus { 39 | /// It is unknown whether the network is reachable. 40 | case unknown 41 | /// The network is not reachable. 42 | case notReachable 43 | /// The network is reachable on the associated `ConnectionType`. 44 | case reachable(ConnectionType) 45 | 46 | init(_ flags: SCNetworkReachabilityFlags) { 47 | guard flags.isActuallyReachable else { self = .notReachable; return } 48 | 49 | var networkStatus: NetworkReachabilityStatus = .reachable(.ethernetOrWiFi) 50 | 51 | if flags.isCellular { networkStatus = .reachable(.cellular) } 52 | 53 | self = networkStatus 54 | } 55 | 56 | /// Defines the various connection types detected by reachability flags. 57 | public enum ConnectionType { 58 | /// The connection type is either over Ethernet or WiFi. 59 | case ethernetOrWiFi 60 | /// The connection type is a cellular connection. 61 | case cellular 62 | } 63 | } 64 | 65 | /// A closure executed when the network reachability status changes. The closure takes a single argument: the 66 | /// network reachability status. 67 | public typealias Listener = (NetworkReachabilityStatus) -> Void 68 | 69 | /// Default `NetworkReachabilityManager` for the zero address and a `listenerQueue` of `.main`. 70 | public static let `default` = NetworkReachabilityManager() 71 | 72 | // MARK: - Properties 73 | 74 | /// Whether the network is currently reachable. 75 | open var isReachable: Bool { return isReachableOnCellular || isReachableOnEthernetOrWiFi } 76 | 77 | /// Whether the network is currently reachable over the cellular interface. 78 | /// 79 | /// - Note: Using this property to decide whether to make a high or low bandwidth request is not recommended. 80 | /// Instead, set the `allowsCellularAccess` on any `URLRequest`s being issued. 81 | /// 82 | open var isReachableOnCellular: Bool { return status == .reachable(.cellular) } 83 | 84 | /// Whether the network is currently reachable over Ethernet or WiFi interface. 85 | open var isReachableOnEthernetOrWiFi: Bool { return status == .reachable(.ethernetOrWiFi) } 86 | 87 | /// `DispatchQueue` on which reachability will update. 88 | public let reachabilityQueue = DispatchQueue(label: "org.alamofire.reachabilityQueue") 89 | 90 | /// Flags of the current reachability type, if any. 91 | open var flags: SCNetworkReachabilityFlags? { 92 | var flags = SCNetworkReachabilityFlags() 93 | 94 | return (SCNetworkReachabilityGetFlags(reachability, &flags)) ? flags : nil 95 | } 96 | 97 | /// The current network reachability status. 98 | open var status: NetworkReachabilityStatus { 99 | return flags.map(NetworkReachabilityStatus.init) ?? .unknown 100 | } 101 | 102 | /// Mutable state storage. 103 | struct MutableState { 104 | /// A closure executed when the network reachability status changes. 105 | var listener: Listener? 106 | /// `DispatchQueue` on which listeners will be called. 107 | var listenerQueue: DispatchQueue? 108 | /// Previously calculated status. 109 | var previousStatus: NetworkReachabilityStatus? 110 | } 111 | 112 | /// `SCNetworkReachability` instance providing notifications. 113 | private let reachability: SCNetworkReachability 114 | 115 | /// Protected storage for mutable state. 116 | private let mutableState = Protector(MutableState()) 117 | 118 | // MARK: - Initialization 119 | 120 | /// Creates an instance with the specified host. 121 | /// 122 | /// - Note: The `host` value must *not* contain a scheme, just the hostname. 123 | /// 124 | /// - Parameters: 125 | /// - host: Host used to evaluate network reachability. Must *not* include the scheme (e.g. `https`). 126 | public convenience init?(host: String) { 127 | guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else { return nil } 128 | 129 | self.init(reachability: reachability) 130 | } 131 | 132 | /// Creates an instance that monitors the address 0.0.0.0. 133 | /// 134 | /// Reachability treats the 0.0.0.0 address as a special token that causes it to monitor the general routing 135 | /// status of the device, both IPv4 and IPv6. 136 | public convenience init?() { 137 | var zero = sockaddr() 138 | zero.sa_len = UInt8(MemoryLayout.size) 139 | zero.sa_family = sa_family_t(AF_INET) 140 | 141 | guard let reachability = SCNetworkReachabilityCreateWithAddress(nil, &zero) else { return nil } 142 | 143 | self.init(reachability: reachability) 144 | } 145 | 146 | private init(reachability: SCNetworkReachability) { 147 | self.reachability = reachability 148 | } 149 | 150 | deinit { 151 | stopListening() 152 | } 153 | 154 | // MARK: - Listening 155 | 156 | /// Starts listening for changes in network reachability status. 157 | /// 158 | /// - Note: Stops and removes any existing listener. 159 | /// 160 | /// - Parameters: 161 | /// - queue: `DispatchQueue` on which to call the `listener` closure. `.main` by default. 162 | /// - listener: `Listener` closure called when reachability changes. 163 | /// 164 | /// - Returns: `true` if listening was started successfully, `false` otherwise. 165 | @discardableResult 166 | open func startListening(onQueue queue: DispatchQueue = .main, 167 | onUpdatePerforming listener: @escaping Listener) -> Bool { 168 | stopListening() 169 | 170 | mutableState.write { state in 171 | state.listenerQueue = queue 172 | state.listener = listener 173 | } 174 | 175 | var context = SCNetworkReachabilityContext(version: 0, 176 | info: Unmanaged.passRetained(self).toOpaque(), 177 | retain: nil, 178 | release: nil, 179 | copyDescription: nil) 180 | let callback: SCNetworkReachabilityCallBack = { _, flags, info in 181 | guard let info = info else { return } 182 | 183 | let instance = Unmanaged.fromOpaque(info).takeUnretainedValue() 184 | instance.notifyListener(flags) 185 | } 186 | 187 | let queueAdded = SCNetworkReachabilitySetDispatchQueue(reachability, reachabilityQueue) 188 | let callbackAdded = SCNetworkReachabilitySetCallback(reachability, callback, &context) 189 | 190 | // Manually call listener to give initial state, since the framework may not. 191 | if let currentFlags = flags { 192 | reachabilityQueue.async { 193 | self.notifyListener(currentFlags) 194 | } 195 | } 196 | 197 | return callbackAdded && queueAdded 198 | } 199 | 200 | /// Stops listening for changes in network reachability status. 201 | open func stopListening() { 202 | SCNetworkReachabilitySetCallback(reachability, nil, nil) 203 | SCNetworkReachabilitySetDispatchQueue(reachability, nil) 204 | mutableState.write { state in 205 | state.listener = nil 206 | state.listenerQueue = nil 207 | state.previousStatus = nil 208 | } 209 | } 210 | 211 | // MARK: - Internal - Listener Notification 212 | 213 | /// Calls the `listener` closure of the `listenerQueue` if the computed status hasn't changed. 214 | /// 215 | /// - Note: Should only be called from the `reachabilityQueue`. 216 | /// 217 | /// - Parameter flags: `SCNetworkReachabilityFlags` to use to calculate the status. 218 | func notifyListener(_ flags: SCNetworkReachabilityFlags) { 219 | let newStatus = NetworkReachabilityStatus(flags) 220 | 221 | mutableState.write { state in 222 | guard state.previousStatus != newStatus else { return } 223 | 224 | state.previousStatus = newStatus 225 | 226 | let listener = state.listener 227 | state.listenerQueue?.async { listener?(newStatus) } 228 | } 229 | } 230 | } 231 | 232 | // MARK: - 233 | 234 | extension NetworkReachabilityManager.NetworkReachabilityStatus: Equatable {} 235 | 236 | extension SCNetworkReachabilityFlags { 237 | var isReachable: Bool { return contains(.reachable) } 238 | var isConnectionRequired: Bool { return contains(.connectionRequired) } 239 | var canConnectAutomatically: Bool { return contains(.connectionOnDemand) || contains(.connectionOnTraffic) } 240 | var canConnectWithoutUserInteraction: Bool { return canConnectAutomatically && !contains(.interventionRequired) } 241 | var isActuallyReachable: Bool { return isReachable && (!isConnectionRequired || canConnectWithoutUserInteraction) } 242 | var isCellular: Bool { 243 | #if os(iOS) || os(tvOS) 244 | return contains(.isWWAN) 245 | #else 246 | return false 247 | #endif 248 | } 249 | 250 | /// Human readable `String` for all states, to help with debugging. 251 | var readableDescription: String { 252 | let W = isCellular ? "W" : "-" 253 | let R = isReachable ? "R" : "-" 254 | let c = isConnectionRequired ? "c" : "-" 255 | let t = contains(.transientConnection) ? "t" : "-" 256 | let i = contains(.interventionRequired) ? "i" : "-" 257 | let C = contains(.connectionOnTraffic) ? "C" : "-" 258 | let D = contains(.connectionOnDemand) ? "D" : "-" 259 | let l = contains(.isLocalAddress) ? "l" : "-" 260 | let d = contains(.isDirect) ? "d" : "-" 261 | let a = contains(.connectionAutomatic) ? "a" : "-" 262 | 263 | return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)\(a)" 264 | } 265 | } 266 | #endif 267 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/ParameterEncoding.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ParameterEncoding.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// A dictionary of parameters to apply to a `URLRequest`. 28 | public typealias Parameters = [String: Any] 29 | 30 | /// A type used to define how a set of parameters are applied to a `URLRequest`. 31 | public protocol ParameterEncoding { 32 | /// Creates a `URLRequest` by encoding parameters and applying them on the passed request. 33 | /// 34 | /// - Parameters: 35 | /// - urlRequest: `URLRequestConvertible` value onto which parameters will be encoded. 36 | /// - parameters: `Parameters` to encode onto the request. 37 | /// 38 | /// - Returns: The encoded `URLRequest`. 39 | /// - Throws: Any `Error` produced during parameter encoding. 40 | func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest 41 | } 42 | 43 | // MARK: - 44 | 45 | /// Creates a url-encoded query string to be set as or appended to any existing URL query string or set as the HTTP 46 | /// body of the URL request. Whether the query string is set or appended to any existing URL query string or set as 47 | /// the HTTP body depends on the destination of the encoding. 48 | /// 49 | /// The `Content-Type` HTTP header field of an encoded request with HTTP body is set to 50 | /// `application/x-www-form-urlencoded; charset=utf-8`. 51 | /// 52 | /// There is no published specification for how to encode collection types. By default the convention of appending 53 | /// `[]` to the key for array values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for 54 | /// nested dictionary values (`foo[bar]=baz`) is used. Optionally, `ArrayEncoding` can be used to omit the 55 | /// square brackets appended to array keys. 56 | /// 57 | /// `BoolEncoding` can be used to configure how boolean values are encoded. The default behavior is to encode 58 | /// `true` as 1 and `false` as 0. 59 | public struct URLEncoding: ParameterEncoding { 60 | // MARK: Helper Types 61 | 62 | /// Defines whether the url-encoded query string is applied to the existing query string or HTTP body of the 63 | /// resulting URL request. 64 | public enum Destination { 65 | /// Applies encoded query string result to existing query string for `GET`, `HEAD` and `DELETE` requests and 66 | /// sets as the HTTP body for requests with any other HTTP method. 67 | case methodDependent 68 | /// Sets or appends encoded query string result to existing query string. 69 | case queryString 70 | /// Sets encoded query string result as the HTTP body of the URL request. 71 | case httpBody 72 | 73 | func encodesParametersInURL(for method: HTTPMethod) -> Bool { 74 | switch self { 75 | case .methodDependent: return [.get, .head, .delete].contains(method) 76 | case .queryString: return true 77 | case .httpBody: return false 78 | } 79 | } 80 | } 81 | 82 | /// Configures how `Array` parameters are encoded. 83 | public enum ArrayEncoding { 84 | /// An empty set of square brackets is appended to the key for every value. This is the default behavior. 85 | case brackets 86 | /// No brackets are appended. The key is encoded as is. 87 | case noBrackets 88 | 89 | func encode(key: String) -> String { 90 | switch self { 91 | case .brackets: 92 | return "\(key)[]" 93 | case .noBrackets: 94 | return key 95 | } 96 | } 97 | } 98 | 99 | /// Configures how `Bool` parameters are encoded. 100 | public enum BoolEncoding { 101 | /// Encode `true` as `1` and `false` as `0`. This is the default behavior. 102 | case numeric 103 | /// Encode `true` and `false` as string literals. 104 | case literal 105 | 106 | func encode(value: Bool) -> String { 107 | switch self { 108 | case .numeric: 109 | return value ? "1" : "0" 110 | case .literal: 111 | return value ? "true" : "false" 112 | } 113 | } 114 | } 115 | 116 | // MARK: Properties 117 | 118 | /// Returns a default `URLEncoding` instance with a `.methodDependent` destination. 119 | public static var `default`: URLEncoding { return URLEncoding() } 120 | 121 | /// Returns a `URLEncoding` instance with a `.queryString` destination. 122 | public static var queryString: URLEncoding { return URLEncoding(destination: .queryString) } 123 | 124 | /// Returns a `URLEncoding` instance with an `.httpBody` destination. 125 | public static var httpBody: URLEncoding { return URLEncoding(destination: .httpBody) } 126 | 127 | /// The destination defining where the encoded query string is to be applied to the URL request. 128 | public let destination: Destination 129 | 130 | /// The encoding to use for `Array` parameters. 131 | public let arrayEncoding: ArrayEncoding 132 | 133 | /// The encoding to use for `Bool` parameters. 134 | public let boolEncoding: BoolEncoding 135 | 136 | // MARK: Initialization 137 | 138 | /// Creates an instance using the specified parameters. 139 | /// 140 | /// - Parameters: 141 | /// - destination: `Destination` defining where the encoded query string will be applied. `.methodDependent` by 142 | /// default. 143 | /// - arrayEncoding: `ArrayEncoding` to use. `.brackets` by default. 144 | /// - boolEncoding: `BoolEncoding` to use. `.numeric` by default. 145 | public init(destination: Destination = .methodDependent, 146 | arrayEncoding: ArrayEncoding = .brackets, 147 | boolEncoding: BoolEncoding = .numeric) { 148 | self.destination = destination 149 | self.arrayEncoding = arrayEncoding 150 | self.boolEncoding = boolEncoding 151 | } 152 | 153 | // MARK: Encoding 154 | 155 | public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { 156 | var urlRequest = try urlRequest.asURLRequest() 157 | 158 | guard let parameters = parameters else { return urlRequest } 159 | 160 | if let method = urlRequest.method, destination.encodesParametersInURL(for: method) { 161 | guard let url = urlRequest.url else { 162 | throw AFError.parameterEncodingFailed(reason: .missingURL) 163 | } 164 | 165 | if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty { 166 | let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters) 167 | urlComponents.percentEncodedQuery = percentEncodedQuery 168 | urlRequest.url = urlComponents.url 169 | } 170 | } else { 171 | if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { 172 | urlRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type") 173 | } 174 | 175 | urlRequest.httpBody = Data(query(parameters).utf8) 176 | } 177 | 178 | return urlRequest 179 | } 180 | 181 | /// Creates a percent-escaped, URL encoded query string components from the given key-value pair recursively. 182 | /// 183 | /// - Parameters: 184 | /// - key: Key of the query component. 185 | /// - value: Value of the query component. 186 | /// 187 | /// - Returns: The percent-escaped, URL encoded query string components. 188 | public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] { 189 | var components: [(String, String)] = [] 190 | 191 | if let dictionary = value as? [String: Any] { 192 | for (nestedKey, value) in dictionary { 193 | components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value) 194 | } 195 | } else if let array = value as? [Any] { 196 | for value in array { 197 | components += queryComponents(fromKey: arrayEncoding.encode(key: key), value: value) 198 | } 199 | } else if let value = value as? NSNumber { 200 | if value.isBool { 201 | components.append((escape(key), escape(boolEncoding.encode(value: value.boolValue)))) 202 | } else { 203 | components.append((escape(key), escape("\(value)"))) 204 | } 205 | } else if let bool = value as? Bool { 206 | components.append((escape(key), escape(boolEncoding.encode(value: bool)))) 207 | } else { 208 | components.append((escape(key), escape("\(value)"))) 209 | } 210 | 211 | return components 212 | } 213 | 214 | /// Creates a percent-escaped string following RFC 3986 for a query string key or value. 215 | /// 216 | /// - Parameter string: `String` to be percent-escaped. 217 | /// 218 | /// - Returns: The percent-escaped `String`. 219 | public func escape(_ string: String) -> String { 220 | return string.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed) ?? string 221 | } 222 | 223 | private func query(_ parameters: [String: Any]) -> String { 224 | var components: [(String, String)] = [] 225 | 226 | for key in parameters.keys.sorted(by: <) { 227 | let value = parameters[key]! 228 | components += queryComponents(fromKey: key, value: value) 229 | } 230 | return components.map { "\($0)=\($1)" }.joined(separator: "&") 231 | } 232 | } 233 | 234 | // MARK: - 235 | 236 | /// Uses `JSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the 237 | /// request. The `Content-Type` HTTP header field of an encoded request is set to `application/json`. 238 | public struct JSONEncoding: ParameterEncoding { 239 | // MARK: Properties 240 | 241 | /// Returns a `JSONEncoding` instance with default writing options. 242 | public static var `default`: JSONEncoding { return JSONEncoding() } 243 | 244 | /// Returns a `JSONEncoding` instance with `.prettyPrinted` writing options. 245 | public static var prettyPrinted: JSONEncoding { return JSONEncoding(options: .prettyPrinted) } 246 | 247 | /// The options for writing the parameters as JSON data. 248 | public let options: JSONSerialization.WritingOptions 249 | 250 | // MARK: Initialization 251 | 252 | /// Creates an instance using the specified `WritingOptions`. 253 | /// 254 | /// - Parameter options: `JSONSerialization.WritingOptions` to use. 255 | public init(options: JSONSerialization.WritingOptions = []) { 256 | self.options = options 257 | } 258 | 259 | // MARK: Encoding 260 | 261 | public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { 262 | var urlRequest = try urlRequest.asURLRequest() 263 | 264 | guard let parameters = parameters else { return urlRequest } 265 | 266 | do { 267 | let data = try JSONSerialization.data(withJSONObject: parameters, options: options) 268 | 269 | if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { 270 | urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") 271 | } 272 | 273 | urlRequest.httpBody = data 274 | } catch { 275 | throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) 276 | } 277 | 278 | return urlRequest 279 | } 280 | 281 | /// Encodes any JSON compatible object into a `URLRequest`. 282 | /// 283 | /// - Parameters: 284 | /// - urlRequest: `URLRequestConvertible` value into which the object will be encoded. 285 | /// - jsonObject: `Any` value (must be JSON compatible` to be encoded into the `URLRequest`. `nil` by default. 286 | /// 287 | /// - Returns: The encoded `URLRequest`. 288 | /// - Throws: Any `Error` produced during encoding. 289 | public func encode(_ urlRequest: URLRequestConvertible, withJSONObject jsonObject: Any? = nil) throws -> URLRequest { 290 | var urlRequest = try urlRequest.asURLRequest() 291 | 292 | guard let jsonObject = jsonObject else { return urlRequest } 293 | 294 | do { 295 | let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options) 296 | 297 | if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { 298 | urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") 299 | } 300 | 301 | urlRequest.httpBody = data 302 | } catch { 303 | throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) 304 | } 305 | 306 | return urlRequest 307 | } 308 | } 309 | 310 | // MARK: - 311 | 312 | extension NSNumber { 313 | fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) } 314 | } 315 | -------------------------------------------------------------------------------- /Pods/Alamofire/README.md: -------------------------------------------------------------------------------- 1 | ![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/Alamofire/Alamofire/master/alamofire.png) 2 | 3 | [![Build Status](https://travis-ci.org/Alamofire/Alamofire.svg?branch=master)](https://travis-ci.org/Alamofire/Alamofire) 4 | [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Alamofire.svg)](https://img.shields.io/cocoapods/v/Alamofire.svg) 5 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Platform](https://img.shields.io/cocoapods/p/Alamofire.svg?style=flat)](https://alamofire.github.io/Alamofire) 7 | [![Twitter](https://img.shields.io/badge/twitter-@AlamofireSF-blue.svg?style=flat)](https://twitter.com/AlamofireSF) 8 | [![Gitter](https://badges.gitter.im/Alamofire/Alamofire.svg)](https://gitter.im/Alamofire/Alamofire?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 9 | [![Open Source Helpers](https://www.codetriage.com/alamofire/alamofire/badges/users.svg)](https://www.codetriage.com/alamofire/alamofire) 10 | 11 | Alamofire is an HTTP networking library written in Swift. 12 | 13 | **⚠️⚠️⚠️ WARNING ⚠️⚠️⚠️** This documentation is out of date during the Alamofire 5 beta process. 14 | 15 | - [Features](#features) 16 | - [Component Libraries](#component-libraries) 17 | - [Requirements](#requirements) 18 | - [Migration Guides](#migration-guides) 19 | - [Communication](#communication) 20 | - [Installation](#installation) 21 | - [Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#using-alamofire) 22 | - [**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) 23 | - **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) 24 | - **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) 25 | - **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) 26 | - [Advanced Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md) 27 | - **URL Session -** [Session Manager](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#session-manager), [Session Delegate](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#session-delegate), [Request](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#request) 28 | - **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) 29 | - **Model Objects -** [Custom Response Serialization](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#custom-response-serialization) 30 | - **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) 31 | - [Open Radars](#open-radars) 32 | - [FAQ](#faq) 33 | - [Credits](#credits) 34 | - [Donations](#donations) 35 | - [License](#license) 36 | 37 | ## Features 38 | 39 | - [x] Chainable Request / Response Methods 40 | - [x] URL / JSON / plist Parameter Encoding 41 | - [x] Upload File / Data / Stream / MultipartFormData 42 | - [x] Download File using Request or Resume Data 43 | - [x] Authentication with URLCredential 44 | - [x] HTTP Response Validation 45 | - [x] Upload and Download Progress Closures with Progress 46 | - [x] cURL Command Output 47 | - [x] Dynamically Adapt and Retry Requests 48 | - [x] TLS Certificate and Public Key Pinning 49 | - [x] Network Reachability 50 | - [x] Comprehensive Unit and Integration Test Coverage 51 | - [x] [Complete Documentation](https://alamofire.github.io/Alamofire) 52 | 53 | ## Component Libraries 54 | 55 | 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. 56 | 57 | - [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. 58 | - [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. 59 | 60 | ## Requirements 61 | 62 | - iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ 63 | - Xcode 10.2+ 64 | - Swift 5+ 65 | 66 | ## Migration Guides 67 | 68 | - Alamofire 5.0 Migration Guide: To be written! 69 | - [Alamofire 4.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md) 70 | - [Alamofire 3.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md) 71 | - [Alamofire 2.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%202.0%20Migration%20Guide.md) 72 | 73 | ## Communication 74 | - If you **need help with making network requests** using Alamofire, use [Stack Overflow](https://stackoverflow.com/questions/tagged/alamofire) and tag `alamofire`. 75 | - If you need to **find or understand an API**, check [our documentation](http://alamofire.github.io/Alamofire/) or [Apple's documentation for `URLSession`](https://developer.apple.com/documentation/foundation/url_loading_system), on top of which Alamofire is built. 76 | - If you need **help with an Alamofire feature**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). 77 | - If you'd like to **discuss Alamofire best practices**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). 78 | - If you'd like to **discuss a feature request**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). 79 | - If you **found a bug**, open an issue here on GitHub and follow the guide. The more detail the better! 80 | - If you **want to contribute**, submit a pull request. 81 | 82 | ## Installation 83 | 84 | ### CocoaPods 85 | 86 | [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`: 87 | 88 | ```ruby 89 | pod 'Alamofire', '~> 5.0.0-rc.3' 90 | ``` 91 | 92 | ### Carthage 93 | 94 | [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`: 95 | 96 | ```ogdl 97 | github "Alamofire/Alamofire" "5.0.0-rc.3" 98 | ``` 99 | 100 | ### Swift Package Manager 101 | 102 | The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. It is in early development, but Alamofire does support its use on supported platforms. 103 | 104 | Once you have your Swift package set up, adding Alamofire as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. 105 | 106 | ```swift 107 | dependencies: [ 108 | .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0-rc.3") 109 | ] 110 | ``` 111 | 112 | ### Manually 113 | 114 | If you prefer not to use any of the aforementioned dependency managers, you can integrate Alamofire into your project manually. 115 | 116 | #### Embedded Framework 117 | 118 | - Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialized as a git repository: 119 | 120 | ```bash 121 | $ git init 122 | ``` 123 | 124 | - Add Alamofire as a git [submodule](https://git-scm.com/docs/git-submodule) by running the following command: 125 | 126 | ```bash 127 | $ git submodule add https://github.com/Alamofire/Alamofire.git 128 | ``` 129 | 130 | - Open the new `Alamofire` folder, and drag the `Alamofire.xcodeproj` into the Project Navigator of your application's Xcode project. 131 | 132 | > It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter. 133 | 134 | - Select the `Alamofire.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target. 135 | - Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar. 136 | - In the tab bar at the top of that window, open the "General" panel. 137 | - Click on the `+` button under the "Embedded Binaries" section. 138 | - You will see two different `Alamofire.xcodeproj` folders each with two different versions of the `Alamofire.framework` nested inside a `Products` folder. 139 | 140 | > It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `Alamofire.framework`. 141 | 142 | - Select the top `Alamofire.framework` for iOS and the bottom one for macOS. 143 | 144 | > 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`. 145 | 146 | - And that's it! 147 | 148 | > 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. 149 | 150 | ## Open Radars 151 | 152 | The following radars have some effect on the current implementation of Alamofire. 153 | 154 | - [`rdar://21349340`](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in test case 155 | - `rdar://26870455` - Background URL Session Configurations do not work in the simulator 156 | - `rdar://26849668` - Some URLProtocol APIs do not properly handle `URLRequest` 157 | 158 | ## Resolved Radars 159 | 160 | The following radars have been resolved over time after being filed against the Alamofire project. 161 | 162 | - [`rdar://26761490`](http://www.openradar.me/radar?id=5010235949318144) - Swift string interpolation causing memory leak with common usage. 163 | - (Resolved): 9/1/17 in Xcode 9 beta 6. 164 | - [`rdar://36082113`](http://openradar.appspot.com/radar?id=4942308441063424) - `URLSessionTaskMetrics` failing to link on watchOS 3.0+ 165 | - (Resolved): Just add `CFNetwork` to your linked frameworks. 166 | 167 | ## FAQ 168 | 169 | ### What's the origin of the name Alamofire? 170 | 171 | Alamofire is named after the [Alamo Fire flower](https://aggie-horticulture.tamu.edu/wildseed/alamofire.html), a hybrid variant of the Bluebonnet, the official state flower of Texas. 172 | 173 | ## Credits 174 | 175 | Alamofire is owned and maintained by the [Alamofire Software Foundation](http://alamofire.org). You can follow them on Twitter at [@AlamofireSF](https://twitter.com/AlamofireSF) for project updates and releases. 176 | 177 | ### Security Disclosure 178 | 179 | If you believe you have identified a security vulnerability with Alamofire, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker. 180 | 181 | ## Donations 182 | 183 | The [ASF](https://github.com/Alamofire/Foundation#members) is looking to raise money to officially stay registered as a federal non-profit organization. 184 | Registering will allow us members to gain some legal protections and also allow us to put donations to use, tax free. 185 | Donating to the ASF will enable us to: 186 | 187 | - Pay our yearly legal fees to keep the non-profit in good status 188 | - Pay for our mail servers to help us stay on top of all questions and security issues 189 | - Potentially fund test servers to make it easier for us to test the edge cases 190 | - Potentially fund developers to work on one of our projects full-time 191 | 192 | The community adoption of the ASF libraries has been amazing. 193 | We are greatly humbled by your enthusiasm around the projects, and want to continue to do everything we can to move the needle forward. 194 | With your continued support, the ASF will be able to improve its reach and also provide better legal safety for the core members. 195 | If you use any of our libraries for work, see if your employers would be interested in donating. 196 | Any amount you can donate today to help us reach our goal would be greatly appreciated. 197 | 198 | [![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) 199 | 200 | ## License 201 | 202 | Alamofire is released under the MIT license. [See LICENSE](https://github.com/Alamofire/Alamofire/blob/master/LICENSE) for details. 203 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/SessionDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SessionDelegate.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// Class which implements the various `URLSessionDelegate` methods to connect various Alamofire features. 28 | open class SessionDelegate: NSObject { 29 | private let fileManager: FileManager 30 | 31 | weak var stateProvider: SessionStateProvider? 32 | var eventMonitor: EventMonitor? 33 | 34 | /// Creates an instance from the given `FileManager`. 35 | /// 36 | /// - Parameter fileManager: `FileManager` to use for underlying file management, such as moving downloaded files. 37 | /// `.default` by default. 38 | public init(fileManager: FileManager = .default) { 39 | self.fileManager = fileManager 40 | } 41 | } 42 | 43 | /// Type which provides various `Session` state values. 44 | protocol SessionStateProvider: AnyObject { 45 | var serverTrustManager: ServerTrustManager? { get } 46 | var redirectHandler: RedirectHandler? { get } 47 | var cachedResponseHandler: CachedResponseHandler? { get } 48 | 49 | func request(for task: URLSessionTask) -> Request? 50 | func didGatherMetricsForTask(_ task: URLSessionTask) 51 | func didCompleteTask(_ task: URLSessionTask) 52 | func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? 53 | func cancelRequestsForSessionInvalidation(with error: Error?) 54 | } 55 | 56 | // MARK: URLSessionDelegate 57 | 58 | extension SessionDelegate: URLSessionDelegate { 59 | open func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { 60 | eventMonitor?.urlSession(session, didBecomeInvalidWithError: error) 61 | 62 | stateProvider?.cancelRequestsForSessionInvalidation(with: error) 63 | } 64 | } 65 | 66 | // MARK: URLSessionTaskDelegate 67 | 68 | extension SessionDelegate: URLSessionTaskDelegate { 69 | /// Result of a `URLAuthenticationChallenge` evaluation. 70 | typealias ChallengeEvaluation = (disposition: URLSession.AuthChallengeDisposition, credential: URLCredential?, error: AFError?) 71 | 72 | open func urlSession(_ session: URLSession, 73 | task: URLSessionTask, 74 | didReceive challenge: URLAuthenticationChallenge, 75 | completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { 76 | eventMonitor?.urlSession(session, task: task, didReceive: challenge) 77 | 78 | let evaluation: ChallengeEvaluation 79 | switch challenge.protectionSpace.authenticationMethod { 80 | case NSURLAuthenticationMethodServerTrust: 81 | evaluation = attemptServerTrustAuthentication(with: challenge) 82 | case NSURLAuthenticationMethodHTTPBasic, NSURLAuthenticationMethodHTTPDigest, NSURLAuthenticationMethodNTLM, NSURLAuthenticationMethodNegotiate: 83 | evaluation = attemptCredentialAuthentication(for: challenge, belongingTo: task) 84 | // case NSURLAuthenticationMethodClientCertificate: 85 | // Alamofire doesn't currently support client certificate validation. 86 | default: 87 | evaluation = (.performDefaultHandling, nil, nil) 88 | } 89 | 90 | if let error = evaluation.error { 91 | stateProvider?.request(for: task)?.didFailTask(task, earlyWithError: error) 92 | } 93 | 94 | completionHandler(evaluation.disposition, evaluation.credential) 95 | } 96 | 97 | /// Evaluates the server trust `URLAuthenticationChallenge` received. 98 | /// 99 | /// - Parameter challenge: The `URLAuthenticationChallenge`. 100 | /// 101 | /// - Returns: The `ChallengeEvaluation`. 102 | func attemptServerTrustAuthentication(with challenge: URLAuthenticationChallenge) -> ChallengeEvaluation { 103 | let host = challenge.protectionSpace.host 104 | 105 | guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, 106 | let trust = challenge.protectionSpace.serverTrust 107 | else { 108 | return (.performDefaultHandling, nil, nil) 109 | } 110 | 111 | do { 112 | guard let evaluator = try stateProvider?.serverTrustManager?.serverTrustEvaluator(forHost: host) else { 113 | return (.performDefaultHandling, nil, nil) 114 | } 115 | 116 | try evaluator.evaluate(trust, forHost: host) 117 | 118 | return (.useCredential, URLCredential(trust: trust), nil) 119 | } catch { 120 | return (.cancelAuthenticationChallenge, nil, error.asAFError(or: .serverTrustEvaluationFailed(reason: .customEvaluationFailed(error: error)))) 121 | } 122 | } 123 | 124 | /// Evaluates the credential-based authentication `URLAuthenticationChallenge` received for `task`. 125 | /// 126 | /// - Parameters: 127 | /// - challenge: The `URLAuthenticationChallenge`. 128 | /// - task: The `URLSessionTask` which received the challenge. 129 | /// 130 | /// - Returns: The `ChallengeEvaluation`. 131 | func attemptCredentialAuthentication(for challenge: URLAuthenticationChallenge, 132 | belongingTo task: URLSessionTask) -> ChallengeEvaluation { 133 | guard challenge.previousFailureCount == 0 else { 134 | return (.rejectProtectionSpace, nil, nil) 135 | } 136 | 137 | guard let credential = stateProvider?.credential(for: task, in: challenge.protectionSpace) else { 138 | return (.performDefaultHandling, nil, nil) 139 | } 140 | 141 | return (.useCredential, credential, nil) 142 | } 143 | 144 | open func urlSession(_ session: URLSession, 145 | task: URLSessionTask, 146 | didSendBodyData bytesSent: Int64, 147 | totalBytesSent: Int64, 148 | totalBytesExpectedToSend: Int64) { 149 | eventMonitor?.urlSession(session, 150 | task: task, 151 | didSendBodyData: bytesSent, 152 | totalBytesSent: totalBytesSent, 153 | totalBytesExpectedToSend: totalBytesExpectedToSend) 154 | 155 | stateProvider?.request(for: task)?.updateUploadProgress(totalBytesSent: totalBytesSent, 156 | totalBytesExpectedToSend: totalBytesExpectedToSend) 157 | } 158 | 159 | open func urlSession(_ session: URLSession, 160 | task: URLSessionTask, 161 | needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) { 162 | eventMonitor?.urlSession(session, taskNeedsNewBodyStream: task) 163 | 164 | guard let request = stateProvider?.request(for: task) as? UploadRequest else { 165 | fatalError("needNewBodyStream for request that isn't UploadRequest.") 166 | } 167 | 168 | completionHandler(request.inputStream()) 169 | } 170 | 171 | open func urlSession(_ session: URLSession, 172 | task: URLSessionTask, 173 | willPerformHTTPRedirection response: HTTPURLResponse, 174 | newRequest request: URLRequest, 175 | completionHandler: @escaping (URLRequest?) -> Void) { 176 | eventMonitor?.urlSession(session, task: task, willPerformHTTPRedirection: response, newRequest: request) 177 | 178 | if let redirectHandler = stateProvider?.request(for: task)?.redirectHandler ?? stateProvider?.redirectHandler { 179 | redirectHandler.task(task, willBeRedirectedTo: request, for: response, completion: completionHandler) 180 | } else { 181 | completionHandler(request) 182 | } 183 | } 184 | 185 | open func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { 186 | eventMonitor?.urlSession(session, task: task, didFinishCollecting: metrics) 187 | 188 | stateProvider?.request(for: task)?.didGatherMetrics(metrics) 189 | 190 | stateProvider?.didGatherMetricsForTask(task) 191 | } 192 | 193 | open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { 194 | eventMonitor?.urlSession(session, task: task, didCompleteWithError: error) 195 | 196 | stateProvider?.request(for: task)?.didCompleteTask(task, with: error.map { $0.asAFError(or: .sessionTaskFailed(error: $0)) }) 197 | 198 | stateProvider?.didCompleteTask(task) 199 | } 200 | 201 | @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) 202 | open func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { 203 | eventMonitor?.urlSession(session, taskIsWaitingForConnectivity: task) 204 | } 205 | } 206 | 207 | // MARK: URLSessionDataDelegate 208 | 209 | extension SessionDelegate: URLSessionDataDelegate { 210 | open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { 211 | eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data) 212 | 213 | guard let request = stateProvider?.request(for: dataTask) as? DataRequest else { 214 | fatalError("dataTask received data for incorrect Request subclass: \(String(describing: stateProvider?.request(for: dataTask)))") 215 | } 216 | 217 | request.didReceive(data: data) 218 | } 219 | 220 | open func urlSession(_ session: URLSession, 221 | dataTask: URLSessionDataTask, 222 | willCacheResponse proposedResponse: CachedURLResponse, 223 | completionHandler: @escaping (CachedURLResponse?) -> Void) { 224 | eventMonitor?.urlSession(session, dataTask: dataTask, willCacheResponse: proposedResponse) 225 | 226 | if let handler = stateProvider?.request(for: dataTask)?.cachedResponseHandler ?? stateProvider?.cachedResponseHandler { 227 | handler.dataTask(dataTask, willCacheResponse: proposedResponse, completion: completionHandler) 228 | } else { 229 | completionHandler(proposedResponse) 230 | } 231 | } 232 | } 233 | 234 | // MARK: URLSessionDownloadDelegate 235 | 236 | extension SessionDelegate: URLSessionDownloadDelegate { 237 | open func urlSession(_ session: URLSession, 238 | downloadTask: URLSessionDownloadTask, 239 | didResumeAtOffset fileOffset: Int64, 240 | expectedTotalBytes: Int64) { 241 | eventMonitor?.urlSession(session, 242 | downloadTask: downloadTask, 243 | didResumeAtOffset: fileOffset, 244 | expectedTotalBytes: expectedTotalBytes) 245 | 246 | guard let downloadRequest = stateProvider?.request(for: downloadTask) as? DownloadRequest else { 247 | fatalError("No DownloadRequest found for downloadTask: \(downloadTask)") 248 | } 249 | 250 | downloadRequest.updateDownloadProgress(bytesWritten: fileOffset, 251 | totalBytesExpectedToWrite: expectedTotalBytes) 252 | } 253 | 254 | open func urlSession(_ session: URLSession, 255 | downloadTask: URLSessionDownloadTask, 256 | didWriteData bytesWritten: Int64, 257 | totalBytesWritten: Int64, 258 | totalBytesExpectedToWrite: Int64) { 259 | eventMonitor?.urlSession(session, 260 | downloadTask: downloadTask, 261 | didWriteData: bytesWritten, 262 | totalBytesWritten: totalBytesWritten, 263 | totalBytesExpectedToWrite: totalBytesExpectedToWrite) 264 | 265 | guard let downloadRequest = stateProvider?.request(for: downloadTask) as? DownloadRequest else { 266 | fatalError("No DownloadRequest found for downloadTask: \(downloadTask)") 267 | } 268 | 269 | downloadRequest.updateDownloadProgress(bytesWritten: bytesWritten, 270 | totalBytesExpectedToWrite: totalBytesExpectedToWrite) 271 | } 272 | 273 | open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { 274 | eventMonitor?.urlSession(session, downloadTask: downloadTask, didFinishDownloadingTo: location) 275 | 276 | guard let request = stateProvider?.request(for: downloadTask) as? DownloadRequest else { 277 | fatalError("Download finished but either no request found or request wasn't DownloadRequest") 278 | } 279 | 280 | guard let response = request.response else { 281 | fatalError("URLSessionDownloadTask finished downloading with no response.") 282 | } 283 | 284 | let (destination, options) = (request.destination)(location, response) 285 | 286 | eventMonitor?.request(request, didCreateDestinationURL: destination) 287 | 288 | do { 289 | if options.contains(.removePreviousFile), fileManager.fileExists(atPath: destination.path) { 290 | try fileManager.removeItem(at: destination) 291 | } 292 | 293 | if options.contains(.createIntermediateDirectories) { 294 | let directory = destination.deletingLastPathComponent() 295 | try fileManager.createDirectory(at: directory, withIntermediateDirectories: true) 296 | } 297 | 298 | try fileManager.moveItem(at: location, to: destination) 299 | 300 | request.didFinishDownloading(using: downloadTask, with: .success(destination)) 301 | } catch { 302 | request.didFinishDownloading(using: downloadTask, with: .failure(.downloadedFileMoveFailed(error: error, source: location, destination: destination))) 303 | } 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /Pods/Alamofire/Source/HTTPHeaders.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HTTPHeaders.swift 3 | // 4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /// An order-preserving and case-insensitive representation of HTTP headers. 28 | public struct HTTPHeaders { 29 | private var headers: [HTTPHeader] = [] 30 | 31 | /// Creates an empty instance. 32 | public init() {} 33 | 34 | /// Creates an instance from an array of `HTTPHeader`s. Duplicate case-insensitive names are collapsed into the last 35 | /// name and value encountered. 36 | public init(_ headers: [HTTPHeader]) { 37 | self.init() 38 | 39 | headers.forEach { update($0) } 40 | } 41 | 42 | /// Creates an instance from a `[String: String]`. Duplicate case-insensitive names are collapsed into the last name 43 | /// and value encountered. 44 | public init(_ dictionary: [String: String]) { 45 | self.init() 46 | 47 | dictionary.forEach { update(HTTPHeader(name: $0.key, value: $0.value)) } 48 | } 49 | 50 | /// Case-insensitively updates or appends an `HTTPHeader` into the instance using the provided `name` and `value`. 51 | /// 52 | /// - Parameters: 53 | /// - name: The `HTTPHeader` name. 54 | /// - value: The `HTTPHeader value. 55 | public mutating func add(name: String, value: String) { 56 | update(HTTPHeader(name: name, value: value)) 57 | } 58 | 59 | /// Case-insensitively updates or appends the provided `HTTPHeader` into the instance. 60 | /// 61 | /// - Parameter header: The `HTTPHeader` to update or append. 62 | public mutating func add(_ header: HTTPHeader) { 63 | update(header) 64 | } 65 | 66 | /// Case-insensitively updates or appends an `HTTPHeader` into the instance using the provided `name` and `value`. 67 | /// 68 | /// - Parameters: 69 | /// - name: The `HTTPHeader` name. 70 | /// - value: The `HTTPHeader value. 71 | public mutating func update(name: String, value: String) { 72 | update(HTTPHeader(name: name, value: value)) 73 | } 74 | 75 | /// Case-insensitively updates or appends the provided `HTTPHeader` into the instance. 76 | /// 77 | /// - Parameter header: The `HTTPHeader` to update or append. 78 | public mutating func update(_ header: HTTPHeader) { 79 | guard let index = headers.index(of: header.name) else { 80 | headers.append(header) 81 | return 82 | } 83 | 84 | headers.replaceSubrange(index...index, with: [header]) 85 | } 86 | 87 | /// Case-insensitively removes an `HTTPHeader`, if it exists, from the instance. 88 | /// 89 | /// - Parameter name: The name of the `HTTPHeader` to remove. 90 | public mutating func remove(name: String) { 91 | guard let index = headers.index(of: name) else { return } 92 | 93 | headers.remove(at: index) 94 | } 95 | 96 | /// Sort the current instance by header name. 97 | public mutating func sort() { 98 | headers.sort { $0.name < $1.name } 99 | } 100 | 101 | /// Returns an instance sorted by header name. 102 | /// 103 | /// - Returns: A copy of the current instance sorted by name. 104 | public func sorted() -> HTTPHeaders { 105 | return HTTPHeaders(headers.sorted { $0.name < $1.name }) 106 | } 107 | 108 | /// Case-insensitively find a header's value by name. 109 | /// 110 | /// - Parameter name: The name of the header to search for, case-insensitively. 111 | /// 112 | /// - Returns: The value of header, if it exists. 113 | public func value(for name: String) -> String? { 114 | guard let index = headers.index(of: name) else { return nil } 115 | 116 | return headers[index].value 117 | } 118 | 119 | /// Case-insensitively access the header with the given name. 120 | /// 121 | /// - Parameter name: The name of the header. 122 | public subscript(_ name: String) -> String? { 123 | get { return value(for: name) } 124 | set { 125 | if let value = newValue { 126 | update(name: name, value: value) 127 | } else { 128 | remove(name: name) 129 | } 130 | } 131 | } 132 | 133 | /// The dictionary representation of all headers. 134 | /// 135 | /// This representation does not preserve the current order of the instance. 136 | public var dictionary: [String: String] { 137 | let namesAndValues = headers.map { ($0.name, $0.value) } 138 | 139 | return Dictionary(namesAndValues, uniquingKeysWith: { _, last in last }) 140 | } 141 | } 142 | 143 | extension HTTPHeaders: ExpressibleByDictionaryLiteral { 144 | public init(dictionaryLiteral elements: (String, String)...) { 145 | self.init() 146 | 147 | elements.forEach { update(name: $0.0, value: $0.1) } 148 | } 149 | } 150 | 151 | extension HTTPHeaders: ExpressibleByArrayLiteral { 152 | public init(arrayLiteral elements: HTTPHeader...) { 153 | self.init(elements) 154 | } 155 | } 156 | 157 | extension HTTPHeaders: Sequence { 158 | public func makeIterator() -> IndexingIterator<[HTTPHeader]> { 159 | return headers.makeIterator() 160 | } 161 | } 162 | 163 | extension HTTPHeaders: Collection { 164 | public var startIndex: Int { 165 | return headers.startIndex 166 | } 167 | 168 | public var endIndex: Int { 169 | return headers.endIndex 170 | } 171 | 172 | public subscript(position: Int) -> HTTPHeader { 173 | return headers[position] 174 | } 175 | 176 | public func index(after i: Int) -> Int { 177 | return headers.index(after: i) 178 | } 179 | } 180 | 181 | extension HTTPHeaders: CustomStringConvertible { 182 | public var description: String { 183 | return headers.map { $0.description } 184 | .joined(separator: "\n") 185 | } 186 | } 187 | 188 | // MARK: - HTTPHeader 189 | 190 | /// A representation of a single HTTP header's name / value pair. 191 | public struct HTTPHeader: Hashable { 192 | /// Name of the header. 193 | public let name: String 194 | 195 | /// Value of the header. 196 | public let value: String 197 | 198 | /// Creates an instance from the given `name` and `value`. 199 | /// 200 | /// - Parameters: 201 | /// - name: The name of the header. 202 | /// - value: The value of the header. 203 | public init(name: String, value: String) { 204 | self.name = name 205 | self.value = value 206 | } 207 | } 208 | 209 | extension HTTPHeader: CustomStringConvertible { 210 | public var description: String { 211 | return "\(name): \(value)" 212 | } 213 | } 214 | 215 | extension HTTPHeader { 216 | /// Returns an `Accept` header. 217 | /// 218 | /// - Parameter value: The `Accept` value. 219 | /// - Returns: The header. 220 | public static func accept(_ value: String) -> HTTPHeader { 221 | return HTTPHeader(name: "Accept", value: value) 222 | } 223 | 224 | /// Returns an `Accept-Charset` header. 225 | /// 226 | /// - Parameter value: The `Accept-Charset` value. 227 | /// - Returns: The header. 228 | public static func acceptCharset(_ value: String) -> HTTPHeader { 229 | return HTTPHeader(name: "Accept-Charset", value: value) 230 | } 231 | 232 | /// Returns an `Accept-Language` header. 233 | /// 234 | /// Alamofire offers a default Accept-Language header that accumulates and encodes the system's preferred languages. 235 | /// Use `HTTPHeader.defaultAcceptLanguage`. 236 | /// 237 | /// - Parameter value: The `Accept-Language` value. 238 | /// 239 | /// - Returns: The header. 240 | public static func acceptLanguage(_ value: String) -> HTTPHeader { 241 | return HTTPHeader(name: "Accept-Language", value: value) 242 | } 243 | 244 | /// Returns an `Accept-Encoding` header. 245 | /// 246 | /// Alamofire offers a default accept encoding value that provides the most common values. Use 247 | /// `HTTPHeader.defaultAcceptEncoding`. 248 | /// 249 | /// - Parameter value: The `Accept-Encoding` value. 250 | /// 251 | /// - Returns: The header 252 | public static func acceptEncoding(_ value: String) -> HTTPHeader { 253 | return HTTPHeader(name: "Accept-Encoding", value: value) 254 | } 255 | 256 | /// Returns a `Basic` `Authorization` header using the `username` and `password` provided. 257 | /// 258 | /// - Parameters: 259 | /// - username: The username of the header. 260 | /// - password: The password of the header. 261 | /// 262 | /// - Returns: The header. 263 | public static func authorization(username: String, password: String) -> HTTPHeader { 264 | let credential = Data("\(username):\(password)".utf8).base64EncodedString() 265 | 266 | return authorization("Basic \(credential)") 267 | } 268 | 269 | /// Returns a `Bearer` `Authorization` header using the `bearerToken` provided 270 | /// 271 | /// - Parameter bearerToken: The bearer token. 272 | /// 273 | /// - Returns: The header. 274 | public static func authorization(bearerToken: String) -> HTTPHeader { 275 | return authorization("Bearer \(bearerToken)") 276 | } 277 | 278 | /// Returns an `Authorization` header. 279 | /// 280 | /// Alamofire provides built-in methods to produce `Authorization` headers. For a Basic `Authorization` header use 281 | /// `HTTPHeader.authorization(username:password:)`. For a Bearer `Authorization` header, use 282 | /// `HTTPHeader.authorization(bearerToken:)`. 283 | /// 284 | /// - Parameter value: The `Authorization` value. 285 | /// 286 | /// - Returns: The header. 287 | public static func authorization(_ value: String) -> HTTPHeader { 288 | return HTTPHeader(name: "Authorization", value: value) 289 | } 290 | 291 | /// Returns a `Content-Disposition` header. 292 | /// 293 | /// - Parameter value: The `Content-Disposition` value. 294 | /// 295 | /// - Returns: The header. 296 | public static func contentDisposition(_ value: String) -> HTTPHeader { 297 | return HTTPHeader(name: "Content-Disposition", value: value) 298 | } 299 | 300 | /// Returns a `Content-Type` header. 301 | /// 302 | /// All Alamofire `ParameterEncoding`s and `ParameterEncoder`s set the `Content-Type` of the request, so it may not be necessary to manually 303 | /// set this value. 304 | /// 305 | /// - Parameter value: The `Content-Type` value. 306 | /// 307 | /// - Returns: The header. 308 | public static func contentType(_ value: String) -> HTTPHeader { 309 | return HTTPHeader(name: "Content-Type", value: value) 310 | } 311 | 312 | /// Returns a `User-Agent` header. 313 | /// 314 | /// - Parameter value: The `User-Agent` value. 315 | /// 316 | /// - Returns: The header. 317 | public static func userAgent(_ value: String) -> HTTPHeader { 318 | return HTTPHeader(name: "User-Agent", value: value) 319 | } 320 | } 321 | 322 | extension Array where Element == HTTPHeader { 323 | /// Case-insensitively finds the index of an `HTTPHeader` with the provided name, if it exists. 324 | func index(of name: String) -> Int? { 325 | let lowercasedName = name.lowercased() 326 | return firstIndex { $0.name.lowercased() == lowercasedName } 327 | } 328 | } 329 | 330 | // MARK: - Defaults 331 | 332 | public extension HTTPHeaders { 333 | /// The default set of `HTTPHeaders` used by Alamofire. Includes `Accept-Encoding`, `Accept-Language`, and 334 | /// `User-Agent`. 335 | static let `default`: HTTPHeaders = [.defaultAcceptEncoding, 336 | .defaultAcceptLanguage, 337 | .defaultUserAgent] 338 | } 339 | 340 | extension HTTPHeader { 341 | /// Returns Alamofire's default `Accept-Encoding` header, appropriate for the encodings supported by particular OS 342 | /// versions. 343 | /// 344 | /// See the [Accept-Encoding HTTP header documentation](https://tools.ietf.org/html/rfc7230#section-4.2.3) . 345 | public static let defaultAcceptEncoding: HTTPHeader = { 346 | let encodings: [String] 347 | if #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) { 348 | encodings = ["br", "gzip", "deflate"] 349 | } else { 350 | encodings = ["gzip", "deflate"] 351 | } 352 | 353 | return .acceptEncoding(encodings.qualityEncoded()) 354 | }() 355 | 356 | /// Returns Alamofire's default `Accept-Language` header, generated by querying `Locale` for the user's 357 | /// `preferredLanguages`. 358 | /// 359 | /// See the [Accept-Language HTTP header documentation](https://tools.ietf.org/html/rfc7231#section-5.3.5). 360 | public static let defaultAcceptLanguage: HTTPHeader = { 361 | .acceptLanguage(Locale.preferredLanguages.prefix(6).qualityEncoded()) 362 | }() 363 | 364 | /// Returns Alamofire's default `User-Agent` header. 365 | /// 366 | /// See the [User-Agent header documentation](https://tools.ietf.org/html/rfc7231#section-5.5.3). 367 | /// 368 | /// Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 13.0.0) Alamofire/5.0.0` 369 | public static let defaultUserAgent: HTTPHeader = { 370 | let userAgent: String = { 371 | if let info = Bundle.main.infoDictionary { 372 | let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown" 373 | let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown" 374 | let appVersion = info["CFBundleShortVersionString"] as? String ?? "Unknown" 375 | let appBuild = info[kCFBundleVersionKey as String] as? String ?? "Unknown" 376 | 377 | let osNameVersion: String = { 378 | let version = ProcessInfo.processInfo.operatingSystemVersion 379 | let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)" 380 | // swiftformat:disable indent 381 | let osName: String = { 382 | #if os(iOS) 383 | return "iOS" 384 | #elseif os(watchOS) 385 | return "watchOS" 386 | #elseif os(tvOS) 387 | return "tvOS" 388 | #elseif os(macOS) 389 | return "macOS" 390 | #elseif os(Linux) 391 | return "Linux" 392 | #else 393 | return "Unknown" 394 | #endif 395 | }() 396 | // swiftformat:enable indent 397 | 398 | return "\(osName) \(versionString)" 399 | }() 400 | 401 | let alamofireVersion = "Alamofire/\(AF.version)" 402 | 403 | return "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)" 404 | } 405 | 406 | return "Alamofire" 407 | }() 408 | 409 | return .userAgent(userAgent) 410 | }() 411 | } 412 | 413 | extension Collection where Element == String { 414 | func qualityEncoded() -> String { 415 | return enumerated().map { index, encoding in 416 | let quality = 1.0 - (Double(index) * 0.1) 417 | return "\(encoding);q=\(quality)" 418 | }.joined(separator: ", ") 419 | } 420 | } 421 | 422 | // MARK: - System Type Extensions 423 | 424 | extension URLRequest { 425 | /// Returns `allHTTPHeaderFields` as `HTTPHeaders`. 426 | public var headers: HTTPHeaders { 427 | get { return allHTTPHeaderFields.map(HTTPHeaders.init) ?? HTTPHeaders() } 428 | set { allHTTPHeaderFields = newValue.dictionary } 429 | } 430 | } 431 | 432 | extension HTTPURLResponse { 433 | /// Returns `allHeaderFields` as `HTTPHeaders`. 434 | public var headers: HTTPHeaders { 435 | return (allHeaderFields as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() 436 | } 437 | } 438 | 439 | public extension URLSessionConfiguration { 440 | /// Returns `httpAdditionalHeaders` as `HTTPHeaders`. 441 | var headers: HTTPHeaders { 442 | get { return (httpAdditionalHeaders as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() } 443 | set { httpAdditionalHeaders = newValue.dictionary } 444 | } 445 | } 446 | -------------------------------------------------------------------------------- /Alamofire-Tutorial.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5F2FBCE92255BD72C9DAFE75 /* Pods_Alamofire_Tutorial.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB32E20E345C99D7EAA3A644 /* Pods_Alamofire_Tutorial.framework */; }; 11 | DC9E3F8B23E03283006F834B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9E3F8A23E03283006F834B /* AppDelegate.swift */; }; 12 | DC9E3F8D23E03283006F834B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9E3F8C23E03283006F834B /* SceneDelegate.swift */; }; 13 | DC9E3F8F23E03283006F834B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9E3F8E23E03283006F834B /* ViewController.swift */; }; 14 | DC9E3F9223E03283006F834B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC9E3F9023E03283006F834B /* Main.storyboard */; }; 15 | DC9E3F9423E03284006F834B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC9E3F9323E03284006F834B /* Assets.xcassets */; }; 16 | DC9E3F9723E03284006F834B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC9E3F9523E03284006F834B /* LaunchScreen.storyboard */; }; 17 | DC9E3F9F23E03372006F834B /* Service.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9E3F9E23E03372006F834B /* Service.swift */; }; 18 | DC9E3FA123E034F1006F834B /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9E3FA023E034F1006F834B /* Country.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 56884BA649BB9CA9BE509FFC /* Pods-Alamofire-Tutorial.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Alamofire-Tutorial.debug.xcconfig"; path = "Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial.debug.xcconfig"; sourceTree = ""; }; 23 | DC9E3F8723E03283006F834B /* Alamofire-Tutorial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Alamofire-Tutorial.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | DC9E3F8A23E03283006F834B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 25 | DC9E3F8C23E03283006F834B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 26 | DC9E3F8E23E03283006F834B /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 27 | DC9E3F9123E03283006F834B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | DC9E3F9323E03284006F834B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29 | DC9E3F9623E03284006F834B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 30 | DC9E3F9823E03284006F834B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | DC9E3F9E23E03372006F834B /* Service.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Service.swift; sourceTree = ""; }; 32 | DC9E3FA023E034F1006F834B /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; 33 | EB32E20E345C99D7EAA3A644 /* Pods_Alamofire_Tutorial.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Alamofire_Tutorial.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | F2273D3E2D2C19527578D246 /* Pods-Alamofire-Tutorial.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Alamofire-Tutorial.release.xcconfig"; path = "Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial.release.xcconfig"; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | DC9E3F8423E03283006F834B /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | 5F2FBCE92255BD72C9DAFE75 /* Pods_Alamofire_Tutorial.framework in Frameworks */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | A5DAC9E788CA4A9BA3DD8D73 /* Frameworks */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | EB32E20E345C99D7EAA3A644 /* Pods_Alamofire_Tutorial.framework */, 53 | ); 54 | name = Frameworks; 55 | sourceTree = ""; 56 | }; 57 | DA1FB3A214DF08DA8F59FCCE /* Pods */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 56884BA649BB9CA9BE509FFC /* Pods-Alamofire-Tutorial.debug.xcconfig */, 61 | F2273D3E2D2C19527578D246 /* Pods-Alamofire-Tutorial.release.xcconfig */, 62 | ); 63 | path = Pods; 64 | sourceTree = ""; 65 | }; 66 | DC9E3F7E23E03283006F834B = { 67 | isa = PBXGroup; 68 | children = ( 69 | DC9E3F8923E03283006F834B /* Alamofire-Tutorial */, 70 | DC9E3F8823E03283006F834B /* Products */, 71 | DA1FB3A214DF08DA8F59FCCE /* Pods */, 72 | A5DAC9E788CA4A9BA3DD8D73 /* Frameworks */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | DC9E3F8823E03283006F834B /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | DC9E3F8723E03283006F834B /* Alamofire-Tutorial.app */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | DC9E3F8923E03283006F834B /* Alamofire-Tutorial */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | DC9E3F8A23E03283006F834B /* AppDelegate.swift */, 88 | DC9E3F8C23E03283006F834B /* SceneDelegate.swift */, 89 | DC9E3F8E23E03283006F834B /* ViewController.swift */, 90 | DC9E3F9E23E03372006F834B /* Service.swift */, 91 | DC9E3FA023E034F1006F834B /* Country.swift */, 92 | DC9E3F9023E03283006F834B /* Main.storyboard */, 93 | DC9E3F9323E03284006F834B /* Assets.xcassets */, 94 | DC9E3F9523E03284006F834B /* LaunchScreen.storyboard */, 95 | DC9E3F9823E03284006F834B /* Info.plist */, 96 | ); 97 | path = "Alamofire-Tutorial"; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | DC9E3F8623E03283006F834B /* Alamofire-Tutorial */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = DC9E3F9B23E03284006F834B /* Build configuration list for PBXNativeTarget "Alamofire-Tutorial" */; 106 | buildPhases = ( 107 | 784458AE54187AE738E3A5F8 /* [CP] Check Pods Manifest.lock */, 108 | DC9E3F8323E03283006F834B /* Sources */, 109 | DC9E3F8423E03283006F834B /* Frameworks */, 110 | DC9E3F8523E03283006F834B /* Resources */, 111 | BE2153FBC6BB9BF336DE59CE /* [CP] Embed Pods Frameworks */, 112 | ); 113 | buildRules = ( 114 | ); 115 | dependencies = ( 116 | ); 117 | name = "Alamofire-Tutorial"; 118 | productName = "Alamofire-Tutorial"; 119 | productReference = DC9E3F8723E03283006F834B /* Alamofire-Tutorial.app */; 120 | productType = "com.apple.product-type.application"; 121 | }; 122 | /* End PBXNativeTarget section */ 123 | 124 | /* Begin PBXProject section */ 125 | DC9E3F7F23E03283006F834B /* Project object */ = { 126 | isa = PBXProject; 127 | attributes = { 128 | LastSwiftUpdateCheck = 1100; 129 | LastUpgradeCheck = 1100; 130 | ORGANIZATIONNAME = "Aman Aggarwal"; 131 | TargetAttributes = { 132 | DC9E3F8623E03283006F834B = { 133 | CreatedOnToolsVersion = 11.0; 134 | }; 135 | }; 136 | }; 137 | buildConfigurationList = DC9E3F8223E03283006F834B /* Build configuration list for PBXProject "Alamofire-Tutorial" */; 138 | compatibilityVersion = "Xcode 9.3"; 139 | developmentRegion = en; 140 | hasScannedForEncodings = 0; 141 | knownRegions = ( 142 | en, 143 | Base, 144 | ); 145 | mainGroup = DC9E3F7E23E03283006F834B; 146 | productRefGroup = DC9E3F8823E03283006F834B /* Products */; 147 | projectDirPath = ""; 148 | projectRoot = ""; 149 | targets = ( 150 | DC9E3F8623E03283006F834B /* Alamofire-Tutorial */, 151 | ); 152 | }; 153 | /* End PBXProject section */ 154 | 155 | /* Begin PBXResourcesBuildPhase section */ 156 | DC9E3F8523E03283006F834B /* Resources */ = { 157 | isa = PBXResourcesBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | DC9E3F9723E03284006F834B /* LaunchScreen.storyboard in Resources */, 161 | DC9E3F9423E03284006F834B /* Assets.xcassets in Resources */, 162 | DC9E3F9223E03283006F834B /* Main.storyboard in Resources */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXResourcesBuildPhase section */ 167 | 168 | /* Begin PBXShellScriptBuildPhase section */ 169 | 784458AE54187AE738E3A5F8 /* [CP] Check Pods Manifest.lock */ = { 170 | isa = PBXShellScriptBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | ); 174 | inputFileListPaths = ( 175 | ); 176 | inputPaths = ( 177 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 178 | "${PODS_ROOT}/Manifest.lock", 179 | ); 180 | name = "[CP] Check Pods Manifest.lock"; 181 | outputFileListPaths = ( 182 | ); 183 | outputPaths = ( 184 | "$(DERIVED_FILE_DIR)/Pods-Alamofire-Tutorial-checkManifestLockResult.txt", 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | shellPath = /bin/sh; 188 | 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"; 189 | showEnvVarsInLog = 0; 190 | }; 191 | BE2153FBC6BB9BF336DE59CE /* [CP] Embed Pods Frameworks */ = { 192 | isa = PBXShellScriptBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | ); 196 | inputFileListPaths = ( 197 | "${PODS_ROOT}/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-${CONFIGURATION}-input-files.xcfilelist", 198 | ); 199 | name = "[CP] Embed Pods Frameworks"; 200 | outputFileListPaths = ( 201 | "${PODS_ROOT}/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks-${CONFIGURATION}-output-files.xcfilelist", 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | shellPath = /bin/sh; 205 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Alamofire-Tutorial/Pods-Alamofire-Tutorial-frameworks.sh\"\n"; 206 | showEnvVarsInLog = 0; 207 | }; 208 | /* End PBXShellScriptBuildPhase section */ 209 | 210 | /* Begin PBXSourcesBuildPhase section */ 211 | DC9E3F8323E03283006F834B /* Sources */ = { 212 | isa = PBXSourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | DC9E3F8F23E03283006F834B /* ViewController.swift in Sources */, 216 | DC9E3F9F23E03372006F834B /* Service.swift in Sources */, 217 | DC9E3F8B23E03283006F834B /* AppDelegate.swift in Sources */, 218 | DC9E3FA123E034F1006F834B /* Country.swift in Sources */, 219 | DC9E3F8D23E03283006F834B /* SceneDelegate.swift in Sources */, 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | /* End PBXSourcesBuildPhase section */ 224 | 225 | /* Begin PBXVariantGroup section */ 226 | DC9E3F9023E03283006F834B /* Main.storyboard */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | DC9E3F9123E03283006F834B /* Base */, 230 | ); 231 | name = Main.storyboard; 232 | sourceTree = ""; 233 | }; 234 | DC9E3F9523E03284006F834B /* LaunchScreen.storyboard */ = { 235 | isa = PBXVariantGroup; 236 | children = ( 237 | DC9E3F9623E03284006F834B /* Base */, 238 | ); 239 | name = LaunchScreen.storyboard; 240 | sourceTree = ""; 241 | }; 242 | /* End PBXVariantGroup section */ 243 | 244 | /* Begin XCBuildConfiguration section */ 245 | DC9E3F9923E03284006F834B /* Debug */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ALWAYS_SEARCH_USER_PATHS = NO; 249 | CLANG_ANALYZER_NONNULL = YES; 250 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 251 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 252 | CLANG_CXX_LIBRARY = "libc++"; 253 | CLANG_ENABLE_MODULES = YES; 254 | CLANG_ENABLE_OBJC_ARC = YES; 255 | CLANG_ENABLE_OBJC_WEAK = YES; 256 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 257 | CLANG_WARN_BOOL_CONVERSION = YES; 258 | CLANG_WARN_COMMA = YES; 259 | CLANG_WARN_CONSTANT_CONVERSION = YES; 260 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 262 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 263 | CLANG_WARN_EMPTY_BODY = YES; 264 | CLANG_WARN_ENUM_CONVERSION = YES; 265 | CLANG_WARN_INFINITE_RECURSION = YES; 266 | CLANG_WARN_INT_CONVERSION = YES; 267 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 268 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 269 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 270 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 271 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 272 | CLANG_WARN_STRICT_PROTOTYPES = YES; 273 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 274 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 275 | CLANG_WARN_UNREACHABLE_CODE = YES; 276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 277 | COPY_PHASE_STRIP = NO; 278 | DEBUG_INFORMATION_FORMAT = dwarf; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | ENABLE_TESTABILITY = YES; 281 | GCC_C_LANGUAGE_STANDARD = gnu11; 282 | GCC_DYNAMIC_NO_PIC = NO; 283 | GCC_NO_COMMON_BLOCKS = YES; 284 | GCC_OPTIMIZATION_LEVEL = 0; 285 | GCC_PREPROCESSOR_DEFINITIONS = ( 286 | "DEBUG=1", 287 | "$(inherited)", 288 | ); 289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 291 | GCC_WARN_UNDECLARED_SELECTOR = YES; 292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 293 | GCC_WARN_UNUSED_FUNCTION = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 296 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 297 | MTL_FAST_MATH = YES; 298 | ONLY_ACTIVE_ARCH = YES; 299 | SDKROOT = iphoneos; 300 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 301 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 302 | }; 303 | name = Debug; 304 | }; 305 | DC9E3F9A23E03284006F834B /* Release */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 311 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 312 | CLANG_CXX_LIBRARY = "libc++"; 313 | CLANG_ENABLE_MODULES = YES; 314 | CLANG_ENABLE_OBJC_ARC = YES; 315 | CLANG_ENABLE_OBJC_WEAK = YES; 316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 317 | CLANG_WARN_BOOL_CONVERSION = YES; 318 | CLANG_WARN_COMMA = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 323 | CLANG_WARN_EMPTY_BODY = YES; 324 | CLANG_WARN_ENUM_CONVERSION = YES; 325 | CLANG_WARN_INFINITE_RECURSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 328 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 329 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 331 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 332 | CLANG_WARN_STRICT_PROTOTYPES = YES; 333 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 334 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 335 | CLANG_WARN_UNREACHABLE_CODE = YES; 336 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 337 | COPY_PHASE_STRIP = NO; 338 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 339 | ENABLE_NS_ASSERTIONS = NO; 340 | ENABLE_STRICT_OBJC_MSGSEND = YES; 341 | GCC_C_LANGUAGE_STANDARD = gnu11; 342 | GCC_NO_COMMON_BLOCKS = YES; 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 350 | MTL_ENABLE_DEBUG_INFO = NO; 351 | MTL_FAST_MATH = YES; 352 | SDKROOT = iphoneos; 353 | SWIFT_COMPILATION_MODE = wholemodule; 354 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 355 | VALIDATE_PRODUCT = YES; 356 | }; 357 | name = Release; 358 | }; 359 | DC9E3F9C23E03284006F834B /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | baseConfigurationReference = 56884BA649BB9CA9BE509FFC /* Pods-Alamofire-Tutorial.debug.xcconfig */; 362 | buildSettings = { 363 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 364 | CODE_SIGN_STYLE = Automatic; 365 | INFOPLIST_FILE = "Alamofire-Tutorial/Info.plist"; 366 | LD_RUNPATH_SEARCH_PATHS = ( 367 | "$(inherited)", 368 | "@executable_path/Frameworks", 369 | ); 370 | PRODUCT_BUNDLE_IDENTIFIER = "com.iostutorialjunction.Alamofire-Tutorial"; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | SWIFT_VERSION = 5.0; 373 | TARGETED_DEVICE_FAMILY = "1,2"; 374 | }; 375 | name = Debug; 376 | }; 377 | DC9E3F9D23E03284006F834B /* Release */ = { 378 | isa = XCBuildConfiguration; 379 | baseConfigurationReference = F2273D3E2D2C19527578D246 /* Pods-Alamofire-Tutorial.release.xcconfig */; 380 | buildSettings = { 381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 382 | CODE_SIGN_STYLE = Automatic; 383 | INFOPLIST_FILE = "Alamofire-Tutorial/Info.plist"; 384 | LD_RUNPATH_SEARCH_PATHS = ( 385 | "$(inherited)", 386 | "@executable_path/Frameworks", 387 | ); 388 | PRODUCT_BUNDLE_IDENTIFIER = "com.iostutorialjunction.Alamofire-Tutorial"; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | SWIFT_VERSION = 5.0; 391 | TARGETED_DEVICE_FAMILY = "1,2"; 392 | }; 393 | name = Release; 394 | }; 395 | /* End XCBuildConfiguration section */ 396 | 397 | /* Begin XCConfigurationList section */ 398 | DC9E3F8223E03283006F834B /* Build configuration list for PBXProject "Alamofire-Tutorial" */ = { 399 | isa = XCConfigurationList; 400 | buildConfigurations = ( 401 | DC9E3F9923E03284006F834B /* Debug */, 402 | DC9E3F9A23E03284006F834B /* Release */, 403 | ); 404 | defaultConfigurationIsVisible = 0; 405 | defaultConfigurationName = Release; 406 | }; 407 | DC9E3F9B23E03284006F834B /* Build configuration list for PBXNativeTarget "Alamofire-Tutorial" */ = { 408 | isa = XCConfigurationList; 409 | buildConfigurations = ( 410 | DC9E3F9C23E03284006F834B /* Debug */, 411 | DC9E3F9D23E03284006F834B /* Release */, 412 | ); 413 | defaultConfigurationIsVisible = 0; 414 | defaultConfigurationName = Release; 415 | }; 416 | /* End XCConfigurationList section */ 417 | }; 418 | rootObject = DC9E3F7F23E03283006F834B /* Project object */; 419 | } 420 | --------------------------------------------------------------------------------