├── .github ├── CODEOWNERS └── workflows │ └── swift.yml ├── .gitignore ├── .swift-version ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── .travis.yml ├── CHANGELOG.md ├── Example ├── Hyperconnectivity.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Hyperconnectivity-Example.xcscheme ├── Hyperconnectivity.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Hyperconnectivity │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── UIColor.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── Hyperconnectivity.podspec.json │ ├── Manifest.lock │ ├── OHHTTPStubs │ │ ├── LICENSE │ │ ├── README.md │ │ └── Sources │ │ │ ├── OHHTTPStubs │ │ │ ├── HTTPStubs+NSURLSessionConfiguration.m │ │ │ ├── HTTPStubs.m │ │ │ ├── HTTPStubsMethodSwizzling.h │ │ │ ├── HTTPStubsMethodSwizzling.m │ │ │ ├── HTTPStubsPathHelpers.m │ │ │ ├── HTTPStubsResponse+JSON.m │ │ │ ├── HTTPStubsResponse.m │ │ │ ├── NSURLRequest+HTTPBodyTesting.m │ │ │ └── include │ │ │ │ ├── Compatibility.h │ │ │ │ ├── HTTPStubs.h │ │ │ │ ├── HTTPStubsPathHelpers.h │ │ │ │ ├── HTTPStubsResponse+JSON.h │ │ │ │ ├── HTTPStubsResponse.h │ │ │ │ └── NSURLRequest+HTTPBodyTesting.h │ │ │ └── OHHTTPStubsSwift │ │ │ └── OHHTTPStubsSwift.swift │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Hyperconnectivity.xcscheme │ └── Target Support Files │ │ ├── Hyperconnectivity │ │ ├── Hyperconnectivity-Info.plist │ │ ├── Hyperconnectivity-dummy.m │ │ ├── Hyperconnectivity-prefix.pch │ │ ├── Hyperconnectivity-umbrella.h │ │ ├── Hyperconnectivity.debug.xcconfig │ │ ├── Hyperconnectivity.modulemap │ │ └── Hyperconnectivity.release.xcconfig │ │ ├── OHHTTPStubs │ │ ├── OHHTTPStubs-Info.plist │ │ ├── OHHTTPStubs-dummy.m │ │ ├── OHHTTPStubs-prefix.pch │ │ ├── OHHTTPStubs-umbrella.h │ │ ├── OHHTTPStubs.debug.xcconfig │ │ ├── OHHTTPStubs.modulemap │ │ └── OHHTTPStubs.release.xcconfig │ │ ├── Pods-Hyperconnectivity_Example │ │ ├── Pods-Hyperconnectivity_Example-Info.plist │ │ ├── Pods-Hyperconnectivity_Example-acknowledgements.markdown │ │ ├── Pods-Hyperconnectivity_Example-acknowledgements.plist │ │ ├── Pods-Hyperconnectivity_Example-dummy.m │ │ ├── Pods-Hyperconnectivity_Example-frameworks.sh │ │ ├── Pods-Hyperconnectivity_Example-umbrella.h │ │ ├── Pods-Hyperconnectivity_Example.debug.xcconfig │ │ ├── Pods-Hyperconnectivity_Example.modulemap │ │ └── Pods-Hyperconnectivity_Example.release.xcconfig │ │ └── Pods-Hyperconnectivity_Tests │ │ ├── Pods-Hyperconnectivity_Tests-Info.plist │ │ ├── Pods-Hyperconnectivity_Tests-acknowledgements.markdown │ │ ├── Pods-Hyperconnectivity_Tests-acknowledgements.plist │ │ ├── Pods-Hyperconnectivity_Tests-dummy.m │ │ ├── Pods-Hyperconnectivity_Tests-frameworks.sh │ │ ├── Pods-Hyperconnectivity_Tests-umbrella.h │ │ ├── Pods-Hyperconnectivity_Tests.debug.xcconfig │ │ ├── Pods-Hyperconnectivity_Tests.modulemap │ │ └── Pods-Hyperconnectivity_Tests.release.xcconfig └── Tests │ ├── ConnectionTests.swift │ ├── ConnectivityPublisherTests.swift │ ├── ConnectivityStateTests.swift │ ├── ConnectivitySubscriptionTests.swift │ ├── Info.plist │ ├── MockConnectivity.swift │ ├── MockPath.swift │ ├── NonCachingURLSessionConfigurationFactoryTests.swift │ ├── PercentageTests.swift │ ├── ReachabilityPublisherTests.swift │ ├── ResponseContainsStringValidatorTests.swift │ ├── ResponseRegExValidatorTests.swift │ ├── ResponseStringEqualityValidatorTests.swift │ ├── failure-response.html │ ├── string-contains-response.html │ └── string-equality-response.html ├── Hyperconnectivity.podspec ├── Hyperconnectivity ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── Combine │ ├── ConnectivityPublisher.swift │ ├── ConnectivitySubscription.swift │ ├── NonCachingURLSessionConfigurationFactory.swift │ ├── Publishers.swift │ ├── ReachabilityPublisher.swift │ └── ReachabilitySubscription.swift │ ├── Core │ └── Hyperconnectivity.swift │ ├── Model │ ├── Configuration.swift │ ├── Connection.swift │ ├── ConnectivityResult.swift │ ├── ConnectivityState.swift │ ├── Notification.Name.swift │ ├── Percentage.swift │ └── ReachabilityResult.swift │ └── Response Validation │ ├── ResponseContainsStringValidator.swift │ ├── ResponseRegExValidator.swift │ ├── ResponseStringEqualityValidator.swift │ ├── ResponseStringValidator.swift │ └── ResponseValidator.swift ├── LICENSE ├── Package.resolved ├── Package.swift ├── README.md ├── _Pods.xcodeproj └── docs └── images ├── comparison-with-connectivity.png ├── hyperconnectivity-banner.png └── hyperconnectivity-logo.png /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @rwbutler 2 | -------------------------------------------------------------------------------- /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Swift project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift 3 | 4 | name: Swift 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: swift build -v 21 | - name: Run tests 22 | run: swift test -v 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.graffle 22 | *.afdesign 23 | 24 | # Bundler 25 | .bundle 26 | 27 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 28 | # Carthage/Checkouts 29 | 30 | Carthage/Build 31 | .build 32 | 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 36 | # 37 | # Note: if you ignore the Pods directory, make sure to uncomment 38 | # `pod install` in .travis.yml 39 | # 40 | # Pods/ 41 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 5.0 -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode13.2 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild clean build test -enableCodeCoverage YES -workspace Example/Hyperconnectivity.xcworkspace -scheme Hyperconnectivity-Example -destination "platform=iOS Simulator,name=iPhone 13 Pro" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [1.2.0] - 2023-02-21 8 | ### Changed 9 | - `Configuration` objects may now be instantiated with either `URL` objects or `URLRequest` objects by using the relevant initializer. 10 | 11 | ## [1.1.1] - 2022-03-20 12 | ### Changed 13 | - Merged [PR #4](https://github.com/rwbutler/Hyperconnectivity/pull/4) to ensure that cached results are never used as part of connectivity checks. 14 | - Adjusted tests to pass both locally as well as on Travis CI. 15 | 16 | ## [1.1.0] - 2020-08-23 17 | ### Added 18 | - Compatibility with macOS, watchOS and tvOS via Swift Package Manager. 19 | 20 | ## [1.0.0] - 2020-05-17 21 | ### Added 22 | - Increased unit test coverage to 90%. 23 | 24 | ## [0.2.0] - 2020-05-08 25 | ### Added 26 | - Support for Carthage and Swift Package Manager. 27 | 28 | ## [0.1.0] - 2020-05-08 29 | ### Added 30 | - Initial release. 31 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity.xcodeproj/xcshareddata/xcschemes/Hyperconnectivity-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 53 | 54 | 55 | 56 | 62 | 63 | 64 | 65 | 67 | 73 | 74 | 75 | 76 | 77 | 87 | 89 | 95 | 96 | 97 | 98 | 104 | 106 | 112 | 113 | 114 | 115 | 117 | 118 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 05/07/2020. 6 | // Copyright (c) 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/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 | 27 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/Images.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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/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 | APPL 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/UIColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColorExtension.swift 3 | // Hyperconnectivity_Example 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UIColor { 13 | static let darkGreen = UIColor(red: 0, green: 108 / 255, blue: 54 / 255, alpha: 1.0) 14 | } 15 | -------------------------------------------------------------------------------- /Example/Hyperconnectivity/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 05/07/2020. 6 | // Copyright (c) 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Combine 10 | import UIKit 11 | import Hyperconnectivity 12 | 13 | class ViewController: UIViewController { 14 | 15 | // MARK: Outlets 16 | @IBOutlet var activityIndicator: UIActivityIndicatorView! 17 | @IBOutlet var notifierButton: UIButton! 18 | @IBOutlet var statusLabel: UILabel! 19 | 20 | // MARK: Status 21 | private var cancellable: AnyCancellable? 22 | fileprivate var isCheckingConnectivity: Bool = false 23 | } 24 | 25 | extension ViewController { 26 | @IBAction func notifierButtonTapped(_: UIButton) { 27 | isCheckingConnectivity ? stopConnectivityChecks() : startConnectivityChecks() 28 | } 29 | } 30 | 31 | private extension ViewController { 32 | func startConnectivityChecks() { 33 | activityIndicator.startAnimating() 34 | cancellable = Hyperconnectivity.Publisher() 35 | .receive(on: DispatchQueue.main) 36 | .eraseToAnyPublisher() 37 | .sink(receiveCompletion: { [weak self] _ in 38 | self?.stopConnectivityChecks() 39 | }, receiveValue: { [weak self] connectivityResult in 40 | self?.updateConnectionStatus(connectivityResult) 41 | }) 42 | isCheckingConnectivity = true 43 | updateNotifierButton(isCheckingConnectivity: isCheckingConnectivity) 44 | } 45 | 46 | func stopConnectivityChecks() { 47 | cancellable?.cancel() 48 | activityIndicator.stopAnimating() 49 | isCheckingConnectivity = false 50 | updateNotifierButton(isCheckingConnectivity: isCheckingConnectivity) 51 | } 52 | 53 | func updateConnectionStatus(_ result: ConnectivityResult) { 54 | statusLabel.textColor = result.isConnected ? .darkGreen : .red 55 | statusLabel.text = result.state.description 56 | } 57 | 58 | func updateNotifierButton(isCheckingConnectivity: Bool) { 59 | let buttonText = isCheckingConnectivity ? "Stop notifier" : "Start notifier" 60 | let buttonTextColor: UIColor = isCheckingConnectivity ? .red : .darkGreen 61 | notifierButton.setTitle(buttonText, for: .normal) 62 | notifierButton.setTitleColor(buttonTextColor, for: .normal) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'Hyperconnectivity_Example' do 4 | pod 'Hyperconnectivity', :path => '../' 5 | 6 | target 'Hyperconnectivity_Tests' do 7 | inherit! :search_paths 8 | pod 'OHHTTPStubs/Swift' 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Hyperconnectivity (1.1.1) 3 | - OHHTTPStubs/Core (9.1.0) 4 | - OHHTTPStubs/Default (9.1.0): 5 | - OHHTTPStubs/Core 6 | - OHHTTPStubs/JSON 7 | - OHHTTPStubs/NSURLSession 8 | - OHHTTPStubs/OHPathHelpers 9 | - OHHTTPStubs/JSON (9.1.0): 10 | - OHHTTPStubs/Core 11 | - OHHTTPStubs/NSURLSession (9.1.0): 12 | - OHHTTPStubs/Core 13 | - OHHTTPStubs/OHPathHelpers (9.1.0) 14 | - OHHTTPStubs/Swift (9.1.0): 15 | - OHHTTPStubs/Default 16 | 17 | DEPENDENCIES: 18 | - Hyperconnectivity (from `../`) 19 | - OHHTTPStubs/Swift 20 | 21 | SPEC REPOS: 22 | trunk: 23 | - OHHTTPStubs 24 | 25 | EXTERNAL SOURCES: 26 | Hyperconnectivity: 27 | :path: "../" 28 | 29 | SPEC CHECKSUMS: 30 | Hyperconnectivity: 8217ab645a07bd808623bc6363ca47e792415901 31 | OHHTTPStubs: 90eac6d8f2c18317baeca36698523dc67c513831 32 | 33 | PODFILE CHECKSUM: c0022d9b2bf93345388e8d49b7dbb6ff97498bc5 34 | 35 | COCOAPODS: 1.11.3 36 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/Hyperconnectivity.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Hyperconnectivity", 3 | "version": "1.1.1", 4 | "swift_versions": "5.0", 5 | "summary": "Modern replacement for Apple's Reachability written in Swift and made elegant using Combine", 6 | "description": "Hyperconnectivity provides Internet connectivity and captive portal detection in Swift using Combine.", 7 | "homepage": "https://github.com/rwbutler/Hyperconnectivity", 8 | "license": { 9 | "type": "MIT", 10 | "file": "LICENSE" 11 | }, 12 | "authors": { 13 | "Ross Butler": "github@rwbutler.com" 14 | }, 15 | "source": { 16 | "git": "https://github.com/rwbutler/Hyperconnectivity.git", 17 | "tag": "1.1.1" 18 | }, 19 | "social_media_url": "https://twitter.com/ross_w_butler", 20 | "platforms": { 21 | "ios": "13.0" 22 | }, 23 | "frameworks": [ 24 | "Combine", 25 | "Network" 26 | ], 27 | "source_files": "Hyperconnectivity/Classes/**/*", 28 | "swift_version": "5.0" 29 | } 30 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Hyperconnectivity (1.1.1) 3 | - OHHTTPStubs/Core (9.1.0) 4 | - OHHTTPStubs/Default (9.1.0): 5 | - OHHTTPStubs/Core 6 | - OHHTTPStubs/JSON 7 | - OHHTTPStubs/NSURLSession 8 | - OHHTTPStubs/OHPathHelpers 9 | - OHHTTPStubs/JSON (9.1.0): 10 | - OHHTTPStubs/Core 11 | - OHHTTPStubs/NSURLSession (9.1.0): 12 | - OHHTTPStubs/Core 13 | - OHHTTPStubs/OHPathHelpers (9.1.0) 14 | - OHHTTPStubs/Swift (9.1.0): 15 | - OHHTTPStubs/Default 16 | 17 | DEPENDENCIES: 18 | - Hyperconnectivity (from `../`) 19 | - OHHTTPStubs/Swift 20 | 21 | SPEC REPOS: 22 | trunk: 23 | - OHHTTPStubs 24 | 25 | EXTERNAL SOURCES: 26 | Hyperconnectivity: 27 | :path: "../" 28 | 29 | SPEC CHECKSUMS: 30 | Hyperconnectivity: 8217ab645a07bd808623bc6363ca47e792415901 31 | OHHTTPStubs: 90eac6d8f2c18317baeca36698523dc67c513831 32 | 33 | PODFILE CHECKSUM: c0022d9b2bf93345388e8d49b7dbb6ff97498bc5 34 | 35 | COCOAPODS: 1.11.3 36 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/LICENSE: -------------------------------------------------------------------------------- 1 | - MIT LICENSE - 2 | 3 | Copyright (c) 2012 Olivier Halligon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubs+NSURLSessionConfiguration.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | #import 26 | 27 | #if defined(__IPHONE_7_0) || defined(__MAC_10_9) 28 | #import "HTTPStubs.h" 29 | #import "HTTPStubsMethodSwizzling.h" 30 | 31 | ////////////////////////////////////////////////////////////////////////////////////////////////// 32 | 33 | /** 34 | * This helper is used to swizzle NSURLSessionConfiguration constructor methods 35 | * defaultSessionConfiguration and ephemeralSessionConfiguration to insert the private 36 | * HTTPStubsProtocol into their protocolClasses array so that OHHTTPStubs is automagically 37 | * supported when you create a new NSURLSession based on one of there configurations. 38 | */ 39 | 40 | typedef NSURLSessionConfiguration*(*SessionConfigConstructor)(id,SEL); 41 | static SessionConfigConstructor orig_defaultSessionConfiguration; 42 | static SessionConfigConstructor orig_ephemeralSessionConfiguration; 43 | 44 | static NSURLSessionConfiguration* HTTPStubs_defaultSessionConfiguration(id self, SEL _cmd) 45 | { 46 | NSURLSessionConfiguration* config = orig_defaultSessionConfiguration(self,_cmd); // call original method 47 | [HTTPStubs setEnabled:YES forSessionConfiguration:config]; //OHHTTPStubsAddProtocolClassToNSURLSessionConfiguration(config); 48 | return config; 49 | } 50 | 51 | static NSURLSessionConfiguration* HTTPStubs_ephemeralSessionConfiguration(id self, SEL _cmd) 52 | { 53 | NSURLSessionConfiguration* config = orig_ephemeralSessionConfiguration(self,_cmd); // call original method 54 | [HTTPStubs setEnabled:YES forSessionConfiguration:config]; //OHHTTPStubsAddProtocolClassToNSURLSessionConfiguration(config); 55 | return config; 56 | } 57 | 58 | @interface NSURLSessionConfiguration(HTTPStubsSupport) @end 59 | 60 | @implementation NSURLSessionConfiguration(HTTPStubsSupport) 61 | 62 | +(void)load 63 | { 64 | orig_defaultSessionConfiguration = (SessionConfigConstructor)HTTPStubsReplaceMethod(@selector(defaultSessionConfiguration), 65 | (IMP)HTTPStubs_defaultSessionConfiguration, 66 | [NSURLSessionConfiguration class], 67 | YES); 68 | orig_ephemeralSessionConfiguration = (SessionConfigConstructor)HTTPStubsReplaceMethod(@selector(ephemeralSessionConfiguration), 69 | (IMP)HTTPStubs_ephemeralSessionConfiguration, 70 | [NSURLSessionConfiguration class], 71 | YES); 72 | } 73 | 74 | @end 75 | 76 | #endif /* __IPHONE_7_0 || __MAC_10_9 */ 77 | 78 | 79 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubsMethodSwizzling.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon, 2016 Sebastian Hagedorn 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | #pragma mark - Imports 27 | 28 | #import 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | #pragma mark - Method Swizzling Helpers 32 | 33 | /** 34 | * Replaces the selector's associated method implementation with the 35 | * given implementation (or adds it, if there was no existing one). 36 | * 37 | * @param selector The selector entry in the dispatch table. 38 | * @param newImpl The implementation that will be associated with 39 | * the given selector. 40 | * @param affectedClass The class whose dispatch table will be altered. 41 | * @param isClassMethod Set to YES if the selector denotes a class 42 | * method, or NO if it is an instance method. 43 | * @return The previous implementation associated with 44 | * the swizzled selector. You should store the 45 | * implementation and call it when overwriting 46 | * the selector. 47 | */ 48 | __attribute__((warn_unused_result)) IMP HTTPStubsReplaceMethod(SEL selector, 49 | IMP newImpl, 50 | Class affectedClass, 51 | BOOL isClassMethod); 52 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubsMethodSwizzling.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon, 2016 Sebastian Hagedorn 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | #pragma mark - Imports 27 | 28 | #import "HTTPStubsMethodSwizzling.h" 29 | 30 | ////////////////////////////////////////////////////////////////////////////////////////////////// 31 | #pragma mark - Method Swizzling Helpers 32 | 33 | IMP HTTPStubsReplaceMethod(SEL selector, 34 | IMP newImpl, 35 | Class affectedClass, 36 | BOOL isClassMethod) 37 | { 38 | Method origMethod = isClassMethod ? class_getClassMethod(affectedClass, selector) : class_getInstanceMethod(affectedClass, selector); 39 | IMP origImpl = method_getImplementation(origMethod); 40 | 41 | if (!class_addMethod(isClassMethod ? object_getClass(affectedClass) : affectedClass, selector, newImpl, method_getTypeEncoding(origMethod))) 42 | { 43 | method_setImplementation(origMethod, newImpl); 44 | } 45 | 46 | return origImpl; 47 | } 48 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubsPathHelpers.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "HTTPStubsPathHelpers.h" 27 | 28 | NSString* __nullable OHPathForFile(NSString* fileName, Class inBundleForClass) 29 | { 30 | NSBundle* bundle = [NSBundle bundleForClass:inBundleForClass]; 31 | return OHPathForFileInBundle(fileName, bundle); 32 | } 33 | 34 | NSString* __nullable OHPathForFileInBundle(NSString* fileName, NSBundle* bundle) 35 | { 36 | return [bundle pathForResource:[fileName stringByDeletingPathExtension] 37 | ofType:[fileName pathExtension]]; 38 | } 39 | 40 | NSString* __nullable OHPathForFileInDocumentsDir(NSString* fileName) 41 | { 42 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 43 | NSString *basePath = (paths.count > 0) ? paths[0] : nil; 44 | return [basePath stringByAppendingPathComponent:fileName]; 45 | } 46 | 47 | NSBundle* __nullable OHResourceBundle(NSString* bundleBasename, Class inBundleForClass) 48 | { 49 | NSBundle* classBundle = [NSBundle bundleForClass:inBundleForClass]; 50 | return [NSBundle bundleWithPath:[classBundle pathForResource:bundleBasename 51 | ofType:@"bundle"]]; 52 | } 53 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubsResponse+JSON.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "HTTPStubsResponse+JSON.h" 27 | 28 | @implementation HTTPStubsResponse (JSON) 29 | 30 | /*! @name Building a response from JSON objects */ 31 | 32 | + (instancetype)responseWithJSONObject:(id)jsonObject 33 | statusCode:(int)statusCode 34 | headers:(nullable NSDictionary *)httpHeaders 35 | { 36 | if (!httpHeaders[@"Content-Type"]) 37 | { 38 | NSMutableDictionary* mutableHeaders = [NSMutableDictionary dictionaryWithDictionary:httpHeaders]; 39 | mutableHeaders[@"Content-Type"] = @"application/json"; 40 | httpHeaders = [NSDictionary dictionaryWithDictionary:mutableHeaders]; // make immutable again 41 | } 42 | 43 | return [self responseWithData:[NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:nil] 44 | statusCode:statusCode 45 | headers:httpHeaders]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/HTTPStubsResponse.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | #if ! __has_feature(objc_arc) 26 | #error This file is expected to be compiled with ARC turned ON 27 | #endif 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | #pragma mark - Imports 31 | 32 | #import "HTTPStubsResponse.h" 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | #pragma mark - Defines & Constants 36 | const double OHHTTPStubsDownloadSpeed1KBPS =- 8 / 8; // kbps -> KB/s 37 | const double OHHTTPStubsDownloadSpeedSLOW =- 12 / 8; // kbps -> KB/s 38 | const double OHHTTPStubsDownloadSpeedGPRS =- 56 / 8; // kbps -> KB/s 39 | const double OHHTTPStubsDownloadSpeedEDGE =- 128 / 8; // kbps -> KB/s 40 | const double OHHTTPStubsDownloadSpeed3G =- 3200 / 8; // kbps -> KB/s 41 | const double OHHTTPStubsDownloadSpeed3GPlus =- 7200 / 8; // kbps -> KB/s 42 | const double OHHTTPStubsDownloadSpeedWifi =- 12000 / 8; // kbps -> KB/s 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | #pragma mark - Implementation 46 | 47 | @implementation HTTPStubsResponse 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | #pragma mark - Commodity Constructors 51 | 52 | 53 | #pragma mark > Building response from NSData 54 | 55 | +(instancetype)responseWithData:(NSData*)data 56 | statusCode:(int)statusCode 57 | headers:(nullable NSDictionary*)httpHeaders 58 | { 59 | HTTPStubsResponse* response = [[self alloc] initWithData:data 60 | statusCode:statusCode 61 | headers:httpHeaders]; 62 | return response; 63 | } 64 | 65 | 66 | #pragma mark > Building response from a file 67 | 68 | +(instancetype)responseWithFileAtPath:(NSString *)filePath 69 | statusCode:(int)statusCode 70 | headers:(nullable NSDictionary *)httpHeaders 71 | { 72 | HTTPStubsResponse* response = [[self alloc] initWithFileAtPath:filePath 73 | statusCode:statusCode 74 | headers:httpHeaders]; 75 | return response; 76 | } 77 | 78 | +(instancetype)responseWithFileURL:(NSURL *)fileURL 79 | statusCode:(int)statusCode 80 | headers:(nullable NSDictionary *)httpHeaders 81 | { 82 | HTTPStubsResponse* response = [[self alloc] initWithFileURL:fileURL 83 | statusCode:statusCode 84 | headers:httpHeaders]; 85 | return response; 86 | } 87 | 88 | #pragma mark > Building an error response 89 | 90 | +(instancetype)responseWithError:(NSError*)error 91 | { 92 | HTTPStubsResponse* response = [[self alloc] initWithError:error]; 93 | return response; 94 | } 95 | 96 | //////////////////////////////////////////////////////////////////////////////// 97 | #pragma mark - Commotidy Setters 98 | 99 | -(instancetype)responseTime:(NSTimeInterval)responseTime 100 | { 101 | _responseTime = responseTime; 102 | return self; 103 | } 104 | 105 | -(instancetype)requestTime:(NSTimeInterval)requestTime responseTime:(NSTimeInterval)responseTime 106 | { 107 | _requestTime = requestTime; 108 | _responseTime = responseTime; 109 | return self; 110 | } 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | #pragma mark - Initializers 114 | 115 | -(instancetype)init 116 | { 117 | self = [super init]; 118 | return self; 119 | } 120 | 121 | -(instancetype)initWithInputStream:(NSInputStream*)inputStream 122 | dataSize:(unsigned long long)dataSize 123 | statusCode:(int)statusCode 124 | headers:(nullable NSDictionary*)httpHeaders 125 | { 126 | self = [super init]; 127 | if (self) 128 | { 129 | _inputStream = inputStream; 130 | _dataSize = dataSize; 131 | _statusCode = statusCode; 132 | NSMutableDictionary * headers = [NSMutableDictionary dictionaryWithDictionary:httpHeaders]; 133 | static NSString *const ContentLengthHeader = @"Content-Length"; 134 | if (!headers[ContentLengthHeader]) 135 | { 136 | headers[ContentLengthHeader] = [NSString stringWithFormat:@"%llu",_dataSize]; 137 | } 138 | _httpHeaders = [NSDictionary dictionaryWithDictionary:headers]; 139 | } 140 | return self; 141 | } 142 | 143 | -(instancetype)initWithFileAtPath:(NSString*)filePath 144 | statusCode:(int)statusCode 145 | headers:(nullable NSDictionary*)httpHeaders 146 | { 147 | NSURL *fileURL = filePath ? [NSURL fileURLWithPath:filePath] : nil; 148 | self = [self initWithFileURL:fileURL 149 | statusCode:statusCode 150 | headers:httpHeaders]; 151 | return self; 152 | } 153 | 154 | -(instancetype)initWithFileURL:(NSURL *)fileURL 155 | statusCode:(int)statusCode 156 | headers:(nullable NSDictionary *)httpHeaders { 157 | if (!fileURL) { 158 | NSLog(@"%s: nil file path. Returning empty data", __PRETTY_FUNCTION__); 159 | return [self initWithInputStream:[NSInputStream inputStreamWithData:[NSData data]] 160 | dataSize:0 161 | statusCode:statusCode 162 | headers:httpHeaders]; 163 | } 164 | 165 | // [NSURL -isFileURL] is only available on iOS 8+ 166 | NSAssert([fileURL.scheme isEqualToString:NSURLFileScheme], @"%s: Only file URLs may be passed to this method.",__PRETTY_FUNCTION__); 167 | 168 | NSNumber *fileSize; 169 | NSError *error; 170 | const BOOL success __unused = [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:&error]; 171 | 172 | NSAssert(success && fileSize, @"%s Couldn't get the file size for URL. \ 173 | The URL was: %@. \ 174 | The operation to retrieve the file size was %@. \ 175 | The error associated with that operation was: %@", 176 | __PRETTY_FUNCTION__, fileURL, success ? @"successful" : @"unsuccessful", error); 177 | 178 | return [self initWithInputStream:[NSInputStream inputStreamWithURL:fileURL] 179 | dataSize:[fileSize unsignedLongLongValue] 180 | statusCode:statusCode 181 | headers:httpHeaders]; 182 | } 183 | 184 | -(instancetype)initWithData:(NSData*)data 185 | statusCode:(int)statusCode 186 | headers:(nullable NSDictionary*)httpHeaders 187 | { 188 | NSInputStream* inputStream = [NSInputStream inputStreamWithData:data?:[NSData data]]; 189 | self = [self initWithInputStream:inputStream 190 | dataSize:data.length 191 | statusCode:statusCode 192 | headers:httpHeaders]; 193 | return self; 194 | } 195 | 196 | -(instancetype)initWithError:(NSError*)error 197 | { 198 | self = [super init]; 199 | if (self) { 200 | _error = error; 201 | } 202 | return self; 203 | } 204 | 205 | -(NSString*)debugDescription 206 | { 207 | return [NSString stringWithFormat:@"<%@ %p requestTime:%f responseTime:%f status:%d dataSize:%llu>", 208 | self.class, self, self.requestTime, self.responseTime, self.statusCode, self.dataSize]; 209 | } 210 | 211 | //////////////////////////////////////////////////////////////////////////////// 212 | #pragma mark - Accessors 213 | 214 | -(void)setRequestTime:(NSTimeInterval)requestTime 215 | { 216 | NSAssert(requestTime >= 0, @"Invalid Request Time (%f) for OHHTTPStubResponse. Request time must be greater than or equal to zero",requestTime); 217 | _requestTime = requestTime; 218 | } 219 | 220 | @end 221 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/NSURLRequest+HTTPBodyTesting.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2016 Sebastian Hagedorn, Felix Lamouroux 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | #import "NSURLRequest+HTTPBodyTesting.h" 26 | 27 | #if defined(__IPHONE_7_0) || defined(__MAC_10_9) 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | #pragma mark - Imports 31 | 32 | #import "HTTPStubsMethodSwizzling.h" 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | #pragma mark - NSURLRequest+CustomHTTPBody 36 | 37 | NSString * const OHHTTPStubs_HTTPBodyKey = @"HTTPBody"; 38 | 39 | @implementation NSURLRequest (HTTPBodyTesting) 40 | 41 | - (NSData*)OHHTTPStubs_HTTPBody 42 | { 43 | return [NSURLProtocol propertyForKey:OHHTTPStubs_HTTPBodyKey inRequest:self]; 44 | } 45 | 46 | @end 47 | 48 | //////////////////////////////////////////////////////////////////////////////// 49 | #pragma mark - NSMutableURLRequest+HTTPBodyTesting 50 | 51 | typedef void(*HTTPStubsSetterIMP)(id, SEL, id); 52 | static HTTPStubsSetterIMP orig_setHTTPBody; 53 | 54 | static void OHHTTPStubs_setHTTPBody(id self, SEL _cmd, NSData* HTTPBody) 55 | { 56 | // store the http body via NSURLProtocol 57 | if (HTTPBody) { 58 | [NSURLProtocol setProperty:HTTPBody forKey:OHHTTPStubs_HTTPBodyKey inRequest:self]; 59 | } else { 60 | // unfortunately resetting does not work properly as the NSURLSession also uses this to reset the property 61 | } 62 | 63 | orig_setHTTPBody(self, _cmd, HTTPBody); 64 | } 65 | 66 | /** 67 | * Swizzles setHTTPBody: in order to maintain a copy of the http body for later 68 | * reference and calls the original implementation. 69 | * 70 | * @warning Should not be used in production, testing only. 71 | */ 72 | @interface NSMutableURLRequest (HTTPBodyTesting) @end 73 | 74 | @implementation NSMutableURLRequest (HTTPBodyTesting) 75 | 76 | + (void)load 77 | { 78 | orig_setHTTPBody = (HTTPStubsSetterIMP)HTTPStubsReplaceMethod(@selector(setHTTPBody:), 79 | (IMP)OHHTTPStubs_setHTTPBody, 80 | [NSMutableURLRequest class], 81 | NO); 82 | } 83 | 84 | @end 85 | 86 | #endif /* __IPHONE_7_0 || __MAC_10_9 */ 87 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/Compatibility.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | /* 27 | * This file allows to keep compatibility with older SDKs which didn't have 28 | * the latest features and associated macros yet. 29 | */ 30 | 31 | 32 | #ifndef NS_DESIGNATED_INITIALIZER 33 | #if __has_attribute(objc_designated_initializer) 34 | #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 35 | #else 36 | #define NS_DESIGNATED_INITIALIZER 37 | #endif 38 | #endif 39 | 40 | // Allow to use nullability macros and keywords even if not supported yet 41 | #if ! __has_feature(nullability) 42 | #define NS_ASSUME_NONNULL_BEGIN 43 | #define NS_ASSUME_NONNULL_END 44 | #define nullable 45 | #define __nullable 46 | #define __nonnull 47 | #endif 48 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/HTTPStubs.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import 30 | 31 | #import "Compatibility.h" 32 | #import "HTTPStubsResponse.h" 33 | 34 | NS_ASSUME_NONNULL_BEGIN 35 | 36 | //////////////////////////////////////////////////////////////////////////////// 37 | #pragma mark - Types 38 | 39 | typedef BOOL(^HTTPStubsTestBlock)(NSURLRequest* request); 40 | typedef HTTPStubsResponse* __nonnull (^HTTPStubsResponseBlock)( NSURLRequest* request); 41 | 42 | /** 43 | * This opaque type represents an installed stub and is used to uniquely 44 | * identify a stub once it has been created. 45 | * 46 | * This type is returned by the `stubRequestsPassingTest:withStubResponse:` method 47 | * so that you can later reference it and use this reference to remove the stub later. 48 | * 49 | * This type also let you add arbitrary metadata to a stub to differenciate it 50 | * more easily when debugging. 51 | */ 52 | @protocol HTTPStubsDescriptor 53 | /** 54 | * An arbitrary name that you can set and get to describe your stub. 55 | * Use it as your own convenience. 56 | * 57 | * This is especially useful if you dump all installed stubs using `allStubs` 58 | * or if you want to log which stubs are being triggered using `onStubActivation:`. 59 | */ 60 | @property(nonatomic, strong, nullable) NSString* name; 61 | @end 62 | 63 | //////////////////////////////////////////////////////////////////////////////// 64 | #pragma mark - Interface 65 | 66 | /** 67 | * Stubs Manager. Use this class to add and remove stubs and stub your network requests. 68 | */ 69 | @interface HTTPStubs : NSObject 70 | 71 | //////////////////////////////////////////////////////////////////////////////// 72 | #pragma mark - Adding & Removing stubs 73 | 74 | 75 | 76 | /** 77 | * Dedicated method to add a stub 78 | * 79 | * @param testBlock Block that should return `YES` if the request passed as parameter 80 | * should be stubbed with the response block, and `NO` if it should 81 | * hit the real world (or be managed by another stub). 82 | * @param responseBlock Block that will return the `HTTPStubsResponse` (response to 83 | * use for stubbing) corresponding to the given request 84 | * 85 | * @return a stub descriptor that uniquely identifies the stub and can be later used to remove it with `removeStub:`. 86 | * 87 | * @note The returned stub descriptor is retained (`__strong` reference) by `HTTPStubs` 88 | * until it is removed (with one of the `removeStub:` / `removeAllStubs` 89 | * methods); it is thus recommended to keep it in a `__weak` storage (and not `__strong`) 90 | * in your app code, to let the stub descriptor be destroyed and let the variable go 91 | * back to `nil` automatically when the stub is removed. 92 | */ 93 | +(id)stubRequestsPassingTest:(HTTPStubsTestBlock)testBlock 94 | withStubResponse:(HTTPStubsResponseBlock)responseBlock; 95 | 96 | /** 97 | * Remove a stub from the list of stubs 98 | * 99 | * @param stubDesc The stub descriptor that has been returned when adding the stub 100 | * using `stubRequestsPassingTest:withStubResponse:` 101 | * 102 | * @return `YES` if the stub has been successfully removed, `NO` if the parameter was 103 | * not a valid stub identifier 104 | */ 105 | +(BOOL)removeStub:(id)stubDesc; 106 | 107 | /** 108 | * Remove all the stubs from the stubs list. 109 | */ 110 | +(void)removeAllStubs; 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | #pragma mark - Disabling & Re-Enabling stubs 114 | 115 | /** 116 | * Enable or disable the stubs for the shared session or for `NSURLConnection` 117 | * 118 | * @param enabled If `YES`, enables the stubs. If `NO`, disable all the 119 | * stubs and let all the requests hit the real world. 120 | * 121 | * @note HTTPStubs are enabled by default, so there is no need to call 122 | * this method with `YES` for stubs to work, except if you explicitely 123 | * disabled the stubs before. 124 | * 125 | * @note This only affects requests that are further made using `NSURLConnection` 126 | * or using `[NSURLSession sharedSession]`. This does not affect requests 127 | * sent on an `NSURLSession` created using an `NSURLSessionConfiguration`. 128 | */ 129 | +(void)setEnabled:(BOOL)enabled; 130 | 131 | /** 132 | * Whether or not stubs are enabled for the shared session or for `NSURLConnection` 133 | * 134 | * @return If `YES` the stubs are enabled. If `NO` then the stubs are disabled 135 | */ 136 | +(BOOL)isEnabled; 137 | 138 | #if defined(__IPHONE_7_0) || defined(__MAC_10_9) 139 | /** 140 | * Enable or disable the stubs on a given `NSURLSessionConfiguration`. 141 | * 142 | * @param enabled If `YES`, enables the stubs for this `NSURLSessionConfiguration`. 143 | * If `NO`, disable the stubs and let all the requests hit the real world 144 | * @param sessionConfig The NSURLSessionConfiguration on which to enabled/disable the stubs 145 | * 146 | * @note HTTPStubs are enabled by default on newly created `defaultSessionConfiguration` 147 | * and `ephemeralSessionConfiguration`, so there is no need to call this method with 148 | * `YES` for stubs to work. You generally only use this if you want to disable 149 | * `OHTTPStubs` per `NSURLSession` by calling it before building the `NSURLSession` 150 | * with the `NSURLSessionConfiguration`. 151 | * 152 | * @note Important: As usual according to the way `NSURLSessionConfiguration` works, you 153 | * MUST set this property BEFORE creating the `NSURLSession`. Once the `NSURLSession` 154 | * object is created, they use a deep copy of the `NSURLSessionConfiguration` object 155 | * used to create them, so changing the configuration later does not affect already 156 | * created sessions. 157 | */ 158 | + (void)setEnabled:(BOOL)enabled forSessionConfiguration:(NSURLSessionConfiguration *)sessionConfig; 159 | 160 | /** 161 | * Whether stubs are enabled or disabled on a given `NSURLSessionConfiguration` 162 | * 163 | * @param sessionConfig The NSURLSessionConfiguration on which to enable/disable the stubs 164 | * 165 | * @return If `YES` the stubs are enabled for sessionConfig. If `NO` then the stubs are disabled 166 | */ 167 | + (BOOL)isEnabledForSessionConfiguration:(NSURLSessionConfiguration *)sessionConfig; 168 | #endif 169 | 170 | #pragma mark - Debug Methods 171 | 172 | /** 173 | * List all the installed stubs 174 | * 175 | * @return An array of `id` objects currently installed. Useful for debug. 176 | */ 177 | +(NSArray*)allStubs; 178 | 179 | /** 180 | * Setup a block to be called each time a stub is triggered. 181 | * 182 | * Useful if you want to log all your requests being stubbed for example and see which stub 183 | * was used to respond to each request. 184 | * 185 | * @param block The block to call each time a request is being stubbed by OHHTTPStubs. 186 | * Set it to `nil` to do nothing. Defaults is `nil`. 187 | */ 188 | +(void)onStubActivation:( nullable void(^)(NSURLRequest* request, id stub, HTTPStubsResponse* responseStub) )block; 189 | 190 | /** 191 | * Setup a block to be called whenever OHHTTPStubs encounters a redirect request. 192 | * 193 | * @param block The block to call each time a redirect request is being stubbed by OHHTTPStubs. 194 | * Set it to `nil` to do nothing. Defaults is `nil`. 195 | */ 196 | +(void)onStubRedirectResponse:( nullable void(^)(NSURLRequest* request, NSURLRequest* redirectRequest, id stub, HTTPStubsResponse* responseStub) )block; 197 | 198 | /** 199 | * Setup a block to be called each time a stub finishes. Useful if stubs take an insignificant amount 200 | * of time to execute (due to low bandwidth or delayed response time). This block may also be called 201 | * if there are errors generated by OHHTTPStubs in the course of executing a network request. 202 | * 203 | * @param block The block to call each time a request is finished being stubbed by OHHTTPStubs. 204 | * Set it to `nil` to do nothing. Defaults is `nil`. 205 | */ 206 | +(void)afterStubFinish:( nullable void(^)(NSURLRequest* request, id stub, HTTPStubsResponse* responseStub, NSError *error) )block; 207 | 208 | /** 209 | * Setup a block to be called whenever OHHTTPStubs encounters a missing stub. 210 | * 211 | * @param block The block to call each time no stub for a request can be found. 212 | * Set it to `nil` to do nothing. Defaults is `nil`. 213 | */ 214 | +(void)onStubMissing:( nullable void(^)(NSURLRequest* request) )block; 215 | 216 | @end 217 | 218 | NS_ASSUME_NONNULL_END 219 | 220 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/HTTPStubsPathHelpers.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import 27 | 28 | #import "Compatibility.h" 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | /** 33 | * Useful function to build a path given a file name and a class. 34 | * 35 | * @param fileName The name of the file to get the path to, including file extension 36 | * @param inBundleForClass The class of the caller, used to determine the current bundle 37 | * in which the file is supposed to be located. 38 | * You should typically pass `self.class` (ObjC) or 39 | * `self.dynamicType` (Swift < 3.0) or `type(of: self)` (Swift >= 3.0) when calling this function. 40 | * 41 | * @return The path of the given file in the same bundle as the inBundleForClass class 42 | */ 43 | NSString* __nullable OHPathForFile(NSString* fileName, Class inBundleForClass); 44 | 45 | /** 46 | * Useful function to build a path given a file name and a bundle. 47 | * 48 | * @param fileName The name of the file to get the path to, including file extension 49 | * @param bundle The bundle in which the file is supposed to be located. 50 | * This parameter can't be null. 51 | * 52 | * @return The path of the given file in given bundle 53 | * 54 | * @note You should avoid using `[NSBundle mainBundle]` for the `bundle` parameter, 55 | * as in the context of Unit Tests, this points to the Simulator's bundle, 56 | * not the bundle of the app under test. That's why `nil` is not an acceptable 57 | * value (so you won't expect it to default to the `mainBundle`). 58 | * You should use `[NSBundle bundleForClass:]` instead. 59 | */ 60 | NSString* __nullable OHPathForFileInBundle(NSString* fileName, NSBundle* bundle); 61 | 62 | /** 63 | * Useful function to build a path to a file in the Documents's directory in the 64 | * app sandbox, used by iTunes File Sharing for example. 65 | * 66 | * @param fileName The name of the file to get the path to, including file extension 67 | * 68 | * @return The path of the file in the Documents directory in your App Sandbox 69 | */ 70 | NSString* __nullable OHPathForFileInDocumentsDir(NSString* fileName); 71 | 72 | 73 | 74 | /** 75 | * Useful function to build an NSBundle located in the application's resources simply from its name 76 | * 77 | * @param bundleBasename The base name, without extension (extension is assumed to be ".bundle"). 78 | * @param inBundleForClass The class of the caller, used to determine the current bundle 79 | * in which the file is supposed to be located. 80 | * You should typically pass `self.class` (ObjC) or 81 | * `self.dynamicType` (Swift) when calling this function. 82 | * 83 | * @return The NSBundle object representing the bundle with the given basename located in your application's resources. 84 | */ 85 | NSBundle* __nullable OHResourceBundle(NSString* bundleBasename, Class inBundleForClass); 86 | 87 | NS_ASSUME_NONNULL_END 88 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/HTTPStubsResponse+JSON.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "HTTPStubsResponse.h" 27 | #import "Compatibility.h" 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | /** 32 | * Adds convenience methods to manipulate JSON objects directly. 33 | * Pass in an `NSDictionary` or `NSArray` to generate a corresponding JSON output. 34 | */ 35 | @interface HTTPStubsResponse (JSON) 36 | 37 | /** 38 | * Builds a response given a JSON object for the response body, status code, and headers. 39 | * 40 | * @param jsonObject Object representing the response body. 41 | * Typically a `NSDictionary`; may be any object accepted by `+[NSJSONSerialization dataWithJSONObject:options:error:]` 42 | * @param statusCode The HTTP Status Code to use in the response 43 | * @param httpHeaders The HTTP Headers to return in the response 44 | * If a "Content-Type" header is not included, "Content-Type: application/json" will be added. 45 | * 46 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 47 | * 48 | * @note This method typically calls `responseWithData:statusCode:headers:`, passing the serialized JSON 49 | * object as the data parameter and adding the Content-Type header if necessary. 50 | */ 51 | + (instancetype)responseWithJSONObject:(id)jsonObject 52 | statusCode:(int)statusCode 53 | headers:(nullable NSDictionary *)httpHeaders; 54 | 55 | @end 56 | 57 | NS_ASSUME_NONNULL_END 58 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/HTTPStubsResponse.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import 30 | 31 | #import "Compatibility.h" 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | #pragma mark - Defines & Constants 35 | 36 | // Non-standard download speeds 37 | extern const double 38 | OHHTTPStubsDownloadSpeed1KBPS, // 1.0 KB per second 39 | OHHTTPStubsDownloadSpeedSLOW; // 1.5 KB per second 40 | 41 | // Standard download speeds. 42 | extern const double 43 | OHHTTPStubsDownloadSpeedGPRS, 44 | OHHTTPStubsDownloadSpeedEDGE, 45 | OHHTTPStubsDownloadSpeed3G, 46 | OHHTTPStubsDownloadSpeed3GPlus, 47 | OHHTTPStubsDownloadSpeedWifi; 48 | 49 | 50 | NS_ASSUME_NONNULL_BEGIN 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | #pragma mark - Interface 54 | 55 | /** 56 | * Stubs Response. This describes a stubbed response to be returned by the URL Loading System, 57 | * including its HTTP headers, body, statusCode and response time. 58 | */ 59 | @interface HTTPStubsResponse : NSObject 60 | 61 | //////////////////////////////////////////////////////////////////////////////// 62 | #pragma mark - Properties 63 | 64 | /** 65 | * The headers to use for the fake response 66 | */ 67 | @property(nonatomic, strong, nullable) NSDictionary* httpHeaders; 68 | /** 69 | * The HTTP status code to use for the fake response 70 | */ 71 | @property(nonatomic, assign) int statusCode; 72 | /** 73 | * The inputStream used when sending the response. 74 | * @note You generally don't manipulate this directly. 75 | */ 76 | @property(nonatomic, strong, nullable) NSInputStream* inputStream; 77 | /** 78 | * The size of the fake response body, in bytes. 79 | */ 80 | @property(nonatomic, assign) unsigned long long dataSize; 81 | /** 82 | * The duration to wait before faking receiving the response headers. 83 | * 84 | * Defaults to 0.0. 85 | */ 86 | @property(nonatomic, assign) NSTimeInterval requestTime; 87 | /** 88 | * The duration to use to send the fake response body. 89 | * 90 | * @note if responseTime<0, it is interpreted as a download speed in KBps ( -200 => 200KB/s ) 91 | */ 92 | @property(nonatomic, assign) NSTimeInterval responseTime; 93 | /** 94 | * The fake error to generate to simulate a network error. 95 | * 96 | * If `error` is non-`nil`, the request will result in a failure and no response will be sent. 97 | */ 98 | @property(nonatomic, strong, nullable) NSError* error; 99 | 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | #pragma mark - Commodity Constructors 103 | /*! @name Commodity */ 104 | 105 | /* -------------------------------------------------------------------------- */ 106 | #pragma mark > Building response from NSData 107 | 108 | /** 109 | * Builds a response given raw data. 110 | * 111 | * @note Internally calls `-initWithInputStream:dataSize:statusCode:headers:` with and inputStream built from the NSData. 112 | * 113 | * @param data The raw data to return in the response 114 | * @param statusCode The HTTP Status Code to use in the response 115 | * @param httpHeaders The HTTP Headers to return in the response 116 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 117 | */ 118 | +(instancetype)responseWithData:(NSData*)data 119 | statusCode:(int)statusCode 120 | headers:(nullable NSDictionary*)httpHeaders; 121 | 122 | 123 | /* -------------------------------------------------------------------------- */ 124 | #pragma mark > Building response from a file 125 | 126 | /** 127 | * Builds a response given a file path, the status code and headers. 128 | * 129 | * @param filePath The file path that contains the response body to return. 130 | * @param statusCode The HTTP Status Code to use in the response 131 | * @param httpHeaders The HTTP Headers to return in the response 132 | * 133 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 134 | * 135 | * @note It is encouraged to use the OHPathHelpers functions & macros to build 136 | * the filePath parameter easily 137 | */ 138 | +(instancetype)responseWithFileAtPath:(NSString *)filePath 139 | statusCode:(int)statusCode 140 | headers:(nullable NSDictionary*)httpHeaders; 141 | 142 | 143 | /** 144 | * Builds a response given a URL, the status code, and headers. 145 | * 146 | * @param fileURL The URL for the data to return in the response 147 | * @param statusCode The HTTP Status Code to use in the response 148 | * @param httpHeaders The HTTP Headers to return in the response 149 | * 150 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 151 | * 152 | * @note This method applies only to URLs that represent file system resources 153 | */ 154 | +(instancetype)responseWithFileURL:(NSURL *)fileURL 155 | statusCode:(int)statusCode 156 | headers:(nullable NSDictionary *)httpHeaders; 157 | 158 | /* -------------------------------------------------------------------------- */ 159 | #pragma mark > Building an error response 160 | 161 | /** 162 | * Builds a response that corresponds to the given error 163 | * 164 | * @param error The error to use in the stubbed response. 165 | * 166 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 167 | * 168 | * @note For example you could use an error like `[NSError errorWithDomain:NSURLErrorDomain code:kCFURLErrorNotConnectedToInternet userInfo:nil]` 169 | */ 170 | +(instancetype)responseWithError:(NSError*)error; 171 | 172 | 173 | //////////////////////////////////////////////////////////////////////////////// 174 | #pragma mark - Commotidy Setters 175 | 176 | /** 177 | * Set the `responseTime` of the `HTTPStubsResponse` and return `self`. Useful for chaining method calls. 178 | * 179 | * _Usage example:_ 180 | *
return [[HTTPStubsResponse responseWithData:data statusCode:200 headers:nil] responseTime:5.0];
181 | * 182 | * @param responseTime If positive, the amount of time used to send the entire response. 183 | * If negative, the rate in KB/s at which to send the response data. 184 | * Useful to simulate slow networks for example. You may use the 185 | * _OHHTTPStubsDownloadSpeed…_ constants here. 186 | * 187 | * @return `self` (= the same `HTTPStubsResponse` that was the target of this method). 188 | * Returning `self` is useful for chaining method calls. 189 | */ 190 | -(instancetype)responseTime:(NSTimeInterval)responseTime; 191 | 192 | /** 193 | * Set both the `requestTime` and the `responseTime` of the `HTTPStubsResponse` at once. 194 | * Useful for chaining method calls. 195 | * 196 | * _Usage example:_ 197 | *
return [[HTTPStubsResponse responseWithData:data statusCode:200 headers:nil]
198 |  *            requestTime:1.0 responseTime:5.0];
199 | * 200 | * @param requestTime The time to wait before the response begins to send. This value must be greater than or equal to zero. 201 | * @param responseTime If positive, the amount of time used to send the entire response. 202 | * If negative, the rate in KB/s at which to send the response data. 203 | * Useful to simulate slow networks for example. You may use the 204 | * _OHHTTPStubsDownloadSpeed…_ constants here. 205 | * 206 | * @return `self` (= the same `HTTPStubsResponse` that was the target of this method). Useful for chaining method calls. 207 | */ 208 | -(instancetype)requestTime:(NSTimeInterval)requestTime responseTime:(NSTimeInterval)responseTime; 209 | 210 | 211 | //////////////////////////////////////////////////////////////////////////////// 212 | #pragma mark - Initializers 213 | /*! @name Initializers */ 214 | 215 | /** 216 | * Designated empty initializer 217 | * 218 | * @return An empty `HTTPStubsResponse` on which you need to set either an error or a statusCode, httpHeaders, inputStream and dataSize. 219 | * 220 | * @note This is not recommended to use this method directly. You should use `initWithInputStream:dataSize:statusCode:headers:` instead. 221 | */ 222 | -(instancetype)init NS_DESIGNATED_INITIALIZER; 223 | 224 | /** 225 | * Designed initializer. Initialize a response with the given input stream, dataSize, 226 | * statusCode and headers. 227 | * 228 | * @param inputStream The input stream that will provide the data to return in the response 229 | * @param dataSize The size of the data in the stream. 230 | * @param statusCode The HTTP Status Code to use in the response 231 | * @param httpHeaders The HTTP Headers to return in the response 232 | * 233 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 234 | * 235 | * @note You will probably never need to call this method yourself. Prefer the other initializers (that will call this method eventually) 236 | */ 237 | -(instancetype)initWithInputStream:(NSInputStream*)inputStream 238 | dataSize:(unsigned long long)dataSize 239 | statusCode:(int)statusCode 240 | headers:(nullable NSDictionary*)httpHeaders NS_DESIGNATED_INITIALIZER; 241 | 242 | 243 | /** 244 | * Initialize a response with a given file path, statusCode and headers. 245 | * 246 | * @param filePath The file path of the data to return in the response 247 | * @param statusCode The HTTP Status Code to use in the response 248 | * @param httpHeaders The HTTP Headers to return in the response 249 | * 250 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 251 | * 252 | * @note This method simply builds the NSInputStream, compute the file size, and then call `-initWithInputStream:dataSize:statusCode:headers:` 253 | */ 254 | -(instancetype)initWithFileAtPath:(NSString*)filePath 255 | statusCode:(int)statusCode 256 | headers:(nullable NSDictionary*)httpHeaders; 257 | 258 | 259 | /** 260 | * Initialize a response with a given URL, statusCode and headers. 261 | * 262 | * @param fileURL The URL for the data to return in the response 263 | * @param statusCode The HTTP Status Code to use in the response 264 | * @param httpHeaders The HTTP Headers to return in the response 265 | * 266 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 267 | * 268 | * @note This method applies only to URLs that represent file system resources 269 | */ 270 | -(instancetype)initWithFileURL:(NSURL *)fileURL 271 | statusCode:(int)statusCode 272 | headers:(nullable NSDictionary *)httpHeaders; 273 | 274 | /** 275 | * Initialize a response with the given data, statusCode and headers. 276 | * 277 | * @param data The raw data to return in the response 278 | * @param statusCode The HTTP Status Code to use in the response 279 | * @param httpHeaders The HTTP Headers to return in the response 280 | * 281 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 282 | */ 283 | -(instancetype)initWithData:(NSData*)data 284 | statusCode:(int)statusCode 285 | headers:(nullable NSDictionary*)httpHeaders; 286 | 287 | 288 | /** 289 | * Designed initializer. Initialize a response with the given error. 290 | * 291 | * @param error The error to use in the stubbed response. 292 | * 293 | * @return An `HTTPStubsResponse` describing the corresponding response to return by the stub 294 | * 295 | * @note For example you could use an error like `[NSError errorWithDomain:NSURLErrorDomain code:kCFURLErrorNotConnectedToInternet userInfo:nil]` 296 | */ 297 | -(instancetype)initWithError:(NSError*)error NS_DESIGNATED_INITIALIZER; 298 | 299 | @end 300 | 301 | NS_ASSUME_NONNULL_END 302 | -------------------------------------------------------------------------------- /Example/Pods/OHHTTPStubs/Sources/OHHTTPStubs/include/NSURLRequest+HTTPBodyTesting.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2016 Sebastian Hagedorn, Felix Lamouroux 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | #pragma mark - Imports 27 | 28 | #import 29 | 30 | // This category is only useful when NSURLSession is present 31 | #if defined(__IPHONE_7_0) || defined(__MAC_10_9) 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | #pragma mark - NSURLRequest+HTTPBodyTesting 35 | 36 | @interface NSURLRequest (HTTPBodyTesting) 37 | /** 38 | * Unfortunately, when sending POST requests (with a body) using NSURLSession, 39 | * by the time the request arrives at OHHTTPStubs, the HTTPBody of the 40 | * NSURLRequest has been reset to nil. 41 | * 42 | * You can use this method to retrieve the HTTPBody for testing and use it to 43 | * conditionally stub your requests. 44 | */ 45 | - (NSData *)OHHTTPStubs_HTTPBody; 46 | @end 47 | 48 | #endif /* __IPHONE_7_0 || __MAC_10_9 */ 49 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Hyperconnectivity.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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity-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.1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Hyperconnectivity : NSObject 3 | @end 4 | @implementation PodsDummy_Hyperconnectivity 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity-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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity-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 HyperconnectivityVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char HyperconnectivityVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Combine" -framework "Network" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity.modulemap: -------------------------------------------------------------------------------- 1 | framework module Hyperconnectivity { 2 | umbrella header "Hyperconnectivity-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Hyperconnectivity/Hyperconnectivity.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Combine" -framework "Network" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs-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 | 9.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_OHHTTPStubs : NSObject 3 | @end 4 | @implementation PodsDummy_OHHTTPStubs 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs-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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs-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 | #import "HTTPStubs.h" 14 | #import "HTTPStubsResponse.h" 15 | #import "Compatibility.h" 16 | #import "HTTPStubsResponse+JSON.h" 17 | #import "NSURLRequest+HTTPBodyTesting.h" 18 | #import "HTTPStubsPathHelpers.h" 19 | #import "Compatibility.h" 20 | 21 | FOUNDATION_EXPORT double OHHTTPStubsVersionNumber; 22 | FOUNDATION_EXPORT const unsigned char OHHTTPStubsVersionString[]; 23 | 24 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/OHHTTPStubs 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs.modulemap: -------------------------------------------------------------------------------- 1 | framework module OHHTTPStubs { 2 | umbrella header "OHHTTPStubs-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/OHHTTPStubs/OHHTTPStubs.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/OHHTTPStubs 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Hyperconnectivity 5 | 6 | Copyright (c) 2020 Ross Butler 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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-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) 2020 Ross Butler 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 | Hyperconnectivity 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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Hyperconnectivity_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Hyperconnectivity_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-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 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | 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}\"" 99 | 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}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # 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. 116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}" 117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 118 | fi 119 | fi 120 | } 121 | 122 | # Used as a return value for each invocation of `strip_invalid_archs` function. 123 | STRIP_BINARY_RETVAL=0 124 | 125 | # Strip invalid architectures 126 | strip_invalid_archs() { 127 | binary="$1" 128 | warn_missing_arch=${2:-true} 129 | # Get architectures for current target binary 130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 131 | # Intersect them with the architectures we are building for 132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 133 | # If there are no archs supported by this binary then warn the user 134 | if [[ -z "$intersected_archs" ]]; then 135 | if [[ "$warn_missing_arch" == "true" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | fi 138 | STRIP_BINARY_RETVAL=1 139 | return 140 | fi 141 | stripped="" 142 | for arch in $binary_archs; do 143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 144 | # Strip non-valid architectures in-place 145 | lipo -remove "$arch" -output "$binary" "$binary" 146 | stripped="$stripped $arch" 147 | fi 148 | done 149 | if [[ "$stripped" ]]; then 150 | echo "Stripped $binary of architectures:$stripped" 151 | fi 152 | STRIP_BINARY_RETVAL=0 153 | } 154 | 155 | # Copies the bcsymbolmap files of a vendored framework 156 | install_bcsymbolmap() { 157 | local bcsymbolmap_path="$1" 158 | local destination="${BUILT_PRODUCTS_DIR}" 159 | 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}"" 160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 161 | } 162 | 163 | # Signs a framework with the provided identity 164 | code_sign_if_enabled() { 165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 166 | # Use the current code_sign_identity 167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 169 | 170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 171 | code_sign_cmd="$code_sign_cmd &" 172 | fi 173 | echo "$code_sign_cmd" 174 | eval "$code_sign_cmd" 175 | fi 176 | } 177 | 178 | if [[ "$CONFIGURATION" == "Debug" ]]; then 179 | install_framework "${BUILT_PRODUCTS_DIR}/Hyperconnectivity/Hyperconnectivity.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/Hyperconnectivity/Hyperconnectivity.framework" 183 | fi 184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 185 | wait 186 | fi 187 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example-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_Hyperconnectivity_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Hyperconnectivity_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity/Hyperconnectivity.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "Combine" -framework "Hyperconnectivity" -framework "Network" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Hyperconnectivity_Example { 2 | umbrella header "Pods-Hyperconnectivity_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Example/Pods-Hyperconnectivity_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity/Hyperconnectivity.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "Combine" -framework "Hyperconnectivity" -framework "Network" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## OHHTTPStubs 5 | 6 | - MIT LICENSE - 7 | 8 | Copyright (c) 2012 Olivier Halligon 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | Generated by CocoaPods - https://cocoapods.org 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-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 | - MIT LICENSE - 18 | 19 | Copyright (c) 2012 Olivier Halligon 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | License 27 | MIT 28 | Title 29 | OHHTTPStubs 30 | Type 31 | PSGroupSpecifier 32 | 33 | 34 | FooterText 35 | Generated by CocoaPods - https://cocoapods.org 36 | Title 37 | 38 | Type 39 | PSGroupSpecifier 40 | 41 | 42 | StringsTable 43 | Acknowledgements 44 | Title 45 | Acknowledgements 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Hyperconnectivity_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Hyperconnectivity_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-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 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | 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}\"" 99 | 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}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # 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. 116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}" 117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 118 | fi 119 | fi 120 | } 121 | 122 | # Used as a return value for each invocation of `strip_invalid_archs` function. 123 | STRIP_BINARY_RETVAL=0 124 | 125 | # Strip invalid architectures 126 | strip_invalid_archs() { 127 | binary="$1" 128 | warn_missing_arch=${2:-true} 129 | # Get architectures for current target binary 130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 131 | # Intersect them with the architectures we are building for 132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 133 | # If there are no archs supported by this binary then warn the user 134 | if [[ -z "$intersected_archs" ]]; then 135 | if [[ "$warn_missing_arch" == "true" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | fi 138 | STRIP_BINARY_RETVAL=1 139 | return 140 | fi 141 | stripped="" 142 | for arch in $binary_archs; do 143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 144 | # Strip non-valid architectures in-place 145 | lipo -remove "$arch" -output "$binary" "$binary" 146 | stripped="$stripped $arch" 147 | fi 148 | done 149 | if [[ "$stripped" ]]; then 150 | echo "Stripped $binary of architectures:$stripped" 151 | fi 152 | STRIP_BINARY_RETVAL=0 153 | } 154 | 155 | # Copies the bcsymbolmap files of a vendored framework 156 | install_bcsymbolmap() { 157 | local bcsymbolmap_path="$1" 158 | local destination="${BUILT_PRODUCTS_DIR}" 159 | 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}"" 160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 161 | } 162 | 163 | # Signs a framework with the provided identity 164 | code_sign_if_enabled() { 165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 166 | # Use the current code_sign_identity 167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 169 | 170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 171 | code_sign_cmd="$code_sign_cmd &" 172 | fi 173 | echo "$code_sign_cmd" 174 | eval "$code_sign_cmd" 175 | fi 176 | } 177 | 178 | if [[ "$CONFIGURATION" == "Debug" ]]; then 179 | install_framework "${BUILT_PRODUCTS_DIR}/OHHTTPStubs/OHHTTPStubs.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/OHHTTPStubs/OHHTTPStubs.framework" 183 | fi 184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 185 | wait 186 | fi 187 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests-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_Hyperconnectivity_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Hyperconnectivity_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity" "${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity/Hyperconnectivity.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs/OHHTTPStubs.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" -framework "Combine" -framework "Foundation" -framework "Hyperconnectivity" -framework "Network" -framework "OHHTTPStubs" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Hyperconnectivity_Tests { 2 | umbrella header "Pods-Hyperconnectivity_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Hyperconnectivity_Tests/Pods-Hyperconnectivity_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity" "${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Hyperconnectivity/Hyperconnectivity.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/OHHTTPStubs/OHHTTPStubs.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork" -framework "Combine" -framework "Foundation" -framework "Hyperconnectivity" -framework "Network" -framework "OHHTTPStubs" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Tests/ConnectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConnectionTests.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 10/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Network 11 | import XCTest 12 | @testable import Hyperconnectivity 13 | 14 | class ConnectionTests: XCTestCase { 15 | 16 | func testIfPathIsWiredEthernetThenConnectionIsEthernet() { 17 | let path = MockPath(interfaceType: .wiredEthernet) 18 | let sut = Connection(path) 19 | XCTAssertEqual(sut, .ethernet) 20 | } 21 | 22 | func testIfPathIsWiFiThenConnectionIsWiFi() { 23 | let path = MockPath(interfaceType: .wifi) 24 | let sut = Connection(path) 25 | XCTAssertEqual(sut, .wifi) 26 | } 27 | 28 | func testIfPathIsCellularThenConnectionIsCellular() { 29 | let path = MockPath(interfaceType: .cellular) 30 | let sut = Connection(path) 31 | XCTAssertEqual(sut, .cellular) 32 | } 33 | 34 | func testIfPathIsWiFiThenConnectionIsOther() { 35 | let path = MockPath(interfaceType: .other) 36 | let sut = Connection(path) 37 | XCTAssertEqual(sut, .other) 38 | } 39 | 40 | func testIfPathIsLoopbackThenConnectionIsLoopback() { 41 | let path = MockPath(interfaceType: .loopback) 42 | let sut = Connection(path) 43 | XCTAssertEqual(sut, .loopback) 44 | } 45 | 46 | func testIfPathIsNilThenConnectionIsDisconnected() { 47 | let path = MockPath(interfaceType: nil) 48 | let sut = Connection(path) 49 | XCTAssertEqual(sut, .disconnected) 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /Example/Tests/ConnectivityPublisherTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConnectivityPublisherTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Combine 10 | import Foundation 11 | import OHHTTPStubs 12 | #if canImport(OHHTTPStubsSwift) 13 | import OHHTTPStubsSwift 14 | #endif 15 | import XCTest 16 | @testable import Hyperconnectivity 17 | 18 | class ConnectivityPublisherTests: XCTestCase { 19 | private var cancellable: AnyCancellable? 20 | private let timeout: TimeInterval = 5.0 21 | 22 | override func tearDown() { 23 | super.tearDown() 24 | HTTPStubs.removeAllStubs() 25 | cancellable = nil 26 | } 27 | 28 | private func stubHost(_ host: String, withHTMLFrom fileName: String) throws { 29 | #if SWIFT_PACKAGE 30 | let bundle = Bundle.module 31 | #else 32 | let bundle = Bundle(for: type(of: self)) 33 | #endif 34 | let fileURL = bundle.url( 35 | forResource: (fileName as NSString).deletingPathExtension, 36 | withExtension: (fileName as NSString).pathExtension 37 | ) 38 | let stubPath = try XCTUnwrap(fileURL?.relativePath) 39 | stub(condition: isHost(host)) { _ in 40 | return fixture(filePath: stubPath, headers: ["Content-Type": "text/html"]) 41 | } 42 | } 43 | 44 | func testSubscriberInvokedOnSuccessfulConnectivityCheck() throws { 45 | try stubHost("captive.apple.com", withHTMLFrom: "string-contains-response.html") 46 | try stubHost("www.apple.com", withHTMLFrom: "string-contains-response.html") 47 | let expectation = XCTestExpectation(description: "Connectivity check succeeds") 48 | cancellable = Hyperconnectivity.Publisher().sink(receiveCompletion: { _ in 49 | }, receiveValue: { result in 50 | XCTAssert(result.state == .wifiWithInternet || result.state == .ethernetWithInternet) 51 | expectation.fulfill() 52 | }) 53 | wait(for: [expectation], timeout: timeout) 54 | } 55 | 56 | func testSubscriberInvokedOnFailedConnectivityCheck() throws { 57 | try stubHost("captive.apple.com", withHTMLFrom: "failure-response.html") 58 | try stubHost("www.apple.com", withHTMLFrom: "failure-response.html") 59 | let expectation = XCTestExpectation(description: "Connectivity check fails") 60 | cancellable = Hyperconnectivity.Publisher().sink(receiveCompletion: { _ in 61 | }, receiveValue: { result in 62 | XCTAssert(result.state == .wifiWithoutInternet || result.state == .ethernetWithoutInternet) 63 | expectation.fulfill() 64 | }) 65 | wait(for: [expectation], timeout: timeout) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Example/Tests/ConnectivityStateTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConnectivityStateTests.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 09/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | @testable import Hyperconnectivity 12 | 13 | class ConnectivityStateTests: XCTestCase { 14 | 15 | func testConnectionIsCellularAndIsConnected() { 16 | let sut = ConnectivityState(connection: .cellular, isConnected: true) 17 | XCTAssertEqual(sut, .cellularWithInternet) 18 | } 19 | 20 | func testConnectionIsCellularAndIsNotConnected() { 21 | let sut = ConnectivityState(connection: .cellular, isConnected: false) 22 | XCTAssertEqual(sut, .cellularWithoutInternet) 23 | } 24 | 25 | func testConnectionIsDisconnectedAndIsConnected() { 26 | let sut = ConnectivityState(connection: .disconnected, isConnected: true) 27 | XCTAssertEqual(sut, .disconnected) 28 | } 29 | 30 | func testConnectionIsDisconnectedAndIsNotConnected() { 31 | let sut = ConnectivityState(connection: .disconnected, isConnected: false) 32 | XCTAssertEqual(sut, .disconnected) 33 | } 34 | 35 | func testConnectionIsEthernetAndIsConnected() { 36 | let sut = ConnectivityState(connection: .ethernet, isConnected: true) 37 | XCTAssertEqual(sut, .ethernetWithInternet) 38 | } 39 | 40 | func testConnectionIsEthernetAndIsNotConnected() { 41 | let sut = ConnectivityState(connection: .ethernet, isConnected: false) 42 | XCTAssertEqual(sut, .ethernetWithoutInternet) 43 | } 44 | 45 | func testConnectionIsLoopbackAndIsConnected() { 46 | let sut = ConnectivityState(connection: .loopback, isConnected: true) 47 | XCTAssertEqual(sut, .loopback) 48 | } 49 | 50 | func testConnectionIsLoopbackAndIsNotConnected() { 51 | let sut = ConnectivityState(connection: .loopback, isConnected: false) 52 | XCTAssertEqual(sut, .loopback) 53 | } 54 | 55 | func testConnectionIsOtherAndIsConnected() { 56 | let sut = ConnectivityState(connection: .other, isConnected: true) 57 | XCTAssertEqual(sut, .otherWithInternet) 58 | } 59 | 60 | func testConnectionIsOtherAndIsNotConnected() { 61 | let sut = ConnectivityState(connection: .other, isConnected: false) 62 | XCTAssertEqual(sut, .otherWithoutInternet) 63 | } 64 | 65 | func testConnectionIsWiFiAndIsConnected() { 66 | let sut = ConnectivityState(connection: .wifi, isConnected: true) 67 | XCTAssertEqual(sut, .wifiWithInternet) 68 | } 69 | 70 | func testConnectionIsWiFiAndIsNotConnected() { 71 | let sut = ConnectivityState(connection: .wifi, isConnected: false) 72 | XCTAssertEqual(sut, .wifiWithoutInternet) 73 | } 74 | 75 | func testDescriptionForCellularWithInternetIsCorrect() { 76 | let sut = ConnectivityState.cellularWithInternet 77 | XCTAssertEqual(sut.description, "Cellular with Internet connectivity") 78 | } 79 | 80 | func testDescriptionForCellularWithoutInternetIsCorrect() { 81 | let sut = ConnectivityState.cellularWithoutInternet 82 | XCTAssertEqual(sut.description, "Cellular without Internet connectivity") 83 | } 84 | 85 | func testDescriptionForDisconnectedIsCorrect() { 86 | let sut = ConnectivityState.disconnected 87 | XCTAssertEqual(sut.description, "Disconnected") 88 | } 89 | 90 | func testDescriptionForEthernetWithInternetIsCorrect() { 91 | let sut = ConnectivityState.ethernetWithInternet 92 | XCTAssertEqual(sut.description, "Ethernet with Internet connectivity") 93 | } 94 | 95 | func testDescriptionForethernetWithoutInternetIsCorrect() { 96 | let sut = ConnectivityState.ethernetWithoutInternet 97 | XCTAssertEqual(sut.description, "Ethernet without Internet connectivity") 98 | } 99 | 100 | func testDescriptionForLoopbackIsCorrect() { 101 | let sut = ConnectivityState.loopback 102 | XCTAssertEqual(sut.description, "Loopback") 103 | } 104 | 105 | func testDescriptionForOtherWithInternetIsCorrect() { 106 | let sut = ConnectivityState.otherWithInternet 107 | XCTAssertEqual(sut.description, "Other with Internet connectivity") 108 | } 109 | 110 | func testDescriptionForOtherWithoutInternetIsCorrect() { 111 | let sut = ConnectivityState.otherWithoutInternet 112 | XCTAssertEqual(sut.description, "Other without Internet connectivity") 113 | } 114 | 115 | func testDescriptionForWiFiWithInternetIsCorrect() { 116 | let sut = ConnectivityState.wifiWithInternet 117 | XCTAssertEqual(sut.description, "Wi-Fi with Internet connectivity") 118 | } 119 | 120 | func testDescriptionForWiFiWithoutInternetIsCorrect() { 121 | let sut = ConnectivityState.wifiWithoutInternet 122 | XCTAssertEqual(sut.description, "Wi-Fi without Internet connectivity") 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /Example/Tests/ConnectivitySubscriptionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConnectivitySubscriptionTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 15/05/2020. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | import Network 12 | import XCTest 13 | @testable import Hyperconnectivity 14 | 15 | class ConnectivitySubscriptionTests: XCTestCase { 16 | private let timeout: TimeInterval = 5.0 17 | 18 | private func sut(subscriber: Subscribers.Sink? = nil, connectivity: Connectivity? = nil) -> ConnectivitySubscription> { 19 | let mockSubscriber = subscriber ?? Subscribers.Sink(receiveCompletion: { _ in }) { _ in } 20 | let mockConfiguration = Hyperconnectivity.Configuration() 21 | return ConnectivitySubscription( 22 | configuration: mockConfiguration, 23 | connectivity: connectivity, 24 | subscriber: mockSubscriber 25 | ) 26 | } 27 | 28 | func testNotifierStartedWhenSubscriptionCreated() { 29 | let mockConfiguration = Hyperconnectivity.Configuration() 30 | let mockConnectivity = MockConnectivity(configuration: mockConfiguration) 31 | _ = sut(connectivity: mockConnectivity) 32 | XCTAssertTrue(mockConnectivity.startNotifierInvoked) 33 | } 34 | 35 | func testNotifierStoppedWhenSubscriptionCancelled() { 36 | let mockConfiguration = Hyperconnectivity.Configuration() 37 | let mockConnectivity = MockConnectivity(configuration: mockConfiguration) 38 | let sut = self.sut(connectivity: mockConnectivity) 39 | sut.cancel() 40 | XCTAssertTrue(mockConnectivity.stopNotifierInvoked) 41 | } 42 | 43 | func testNotificationSentWhenSubscriptionCreated() { 44 | expectation( 45 | forNotification: .ConnectivityDidStart, 46 | object: nil, 47 | handler: nil 48 | ) 49 | _ = sut() 50 | waitForExpectations(timeout: timeout, handler: nil) 51 | } 52 | 53 | func testNotificationSentWhenSubscriptionCancelled() { 54 | expectation( 55 | forNotification: .ConnectivityDidFinish, 56 | object: nil, 57 | handler: nil 58 | ) 59 | let sut = self.sut() 60 | sut.cancel() 61 | waitForExpectations(timeout: timeout, handler: nil) 62 | } 63 | 64 | func testSubscriberCompletesWhenSubscriptionCancelled() { 65 | let connectivityFinishedExpectation = expectation(description: "Connectivity finished") 66 | let mockSubscriber = Subscribers.Sink(receiveCompletion: { _ in 67 | connectivityFinishedExpectation.fulfill() 68 | }) { _ in} 69 | let sut = self.sut(subscriber: mockSubscriber) 70 | sut.cancel() 71 | waitForExpectations(timeout: timeout, handler: nil) 72 | } 73 | 74 | func testSubscriberNotifiedWhenConnectivityChanged() { 75 | let mockConfiguration = Hyperconnectivity.Configuration() 76 | let connectivityChangedExpectation = expectation(description: "Connectivity changed") 77 | let mockSubscriber = Subscribers.Sink(receiveCompletion: { _ in }) { _ in 78 | connectivityChangedExpectation.fulfill() 79 | } 80 | let mockConnectivity = MockConnectivity(configuration: mockConfiguration) 81 | _ = sut(subscriber: mockSubscriber, connectivity: mockConnectivity) 82 | let mockPath = MockPath(interfaceType: .wiredEthernet) 83 | let mockResult = ConnectivityResult(path: mockPath, successThreshold: Percentage(100.0), totalChecks: 0) 84 | mockConnectivity.connectivityChanged?(mockResult) 85 | waitForExpectations(timeout: timeout, handler: nil) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Example/Tests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/MockConnectivity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockConnectivity.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | @testable import Hyperconnectivity 11 | 12 | class MockConnectivity: Connectivity { 13 | var connectivityChanged: Hyperconnectivity.ConnectivityChanged? 14 | var initInvoked = false 15 | var startNotifierInvoked = false 16 | var stopNotifierInvoked = false 17 | 18 | required init(configuration: Hyperconnectivity.Configuration) { 19 | initInvoked = true 20 | } 21 | 22 | func startNotifier() { 23 | startNotifierInvoked = true 24 | } 25 | 26 | func stopNotifier() { 27 | stopNotifierInvoked = true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Example/Tests/MockPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockPath.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Network 11 | @testable import Hyperconnectivity 12 | 13 | struct MockPath: Path { 14 | var isExpensive: Bool = false 15 | private let interfaceType: NWInterface.InterfaceType? 16 | 17 | init(interfaceType: NWInterface.InterfaceType?) { 18 | self.interfaceType = interfaceType 19 | } 20 | 21 | func usesInterfaceType(_ type: NWInterface.InterfaceType) -> Bool { 22 | return interfaceType == type 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Example/Tests/NonCachingURLSessionConfigurationFactoryTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonCachingURLSessionConfigurationFactoryTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 20/03/2022. 6 | // Copyright © 2022 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | @testable import Hyperconnectivity 11 | import XCTest 12 | 13 | class NonCachingURLSessionConfigurationFactoryTests: XCTestCase { 14 | /// Tests that given a `URLSessionConfiguration` object with a response cache set, the factory will return a `URLSessionConfiguration` object which does not cache. 15 | func testResponseCachingIsDisabled() { 16 | let sut = NonCachingURLSessionConfigurationFactory() 17 | let originalURLSessionConfiguration = URLSessionConfiguration.default 18 | XCTAssertNotNil(originalURLSessionConfiguration.urlCache) 19 | let newURLSessionConfiguration = sut.urlSessionConfiguration(from: originalURLSessionConfiguration) 20 | XCTAssertNil(newURLSessionConfiguration.urlCache, "URL cache should be nil.") 21 | } 22 | 23 | /// Tests that the `URLSessionConfiguration` passed as input to the factory is copied i.e. the output of the factory is a different object. 24 | func testThatFactoryProducesACopy() { 25 | let sut = NonCachingURLSessionConfigurationFactory() 26 | let originalURLSessionConfiguration = URLSessionConfiguration.default 27 | let newURLSessionConfiguration = sut.urlSessionConfiguration(from: originalURLSessionConfiguration) 28 | XCTAssertFalse(originalURLSessionConfiguration === newURLSessionConfiguration) 29 | } 30 | 31 | /// Tests that given a `URLSessionConfiguration` object passed as input to the factory, the request caching policy of the output ignores the local cache. 32 | func testRequestCachePolicyIgnoresLocalCache() { 33 | let sut = NonCachingURLSessionConfigurationFactory() 34 | let originalURLSessionConfiguration = URLSessionConfiguration.default 35 | XCTAssertEqual(originalURLSessionConfiguration.requestCachePolicy, .useProtocolCachePolicy) 36 | let newURLSessionConfiguration = sut.urlSessionConfiguration(from: originalURLSessionConfiguration) 37 | XCTAssertEqual(newURLSessionConfiguration.requestCachePolicy, .reloadIgnoringLocalCacheData) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Example/Tests/PercentageTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PercentageTests.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 09/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Hyperconnectivity 11 | 12 | class PercentageTests: XCTestCase { 13 | 14 | func testMidRangeValueApplied() { 15 | let sut = Percentage(50.0) 16 | XCTAssertEqual(sut.value, 50.0) 17 | } 18 | 19 | func testLowerBoundaryValueApplied() { 20 | let sut = Percentage(0.0) 21 | XCTAssertEqual(sut.value, 0.0) 22 | } 23 | 24 | func testUpperBoundaryValueApplied() { 25 | let sut = Percentage(100.0) 26 | XCTAssertEqual(sut.value, 100.0) 27 | } 28 | 29 | func testOutOfLowerBoundValueNotApplied() { 30 | let sut = Percentage(-0.1) 31 | XCTAssertEqual(sut.value, 0.0) 32 | } 33 | 34 | func testOutOfUpperBoundValueNotApplied() { 35 | let sut = Percentage(100.1) 36 | XCTAssertEqual(sut.value, 100.0) 37 | } 38 | 39 | func testPercentageCalculatedWithMidRangeUIntValues() { 40 | let sut = Percentage(UInt(2), outOf: UInt(10)) 41 | XCTAssertEqual(sut.value, 20.0) 42 | } 43 | 44 | func testPercentageCalculatedWithLowerBoundaryUIntValues() { 45 | let sut = Percentage(UInt(0), outOf: UInt(1)) 46 | XCTAssertEqual(sut.value, 0.0) 47 | } 48 | 49 | func testPercentageCalculatedIsZeroWhenDivisorIsZero() { 50 | let sut = Percentage(UInt(1), outOf: UInt(0)) 51 | XCTAssertEqual(sut.value, 0.0) 52 | } 53 | 54 | func testPercentageNotLessThanSameValue() { 55 | XCTAssertFalse(Percentage(0.0) < Percentage(0.0)) 56 | } 57 | 58 | func testPercentageIsLessThanGreaterValue() { 59 | XCTAssertTrue(Percentage(0.0) < Percentage(0.1)) 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Example/Tests/ReachabilityPublisherTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReachabilityPublisherTests.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Combine 10 | import Foundation 11 | #if canImport(OHHTTPStubsSwift) 12 | import OHHTTPStubsSwift 13 | #endif 14 | import XCTest 15 | @testable import Hyperconnectivity 16 | 17 | class ReachabilityPublisherTests: XCTestCase { 18 | private var cancellable: AnyCancellable? 19 | private let timeout: TimeInterval = 5.0 20 | 21 | func testSubscriberInvokedOnSuccessfulReachabilityCheck() throws { 22 | let expectation = XCTestExpectation(description: "Reachability check succeeds") 23 | cancellable = Publishers.Reachability().sink(receiveCompletion: { _ in 24 | }, receiveValue: { result in 25 | XCTAssert(result.connection == .wifi || result.connection == .ethernet) 26 | XCTAssertTrue(result.isReachable) 27 | expectation.fulfill() 28 | }) 29 | wait(for: [expectation], timeout: timeout) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Tests/ResponseContainsStringValidatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseContainsStringValidatorTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import OHHTTPStubs 11 | #if canImport(OHHTTPStubsSwift) 12 | import OHHTTPStubsSwift 13 | #endif 14 | import XCTest 15 | @testable import Hyperconnectivity 16 | 17 | class ResponseContainsStringValidatorTests: XCTestCase { 18 | private let timeout: TimeInterval = 5.0 19 | 20 | override func tearDown() { 21 | super.tearDown() 22 | HTTPStubs.removeAllStubs() 23 | } 24 | 25 | private func stubHost(_ host: String, withHTMLFrom fileName: String) throws { 26 | #if SWIFT_PACKAGE 27 | let bundle = Bundle.module 28 | #else 29 | let bundle = Bundle(for: type(of: self)) 30 | #endif 31 | let fileURL = bundle.url( 32 | forResource: (fileName as NSString).deletingPathExtension, 33 | withExtension: (fileName as NSString).pathExtension 34 | ) 35 | let stubPath = try XCTUnwrap(fileURL?.relativePath) 36 | stub(condition: isHost(host)) { _ in 37 | return fixture(filePath: stubPath, headers: ["Content-Type": "text/html"]) 38 | } 39 | } 40 | 41 | /// Test response is valid when the response string contains the expected response. 42 | func testContainsExpectedResponseString() throws { 43 | try stubHost("www.apple.com", withHTMLFrom: "string-contains-response.html") 44 | let expectation = XCTestExpectation(description: "Connectivity check succeeds") 45 | let config = Hyperconnectivity.Configuration(responseValidator: ResponseContainsStringValidator(expectedResponse: "Success")) 46 | let connectivity = Hyperconnectivity(configuration: config) 47 | let connectivityChanged: (ConnectivityResult) -> Void = { result in 48 | XCTAssert(result.state == .wifiWithInternet || result.state == .ethernetWithInternet) 49 | expectation.fulfill() 50 | } 51 | connectivity.connectivityChanged = connectivityChanged 52 | connectivity.startNotifier() 53 | wait(for: [expectation], timeout: timeout) 54 | connectivity.stopNotifier() 55 | } 56 | 57 | /// Test response is valid when the response string does not contain the expected response. 58 | func testDoesNotContainExpectedResponseString() throws { 59 | try stubHost("www.apple.com", withHTMLFrom: "string-contains-response.html") 60 | let expectation = XCTestExpectation(description: "Connectivity check succeeds") 61 | let config = Hyperconnectivity.Configuration(responseValidator: ResponseContainsStringValidator(expectedResponse: "Failure")) 62 | let connectivity = Hyperconnectivity(configuration: config) 63 | let connectivityChanged: (ConnectivityResult) -> Void = { result in 64 | XCTAssert(result.state == .wifiWithoutInternet || result.state == .ethernetWithoutInternet) 65 | expectation.fulfill() 66 | } 67 | connectivity.connectivityChanged = connectivityChanged 68 | connectivity.startNotifier() 69 | wait(for: [expectation], timeout: timeout) 70 | connectivity.stopNotifier() 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Example/Tests/ResponseRegExValidatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseRegExValidatorTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | @testable import Hyperconnectivity 12 | 13 | class ResponseRegExValidatorTests: XCTestCase { 14 | func testRegexStringValidation() throws { 15 | try checkValid(string: "test1234", matchedBy: "test[0-9]+", expectedResult: true) 16 | try checkValid(string: "testa1234", matchedBy: "test[0-9]+", expectedResult: false) 17 | } 18 | 19 | private func checkValid( 20 | string: String, 21 | matchedBy regEx: String, 22 | expectedResult: Bool, 23 | file: StaticString = #file, 24 | line: UInt = #line 25 | ) throws { 26 | let validator = ResponseRegExValidator(regEx: regEx) 27 | let data = try XCTUnwrap(string.data(using: .utf8)) 28 | let url = try XCTUnwrap(URL(string: "https://example.com")) 29 | let response = URLResponse(url: url, mimeType: nil, expectedContentLength: data.count, textEncodingName: nil) 30 | let result = validator.isResponseValid(response, data: data) 31 | let expectedResultStr = expectedResult ? "match" : "not match" 32 | let message = "Expected \"\(string)\" to \(expectedResultStr) \(regEx) via regex" 33 | XCTAssertEqual(result, expectedResult, message, file: file, line: line) 34 | } 35 | 36 | func testResponseInvalidWhenDataIsNil() throws { 37 | let regEx = "test[0-9]+" 38 | let validator = ResponseRegExValidator(regEx: regEx) 39 | let url = try XCTUnwrap(URL(string: "https://example.com")) 40 | let data = try XCTUnwrap("".data(using: .utf8)) 41 | let response = URLResponse(url: url, mimeType: nil, expectedContentLength: 0, textEncodingName: nil) 42 | let responseValid = validator.isResponseValid(response, data: data) 43 | XCTAssertFalse(responseValid) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/Tests/ResponseStringEqualityValidatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseStringValidatorTests.swift 3 | // Hyperconnectivity_Tests 4 | // 5 | // Created by Ross Butler on 17/05/2020. 6 | // Copyright © 2020 Ross Butler. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import OHHTTPStubs 11 | #if canImport(OHHTTPStubsSwift) 12 | import OHHTTPStubsSwift 13 | #endif 14 | import XCTest 15 | @testable import Hyperconnectivity 16 | 17 | class ResponseStringEqualityValidatorTests: XCTestCase { 18 | private let timeout: TimeInterval = 5.0 19 | 20 | override func tearDown() { 21 | super.tearDown() 22 | HTTPStubs.removeAllStubs() 23 | } 24 | 25 | private func stubHost(_ host: String, withHTMLFrom fileName: String) throws { 26 | #if SWIFT_PACKAGE 27 | let bundle = Bundle.module 28 | #else 29 | let bundle = Bundle(for: type(of: self)) 30 | #endif 31 | let fileURL = bundle.url( 32 | forResource: (fileName as NSString).deletingPathExtension, 33 | withExtension: (fileName as NSString).pathExtension 34 | ) 35 | let stubPath = try XCTUnwrap(fileURL?.relativePath) 36 | stub(condition: isHost(host)) { _ in 37 | return fixture(filePath: stubPath, headers: ["Content-Type": "text/html"]) 38 | } 39 | } 40 | 41 | /// Test response is valid when the response string is equal to the expected response. 42 | func testEqualsExpectedResponseString() throws { 43 | try stubHost("www.apple.com", withHTMLFrom: "string-equality-response.html") 44 | let expectation = XCTestExpectation(description: "Connectivity check succeeds") 45 | let config = Hyperconnectivity.Configuration(responseValidator: ResponseStringEqualityValidator(expectedResponse: "Success")) 46 | let connectivity = Hyperconnectivity(configuration: config) 47 | let connectivityChanged: (ConnectivityResult) -> Void = { result in 48 | XCTAssert(result.state == .wifiWithInternet || result.state == .ethernetWithInternet) 49 | expectation.fulfill() 50 | } 51 | connectivity.connectivityChanged = connectivityChanged 52 | connectivity.startNotifier() 53 | wait(for: [expectation], timeout: timeout) 54 | connectivity.stopNotifier() 55 | } 56 | 57 | /// Test response is valid when the response string is equal to the expected response. 58 | func testEqualsExpectedSpecifiedResponseString() throws { 59 | try stubHost("www.apple.com", withHTMLFrom: "string-equality-response.html") 60 | let expectation = XCTestExpectation(description: "Connectivity check succeeds") 61 | let config = Hyperconnectivity.Configuration(responseValidator: ResponseStringEqualityValidator(expectedResponse: "Success")) 62 | let connectivity = Hyperconnectivity(configuration: config) 63 | let connectivityChanged: (ConnectivityResult) -> Void = { result in 64 | XCTAssert(result.state == .wifiWithInternet || result.state == .ethernetWithInternet) 65 | expectation.fulfill() 66 | } 67 | connectivity.connectivityChanged = connectivityChanged 68 | connectivity.startNotifier() 69 | wait(for: [expectation], timeout: timeout) 70 | connectivity.stopNotifier() 71 | } 72 | 73 | /// Test response is invalid when the response string is not equal to the expected response. 74 | func testNotEqualsExpectedResponseString() throws { 75 | try stubHost("www.apple.com", withHTMLFrom: "string-contains-response.html") 76 | let expectation = XCTestExpectation(description: "Connectivity check fails") 77 | let config = Hyperconnectivity.Configuration(responseValidator: ResponseStringEqualityValidator(expectedResponse: "Success")) 78 | let connectivity = Hyperconnectivity(configuration: config) 79 | let connectivityChanged: (ConnectivityResult) -> Void = { result in 80 | XCTAssert(result.state == .wifiWithoutInternet || result.state == .ethernetWithoutInternet) 81 | expectation.fulfill() 82 | } 83 | connectivity.connectivityChanged = connectivityChanged 84 | connectivity.startNotifier() 85 | wait(for: [expectation], timeout: timeout) 86 | connectivity.stopNotifier() 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Example/Tests/failure-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | 7 | 8 | 9 | 10 | 13 |
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /Example/Tests/string-contains-response.html: -------------------------------------------------------------------------------- 1 | 2 | Successful 3 | 4 | -------------------------------------------------------------------------------- /Example/Tests/string-equality-response.html: -------------------------------------------------------------------------------- 1 | Success 2 | -------------------------------------------------------------------------------- /Hyperconnectivity.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Hyperconnectivity' 3 | s.version = '1.1.1' 4 | s.swift_version = '5.0' 5 | s.summary = 'Modern replacement for Apple\'s Reachability written in Swift and made elegant using Combine' 6 | s.description = <<-DESC 7 | Hyperconnectivity provides Internet connectivity and captive portal detection in Swift using Combine. 8 | DESC 9 | s.homepage = 'https://github.com/rwbutler/Hyperconnectivity' 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { 'Ross Butler' => 'github@rwbutler.com' } 12 | s.source = { :git => 'https://github.com/rwbutler/Hyperconnectivity.git', :tag => s.version.to_s } 13 | s.social_media_url = 'https://twitter.com/ross_w_butler' 14 | s.ios.deployment_target = '13.0' 15 | s.frameworks = 'Combine', 'Network' 16 | s.source_files = 'Hyperconnectivity/Classes/**/*' 17 | end 18 | -------------------------------------------------------------------------------- /Hyperconnectivity/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwbutler/Hyperconnectivity/0503595f9ab5bfdef6c06c2d8c2712cb50213259/Hyperconnectivity/Assets/.gitkeep -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwbutler/Hyperconnectivity/0503595f9ab5bfdef6c06c2d8c2712cb50213259/Hyperconnectivity/Classes/.gitkeep -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/ConnectivityPublisher.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Publisher.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Combine 9 | import Foundation 10 | 11 | public struct ConnectivityPublisher: Publisher { 12 | 13 | // MARK: - Type Definitions 14 | public typealias Configuration = Hyperconnectivity.Configuration 15 | public typealias Failure = Never 16 | public typealias Output = ConnectivityResult 17 | 18 | // MARK: State 19 | private let configuration: Configuration 20 | 21 | public init(configuration: Configuration = Configuration()) { 22 | self.configuration = configuration 23 | } 24 | 25 | public func receive(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input { 26 | let subscription = ConnectivitySubscription(configuration: configuration, subscriber: subscriber) 27 | subscriber.receive(subscription: subscription) 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/ConnectivitySubscription.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Subscription.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Combine 10 | 11 | protocol Connectivity { 12 | var connectivityChanged: Hyperconnectivity.ConnectivityChanged? { get set } 13 | init(configuration: Hyperconnectivity.Configuration) 14 | func startNotifier() 15 | func stopNotifier() 16 | } 17 | 18 | extension Hyperconnectivity: Connectivity {} 19 | 20 | class ConnectivitySubscription: Subscription where S.Input == ConnectivityResult, S.Failure == Never { 21 | private let configuration: Hyperconnectivity.Configuration 22 | private var connectivity: Connectivity? 23 | private var subscriber: S? 24 | 25 | init(configuration: Hyperconnectivity.Configuration, connectivity: Connectivity? = nil, subscriber: S) { 26 | self.configuration = configuration 27 | self.connectivity = connectivity 28 | self.subscriber = subscriber 29 | startNotifier(with: subscriber) 30 | } 31 | 32 | func cancel() { 33 | stopNotifier() 34 | } 35 | 36 | func request(_: Subscribers.Demand) {} 37 | } 38 | 39 | private extension ConnectivitySubscription { 40 | 41 | private func startNotifier(with subscriber: S) { 42 | connectivity = connectivity ?? Hyperconnectivity(configuration: configuration) 43 | let connectivityChanged: (ConnectivityResult) -> Void = { connectivity in 44 | _ = subscriber.receive(connectivity) 45 | } 46 | connectivity?.connectivityChanged = connectivityChanged 47 | connectivity?.startNotifier() 48 | } 49 | 50 | private func stopNotifier() { 51 | connectivity?.stopNotifier() 52 | connectivity = nil 53 | subscriber?.receive(completion: Subscribers.Completion.finished) 54 | subscriber = nil 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/NonCachingURLSessionConfigurationFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonCachingURLSessionConfigurationFactory.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 20/03/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct NonCachingURLSessionConfigurationFactory { 11 | func urlSessionConfiguration(from input: URLSessionConfiguration) -> URLSessionConfiguration { 12 | // Ensure that we never use cached results, including where using a custom `URLSessionConfiguration`. 13 | let output = input.copy() as! URLSessionConfiguration 14 | output.requestCachePolicy = .reloadIgnoringCacheData 15 | output.urlCache = nil 16 | return output 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/Publishers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Publishers.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Combine 10 | 11 | extension Publishers { 12 | public typealias Connectivity = ConnectivityPublisher 13 | public typealias Reachability = ReachabilityPublisher 14 | } 15 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/ReachabilityPublisher.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReachabilityPublisher.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Combine 9 | import Foundation 10 | 11 | public struct ReachabilityPublisher: Publisher { 12 | 13 | // MARK: - Type Definitions 14 | public typealias Configuration = Hyperconnectivity.Configuration 15 | public typealias Failure = Never 16 | public typealias Output = ReachabilityResult 17 | 18 | // MARK: State 19 | private let configuration: Configuration 20 | 21 | public init(configuration: Configuration = Configuration()) { 22 | self.configuration = configuration.cloneForReachability() 23 | } 24 | 25 | public func receive(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input { 26 | let subscription = ReachabilitySubscription(configuration: configuration, subscriber: subscriber) 27 | subscriber.receive(subscription: subscription) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Combine/ReachabilitySubscription.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReachabilitySubscription.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Combine 10 | 11 | class ReachabilitySubscription: Subscription where S.Input == ReachabilityResult, S.Failure == Never { 12 | private let configuration: Hyperconnectivity.Configuration 13 | private var connectivity: Hyperconnectivity? 14 | private var subscriber: S? 15 | 16 | init(configuration: Hyperconnectivity.Configuration, subscriber: S) { 17 | self.configuration = configuration.cloneForReachability() 18 | self.subscriber = subscriber 19 | startNotifier(with: subscriber) 20 | } 21 | 22 | func cancel() { 23 | stopNotifier() 24 | } 25 | 26 | func request(_: Subscribers.Demand) {} 27 | } 28 | 29 | private extension ReachabilitySubscription { 30 | 31 | private func startNotifier(with subscriber: S) { 32 | connectivity = Hyperconnectivity(configuration: configuration) 33 | let reachabilityChanged: (ReachabilityResult) -> Void = { reachability in 34 | _ = subscriber.receive(reachability) 35 | } 36 | connectivity?.reachabilityChanged = reachabilityChanged 37 | connectivity?.startNotifier() 38 | } 39 | 40 | private func stopNotifier() { 41 | connectivity?.stopNotifier() 42 | connectivity = nil 43 | subscriber?.receive(completion: Subscribers.Completion.finished) 44 | subscriber = nil 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Core/Hyperconnectivity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Hyperconnectivity.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Combine 9 | import Foundation 10 | import Network 11 | 12 | public class Hyperconnectivity { 13 | 14 | // MARK: Type declarations 15 | public typealias Configuration = HyperconnectivityConfiguration 16 | public typealias ConnectivityChanged = (ConnectivityResult) -> Void 17 | public typealias Publisher = ConnectivityPublisher 18 | public typealias ReachabilityChanged = (ReachabilityResult) -> Void 19 | public typealias State = ConnectivityState 20 | 21 | // MARK: State 22 | private var cancellable: AnyCancellable? 23 | private let configuration: Configuration 24 | internal var connectivityChanged: ConnectivityChanged? 25 | private let notifier = NotificationCenter.default 26 | private var pathMonitor: NWPathMonitor? 27 | internal var reachabilityChanged: ReachabilityChanged? 28 | 29 | required init(configuration: Configuration = Configuration()) { 30 | self.configuration = configuration 31 | } 32 | 33 | func startNotifier() { 34 | let configuration = self.configuration 35 | let pathMonitor = NWPathMonitor() 36 | pathMonitor.pathUpdateHandler = { [weak self] path in 37 | self?.pathUpdated(path, with: configuration) 38 | } 39 | self.pathMonitor = pathMonitor 40 | notifier.post(name: .ConnectivityDidStart, object: nil) 41 | pathMonitor.start(queue: configuration.connectivityQueue) 42 | } 43 | 44 | func stopNotifier() { 45 | cancellable?.cancel() 46 | cancellable = nil 47 | notifier.post(name: .ConnectivityDidFinish, object: nil) 48 | pathMonitor = nil 49 | } 50 | } 51 | 52 | private extension Hyperconnectivity { 53 | private func checkConnectivity(of path: NWPath, using configuration: Configuration) { 54 | let factory = NonCachingURLSessionConfigurationFactory() 55 | let urlSessionConfiguration = factory.urlSessionConfiguration(from: configuration.urlSessionConfiguration) 56 | let publishers = configuration.connectivityURLRequests.map { urlRequest in 57 | URLSession(configuration: urlSessionConfiguration).dataTaskPublisher(for: urlRequest) 58 | } 59 | let totalChecks = UInt(configuration.connectivityURLRequests.count) 60 | let result = ConnectivityResult(path: path, successThreshold: configuration.successThreshold, totalChecks: totalChecks) 61 | let combinedPublisher = Publishers.MergeMany(publishers) 62 | cancellable = combinedPublisher.sink(receiveCompletion:{ [weak self] _ in 63 | self?.connectivityChanged(result) 64 | }, receiveValue: { [weak self] response in 65 | result.connectivityCheck(successful: configuration.isResponseValid(response)) 66 | guard result.isConnected else { 67 | return 68 | } 69 | self?.connectivityChanged(result) 70 | }) 71 | } 72 | 73 | private func connectivityChanged(_ result: ConnectivityResult) { 74 | connectivityChanged?(result) 75 | cancellable?.cancel() 76 | notifier.post(name: .ConnectivityDidChange, object: result) 77 | } 78 | 79 | private func handleReachability(for path: NWPath) { 80 | let result = ReachabilityResult(path: path) 81 | reachabilityChanged?(result) 82 | } 83 | 84 | /// Invoked on `NWPath` change by `pathUpdateHandler`. 85 | private func pathUpdated(_ path: NWPath, with configuration: Configuration) { 86 | handleReachability(for: path) 87 | if configuration.shouldCheckConnectivity { 88 | checkConnectivity(of: path, using: configuration) 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/Configuration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Configuration.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct HyperconnectivityConfiguration { 11 | public static let defaultConnectivityURLs = [ 12 | URL(string: "https://www.apple.com/library/test/success.html"), 13 | URL(string: "https://captive.apple.com/hotspot-detect.html") 14 | ].compactMap { $0 } 15 | 16 | public static let defaultURLSessionConfiguration: URLSessionConfiguration = { 17 | let sessionConfiguration = URLSessionConfiguration.default 18 | sessionConfiguration.requestCachePolicy = .reloadIgnoringCacheData 19 | sessionConfiguration.urlCache = nil 20 | sessionConfiguration.timeoutIntervalForRequest = 5.0 21 | sessionConfiguration.timeoutIntervalForResource = 5.0 22 | return sessionConfiguration 23 | }() 24 | 25 | let callbackQueue: DispatchQueue 26 | let connectivityQueue: DispatchQueue 27 | let connectivityURLRequests: [URLRequest] 28 | let responseValidator: ResponseValidator 29 | let shouldCheckConnectivity: Bool 30 | 31 | /// % successful connections required to be deemed to have connectivity 32 | let successThreshold: Percentage 33 | let urlSessionConfiguration: URLSessionConfiguration 34 | 35 | public init( 36 | callbackQueue: DispatchQueue = DispatchQueue.main, 37 | connectivityQueue: DispatchQueue = DispatchQueue.global(qos: .utility), 38 | connectivityURLs: [URL] = Self.defaultConnectivityURLs, 39 | responseValidator: ResponseValidator? = nil, 40 | shouldCheckConnectivity: Bool = true, 41 | successThreshold: Percentage = Percentage(50.0), 42 | urlSessionConfiguration: URLSessionConfiguration = Self.defaultURLSessionConfiguration 43 | ) { 44 | self.init( 45 | callbackQueue: callbackQueue, 46 | connectivityQueue: connectivityQueue, 47 | connectivityURLRequests: connectivityURLs.map { URLRequest(url: $0) }, 48 | responseValidator: responseValidator, 49 | shouldCheckConnectivity: shouldCheckConnectivity, 50 | successThreshold: successThreshold, 51 | urlSessionConfiguration: urlSessionConfiguration 52 | ) 53 | } 54 | 55 | public init( 56 | callbackQueue: DispatchQueue = DispatchQueue.main, 57 | connectivityQueue: DispatchQueue = DispatchQueue.global(qos: .utility), 58 | connectivityURLRequests: [URLRequest], 59 | responseValidator: ResponseValidator? = nil, 60 | shouldCheckConnectivity: Bool = true, 61 | successThreshold: Percentage = Percentage(50.0), 62 | urlSessionConfiguration: URLSessionConfiguration = Self.defaultURLSessionConfiguration 63 | ) { 64 | let defaultValidator = ResponseStringValidator( 65 | validationMode: .containsExpectedResponseString 66 | ) 67 | self.callbackQueue = callbackQueue 68 | self.connectivityQueue = connectivityQueue 69 | self.connectivityURLRequests = connectivityURLRequests 70 | self.responseValidator = responseValidator ?? defaultValidator 71 | self.shouldCheckConnectivity = shouldCheckConnectivity 72 | self.successThreshold = successThreshold 73 | self.urlSessionConfiguration = urlSessionConfiguration 74 | } 75 | 76 | func cloneForReachability() -> Self { 77 | return HyperconnectivityConfiguration( 78 | callbackQueue: callbackQueue, 79 | connectivityQueue: connectivityQueue, 80 | connectivityURLs: [], 81 | responseValidator: responseValidator, 82 | shouldCheckConnectivity: false, 83 | successThreshold: Percentage(0.0), 84 | urlSessionConfiguration: urlSessionConfiguration) 85 | } 86 | 87 | /// Convenience method for determining whether or not the response is valid. 88 | func isResponseValid(_ response: (Data, URLResponse)) -> Bool { 89 | responseValidator.isResponseValid(response.1, data: response.0) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/Connection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Connection.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Network 10 | 11 | protocol Path { 12 | var isExpensive: Bool { get } 13 | func usesInterfaceType(_ type: NWInterface.InterfaceType) -> Bool 14 | } 15 | 16 | extension NWPath: Path {} 17 | 18 | public enum Connection { 19 | case cellular 20 | case disconnected 21 | case ethernet 22 | case loopback 23 | case other 24 | case wifi 25 | 26 | init(_ path: Path) { 27 | if path.usesInterfaceType(.wiredEthernet) { 28 | self = .ethernet 29 | } else if path.usesInterfaceType(.wifi) { 30 | self = .wifi 31 | } else if path.usesInterfaceType(.cellular) { 32 | self = .cellular 33 | } else if path.usesInterfaceType(.other) { 34 | self = .other 35 | } else if path.usesInterfaceType(.loopback) { 36 | self = .loopback 37 | } else { 38 | self = .disconnected 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/ConnectivityResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Result.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Network 10 | 11 | public class ConnectivityResult { 12 | public let connection: Connection 13 | public var isConnected: Bool { 14 | isThresholdMet(successPercentage, threshold: successThreshold) 15 | } 16 | public let isExpensive: Bool 17 | public var state: Hyperconnectivity.State { 18 | Hyperconnectivity.State(connection: connection, isConnected: isConnected) 19 | } 20 | private var successfulChecks: UInt = 0 21 | private let successThreshold: Percentage 22 | private let totalChecks: UInt 23 | private var successPercentage: Percentage { 24 | Percentage(successfulChecks, outOf: totalChecks) 25 | } 26 | 27 | init(path: Path, successThreshold: Percentage, totalChecks: UInt) { 28 | connection = Connection(path) 29 | isExpensive = path.isExpensive 30 | self.successThreshold = successThreshold 31 | self.totalChecks = totalChecks 32 | } 33 | 34 | func connectivityCheck(successful: Bool) { 35 | if successful { 36 | successfulChecks += 1 37 | } 38 | } 39 | 40 | private func isThresholdMet(_ percentage: Percentage, threshold: Percentage) -> Bool { 41 | return percentage >= threshold 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/ConnectivityState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // State.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum ConnectivityState { 11 | case cellularWithInternet 12 | case cellularWithoutInternet 13 | case disconnected 14 | case ethernetWithInternet 15 | case ethernetWithoutInternet 16 | case loopback 17 | case otherWithInternet 18 | case otherWithoutInternet 19 | case wifiWithInternet 20 | case wifiWithoutInternet 21 | 22 | init(connection: Connection, isConnected: Bool) { 23 | switch connection { 24 | case .cellular: 25 | self = (isConnected) ? .cellularWithInternet : .cellularWithoutInternet 26 | case .disconnected: 27 | self = .disconnected 28 | case .ethernet: 29 | self = (isConnected) ? .ethernetWithInternet : .ethernetWithoutInternet 30 | case .loopback: 31 | self = .loopback 32 | case .other: 33 | self = (isConnected) ? .otherWithInternet : .otherWithoutInternet 34 | case .wifi: 35 | self = (isConnected) ? .wifiWithInternet : .wifiWithoutInternet 36 | } 37 | } 38 | } 39 | 40 | extension ConnectivityState: CustomStringConvertible { 41 | public var description: String { 42 | switch self { 43 | case .cellularWithInternet: 44 | return "Cellular with Internet connectivity" 45 | case .cellularWithoutInternet: 46 | return "Cellular without Internet connectivity" 47 | case .disconnected: 48 | return "Disconnected" 49 | case .ethernetWithInternet: 50 | return "Ethernet with Internet connectivity" 51 | case .ethernetWithoutInternet: 52 | return "Ethernet without Internet connectivity" 53 | case .loopback: 54 | return "Loopback" 55 | case .otherWithInternet: 56 | return "Other with Internet connectivity" 57 | case .otherWithoutInternet: 58 | return "Other without Internet connectivity" 59 | case .wifiWithInternet: 60 | return "Wi-Fi with Internet connectivity" 61 | case .wifiWithoutInternet: 62 | return "Wi-Fi without Internet connectivity" 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/Notification.Name.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Notification.Name.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 16/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Notification.Name { 11 | 12 | // Connectivity 13 | public static let ConnectivityDidStart = Notification.Name("kNetworkConnectivityStartedNotification") 14 | public static let ConnectivityDidChange = Notification.Name("kNetworkConnectivityChangedNotification") 15 | public static let ConnectivityDidFinish = Notification.Name("kNetworkConnectivityFinishedNotification") 16 | 17 | // Reachability 18 | public static let ReachabilityDidChange = Notification.Name("kNetworkReachabilityChangedNotification") 19 | } 20 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/Percentage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Percentage.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 07/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct Percentage: Comparable { 11 | let value: Double 12 | 13 | public init(_ value: Double) { 14 | var result = value < 0.0 ? 0.0 : value 15 | result = result > 100.0 ? 100.0 : result 16 | self.value = result 17 | } 18 | 19 | public init(_ value: UInt, outOf total: UInt) { 20 | self.init(Double(value), outOf: Double(total)) 21 | } 22 | 23 | public init(_ value: Double, outOf total: Double) { 24 | guard total > 0 else { 25 | self.init(0.0) 26 | return 27 | } 28 | self.init((value / total) * 100.0) 29 | } 30 | 31 | public static func < (lhs: Self, rhs: Self) -> Bool { 32 | return lhs.value < rhs.value 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Model/ReachabilityResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReachabilityResult.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | import Network 10 | 11 | public struct ReachabilityResult { 12 | 13 | public let connection: Connection 14 | public let isExpensive: Bool 15 | public let isReachable: Bool 16 | 17 | init(path: NWPath) { 18 | connection = Connection(path) 19 | isExpensive = path.isExpensive 20 | isReachable = path.status == .satisfied 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Response Validation/ResponseContainsStringValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseContainsValidator.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public class ResponseContainsStringValidator: ResponseValidator { 11 | 12 | /// The `String` expected to be contained in the response 13 | public let expectedResponse: String 14 | 15 | /// Initializes the receiver to validate that the response `String` contains the expected response. 16 | /// 17 | /// - Parameter expectedResponse: The `String` expected to be contained in the response. 18 | public init(expectedResponse: String = "Success") { 19 | self.expectedResponse = expectedResponse 20 | } 21 | 22 | public func isResponseValid(_ response: URLResponse, data: Data) -> Bool { 23 | guard let responseString = String(data: data, encoding: .utf8) else { 24 | return false 25 | } 26 | return responseString.contains(expectedResponse) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Response Validation/ResponseRegExValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseRegExValidator.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public class ResponseRegExValidator: ResponseValidator { 11 | 12 | public static let defaultRegularExpression = ".*?.*?Success.*?.*" 13 | 14 | /// Matching options for determining how the response is matched against the regular expression. 15 | private let options: NSRegularExpression.Options 16 | 17 | /// Response `String` is matched against the regex to determine whether or not the response is valid. 18 | private let regularExpression: String 19 | 20 | /// Initializes the receiver to validate the response against a supplied regular expression. 21 | /// - Parameters: 22 | /// - options: Matching options for determining whether or not the response `String` 23 | /// matching the provided regular expression. 24 | /// - regEx: Regular expression used to validate the response. If the response 25 | /// `String` matches the regular expression then the response is deemed to be valid. 26 | public init(regEx: String = ResponseRegExValidator.defaultRegularExpression, 27 | options: NSRegularExpression.Options? = nil 28 | ) { 29 | self.options = options ?? [.caseInsensitive, .allowCommentsAndWhitespace, .dotMatchesLineSeparators] 30 | self.regularExpression = regEx 31 | } 32 | 33 | public func isResponseValid(_ response: URLResponse, data: Data) -> Bool { 34 | guard let responseString = String(data: data, encoding: .utf8), 35 | let regEx = try? NSRegularExpression(pattern: regularExpression, options: options) else { 36 | return false 37 | } 38 | let responseStrRange = NSRange(location: 0, length: responseString.count) 39 | let matches = regEx.matches(in: responseString, options: [], range: responseStrRange) 40 | return !matches.isEmpty 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Response Validation/ResponseStringEqualityValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseStringEqualityValidator.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public class ResponseStringEqualityValidator: ResponseValidator { 11 | 12 | /// The `String` expected as the response 13 | public let expectedResponse: String 14 | 15 | /// Initializes the receiver to validate that the response `String` is equal to the expected response. 16 | /// 17 | /// - Parameter expectedResponse: The `String` expected as the response. 18 | public init(expectedResponse: String = "Success") { 19 | self.expectedResponse = expectedResponse 20 | } 21 | 22 | public func isResponseValid(_ response: URLResponse, data: Data) -> Bool { 23 | guard let responseString = String(data: data, encoding: .utf8) else { 24 | return false 25 | } 26 | return expectedResponse == responseString.trimmingCharacters(in: .whitespacesAndNewlines) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Response Validation/ResponseStringValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseStringValidation.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | public class ResponseStringValidator: ResponseValidator { 11 | 12 | public enum ValidationMode: Int { 13 | case containsExpectedResponseString 14 | case equalsExpectedResponseString 15 | case matchesRegularExpression 16 | } 17 | 18 | /// The method used to validate the response from the connectivity endpoints. 19 | public let responseValidationMode: ValidationMode 20 | 21 | /// The `String` expected in the response, which is tested based on the validationMode 22 | public let expectedResponse: String? 23 | 24 | /// Initializes the receiver to validate response `String`s 25 | /// using the given validation mode 26 | /// 27 | /// - Parameter validationMode: The mode to use for validating the response `String`. 28 | /// - Parameter expectedResponse: The `String` expected in the response, which is 29 | /// tested based on the validationMode 30 | public init(validationMode: ValidationMode, expectedResponse: String? = nil) { 31 | self.responseValidationMode = validationMode 32 | self.expectedResponse = expectedResponse 33 | } 34 | 35 | public func isResponseValid(_ response: URLResponse, data: Data) -> Bool { 36 | let validator: ResponseValidator 37 | guard let expectedResponse = self.expectedResponse else { 38 | switch responseValidationMode { 39 | case .containsExpectedResponseString: 40 | validator = ResponseContainsStringValidator() 41 | case .equalsExpectedResponseString: 42 | validator = ResponseStringEqualityValidator() 43 | case .matchesRegularExpression: 44 | validator = ResponseRegExValidator() 45 | } 46 | return validator.isResponseValid(response, data: data) 47 | } 48 | switch responseValidationMode { 49 | case .containsExpectedResponseString: 50 | validator = ResponseContainsStringValidator(expectedResponse: expectedResponse) 51 | case .equalsExpectedResponseString: 52 | validator = ResponseStringEqualityValidator(expectedResponse: expectedResponse) 53 | case .matchesRegularExpression: 54 | validator = ResponseRegExValidator(regEx: expectedResponse) 55 | } 56 | return validator.isResponseValid(response, data: data) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Hyperconnectivity/Classes/Response Validation/ResponseValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseValidation.swift 3 | // Hyperconnectivity 4 | // 5 | // Created by Ross Butler on 08/05/2020. 6 | // 7 | 8 | import Foundation 9 | 10 | /// The contract for a response validator used to determine 11 | /// connectivity based on a network response 12 | public protocol ResponseValidator { 13 | 14 | /// Determines whether or not the response is valid 15 | /// and expected for a given `URL` 16 | /// 17 | /// - Parameter url: The `URL`, from which the response was fetched 18 | /// - Parameter _ response: The `URLResponse` returned by url 19 | /// - Parameter data: The data in the response returned by url 20 | func isResponseValid(_ response: URLResponse, data: Data) -> Bool 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Ross Butler 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 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "ohhttpstubs", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/AliSoftware/OHHTTPStubs", 7 | "state" : { 8 | "revision" : "12f19662426d0434d6c330c6974d53e2eb10ecd9", 9 | "version" : "9.1.0" 10 | } 11 | } 12 | ], 13 | "version" : 2 14 | } 15 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.7 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "Hyperconnectivity", 6 | platforms: [ 7 | .iOS(.v13), 8 | .tvOS(.v13), 9 | .macOS(.v10_15), 10 | .watchOS(.v6) 11 | ], 12 | products: [ 13 | .library( 14 | name: "Hyperconnectivity", 15 | targets: ["Hyperconnectivity"] 16 | ) 17 | ], 18 | dependencies: [ 19 | .package(url: "https://github.com/AliSoftware/OHHTTPStubs", from: "9.1.0") 20 | ], 21 | targets: [ 22 | .target( 23 | name: "Hyperconnectivity", 24 | path: "Hyperconnectivity/Classes" 25 | ), 26 | .testTarget( 27 | name: "HyperconnectivityTests", 28 | dependencies: [ 29 | .target(name: "Hyperconnectivity"), 30 | .product(name: "OHHTTPStubsSwift", package: "OHHTTPStubs") 31 | ], 32 | path: "Example/Tests", 33 | resources: [ 34 | .process("failure-response.html"), 35 | .process("string-contains-response.html"), 36 | .process("string-equality-response.html") 37 | ] 38 | ) 39 | ] 40 | ) 41 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /docs/images/comparison-with-connectivity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwbutler/Hyperconnectivity/0503595f9ab5bfdef6c06c2d8c2712cb50213259/docs/images/comparison-with-connectivity.png -------------------------------------------------------------------------------- /docs/images/hyperconnectivity-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwbutler/Hyperconnectivity/0503595f9ab5bfdef6c06c2d8c2712cb50213259/docs/images/hyperconnectivity-banner.png -------------------------------------------------------------------------------- /docs/images/hyperconnectivity-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwbutler/Hyperconnectivity/0503595f9ab5bfdef6c06c2d8c2712cb50213259/docs/images/hyperconnectivity-logo.png --------------------------------------------------------------------------------